Issue #2693725 by chx, alexpott: Add <nolink> to allow for non-link links

8.2.x
Nathaniel Catchpole 2016-05-04 14:03:08 +01:00
parent ba8e8b2a3f
commit a39876b9f4
5 changed files with 55 additions and 2 deletions

View File

@ -14,6 +14,11 @@ use Drupal\Core\Render\BubbleableMetadata;
*/
class GeneratedLink extends BubbleableMetadata implements MarkupInterface, \Countable {
/**
* HTML tag to use when building the link.
*/
const TAG = 'a';
/**
* The HTML string value containing a link.
*

View File

@ -0,0 +1,15 @@
<?php
namespace Drupal\Core;
/**
* This class holds a <span> generated from the <nolink> route.
*/
class GeneratedNoLink extends GeneratedLink {
/**
* {@inheritdoc}
*/
const TAG = 'span';
}

View File

@ -7,6 +7,7 @@ use Drupal\Component\Utility\Html;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\GeneratedLink;
use Drupal\Core\GeneratedNoLink;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;
@ -142,7 +143,7 @@ class LinkGenerator implements LinkGeneratorInterface {
$this->moduleHandler->alter('link', $variables);
// Move attributes out of options since generateFromRoute() doesn't need
// them. Include a placeholder for the href.
// them. Make sure the "href" comes first for testing purposes.
$attributes = array('href' => '') + $variables['options']['attributes'];
unset($variables['options']['attributes']);
$url->setOptions($variables['options']);
@ -152,6 +153,10 @@ class LinkGenerator implements LinkGeneratorInterface {
$generated_link = new GeneratedLink();
$attributes['href'] = $url->toString(FALSE);
}
elseif ($url->isRouted() && $url->getRouteName() === '<nolink>') {
$generated_link = new GeneratedNoLink();
unset($attributes['href']);
}
else {
$generated_url = $url->toString(TRUE);
$generated_link = GeneratedLink::createFromObject($generated_url);
@ -166,7 +171,7 @@ class LinkGenerator implements LinkGeneratorInterface {
$attributes = new Attribute($attributes);
// This is safe because Attribute does escaping and $variables['text'] is
// either rendered or escaped.
return $generated_link->setGeneratedLink('<a' . $attributes . '>' . $variables['text'] . '</a>');
return $generated_link->setGeneratedLink('<' . $generated_link::TAG . $attributes . '>' . $variables['text'] . '</' . $generated_link::TAG . '>');
}
}

View File

@ -397,6 +397,13 @@ system.theme_settings_theme:
requirements:
_access: 'TRUE'
'<nolink>':
path: ''
options:
_no_path: TRUE
requirements:
_access: 'TRUE'
'<current>':
path: '<current>'

View File

@ -3,6 +3,7 @@
namespace Drupal\Tests\Core\Utility {
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\GeneratedNoLink;
use Drupal\Core\GeneratedUrl;
use Drupal\Core\Language\Language;
use Drupal\Core\Link;
@ -146,6 +147,26 @@ class LinkGeneratorTest extends UnitTestCase {
), $result);
}
/**
* Tests the generate() method with the <nolink> route.
*
* @covers ::generate
*/
public function testGenerateNoLink() {
$this->urlGenerator->expects($this->never())
->method('generateFromRoute');
$this->moduleHandler->expects($this->once())
->method('alter')
->with('link', $this->isType('array'));
$url = Url::fromRoute('<nolink>');
$url->setUrlGenerator($this->urlGenerator);
$result = $this->linkGenerator->generate('Test', $url);
$this->assertTrue($result instanceof GeneratedNoLink);
$this->assertSame('<span>Test</span>', (string) $result);
}
/**
* Tests the generate() method with an external URL.
*