diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 79f71070151..015b517d51b 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1964,7 +1964,7 @@ function template_preprocess_page(&$variables) { if (!defined('MAINTENANCE_MODE')) { $variables['breadcrumb'] = array( '#theme' => 'breadcrumb', - '#breadcrumb' => \Drupal::service('breadcrumb')->build(\Drupal::routeMatch()), + '#links' => \Drupal::service('breadcrumb')->build(\Drupal::routeMatch()), ); } } @@ -2304,6 +2304,23 @@ function template_preprocess_field_multiple_value_form(&$variables) { } } +/** + * Prepares variables for breadcrumb templates. + * + * Default template: breadcrumb.html.twig. + * + * @param array $variables + * An associative array containing: + * - links: A list of \Drupal\Core\Link objects which should be rendered. + */ +function template_preprocess_breadcrumb(&$variables) { + /** @var \Drupal\Core\Link[] $links */ + $links = $variables['links']; + foreach ($links as $key => $link) { + $variables['breadcrumb'][$key] = array('text' => $link->getText(), 'url' => $link->getUrl()->toString()); + } +} + /** * Callback for usort() within template_preprocess_field_multiple_value_form(). * @@ -2366,7 +2383,7 @@ function drupal_common_theme() { 'template' => 'image', ), 'breadcrumb' => array( - 'variables' => array('breadcrumb' => NULL), + 'variables' => array('links' => array(), 'breadcrumb' => array()), 'template' => 'breadcrumb', ), 'table' => array( diff --git a/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php b/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php index c808ce65f78..ebdfa5569a5 100644 --- a/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php +++ b/core/lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php @@ -32,8 +32,8 @@ interface BreadcrumbBuilderInterface { * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The current route match. * - * @return array - * An array of HTML links for the breadcrumb. Returning an empty array will + * @return \Drupal\Core\Link[] + * An array of links for the breadcrumb. Returning an empty array will * suppress all breadcrumbs. */ public function build(RouteMatchInterface $route_match); diff --git a/core/lib/Drupal/Core/Link.php b/core/lib/Drupal/Core/Link.php new file mode 100644 index 00000000000..936b541cb4c --- /dev/null +++ b/core/lib/Drupal/Core/Link.php @@ -0,0 +1,119 @@ +text = $text; + $this->url = $url; + } + + /** + * Creates a link object from a given route name and parameters. + * + * @param string $text + * The text of the link. + * @param string $route_name + * The name of the route + * @param array $route_parameters + * (optional) An associative array of parameter names and values. + * @param array $options + * (optional) An associative array of additional options, with the following + * elements: + * - 'query': An array of query key/value-pairs (without any URL-encoding) + * to append to the URL. Merged with the parameters array. + * - 'fragment': A fragment identifier (named anchor) to append to the URL. + * Do not include the leading '#' character. + * - 'absolute': Defaults to FALSE. Whether to force the output to be an + * absolute link (beginning with http:). Useful for links that will be + * displayed outside the site, such as in an RSS feed. + * - 'language': An optional language object used to look up the alias + * for the URL. If $options['language'] is omitted, it defaults to the + * current language for the language type LanguageInterface::TYPE_URL. + * - 'https': Whether this URL should point to a secure location. If not + * defined, the current scheme is used, so the user stays on HTTP or HTTPS + * respectively. if mixed mode sessions are permitted, TRUE enforces HTTPS + * and FALSE enforces HTTP. + * + * @return static + */ + public static function createFromRoute($text, $route_name, $route_parameters = array(), $options = array()) { + return new static($text, new Url($route_name, $route_parameters, $options)); + } + + /** + * Returns the text of the link. + * + * @return string + */ + public function getText() { + return $this->text; + } + + /** + * Sets the new text of the link. + * + * @param string $text + * The new text. + * + * @return $this + */ + public function setText($text) { + $this->text = $text; + return $this; + } + + /** + * Returns the URL of the link. + * + * @return \Drupal\Core\Url + */ + public function getUrl() { + return $this->url; + } + + /** + * Sets the URL of this link. + * + * @param Url $url + * The URL object to set + * + * @return $this + */ + public function setUrl(Url $url) { + $this->url = $url; + return $this; + } + +} diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php index d3093ac093a..f8660ab1581 100644 --- a/core/lib/Drupal/Core/Utility/LinkGenerator.php +++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php @@ -11,6 +11,7 @@ use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\String; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Link; use Drupal\Core\Path\AliasManagerInterface; use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Template\Attribute; @@ -48,6 +49,13 @@ class LinkGenerator implements LinkGeneratorInterface { $this->moduleHandler = $module_handler; } + /** + * {@inheritdoc} + */ + public function generateFromLink(Link $link) { + return $this->generateFromUrl($link->getText(), $link->getUrl()); + } + /** * {@inheritdoc} * diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php index e6e74a74e70..edce761c1e0 100644 --- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php +++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Utility; +use Drupal\Core\Link; use Drupal\Core\Url; /** @@ -92,4 +93,15 @@ interface LinkGeneratorInterface { */ public function generateFromUrl($text, Url $url); + /** + * Renders a link from a link object. + * + * @param \Drupal\Core\Link $link + * A link object to convert to a string. + * + * @return string + * An HTML string containing a link to the given link. + */ + public function generateFromLink(Link $link); + } diff --git a/core/modules/book/src/BookBreadcrumbBuilder.php b/core/modules/book/src/BookBreadcrumbBuilder.php index 9708b3de74e..be0e63a866b 100644 --- a/core/modules/book/src/BookBreadcrumbBuilder.php +++ b/core/modules/book/src/BookBreadcrumbBuilder.php @@ -10,7 +10,7 @@ namespace Drupal\book; use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Routing\LinkGeneratorTrait; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -21,7 +21,6 @@ use Drupal\node\NodeInterface; */ class BookBreadcrumbBuilder implements BreadcrumbBuilderInterface { use StringTranslationTrait; - use LinkGeneratorTrait; /** * The node storage. @@ -73,7 +72,7 @@ class BookBreadcrumbBuilder implements BreadcrumbBuilderInterface { */ public function build(RouteMatchInterface $route_match) { $book_nids = array(); - $links = array($this->l($this->t('Home'), '')); + $links = array(Link::createFromRoute($this->t('Home'), '')); $book = $route_match->getParameter('node')->book; $depth = 1; // We skip the current node. @@ -87,7 +86,7 @@ class BookBreadcrumbBuilder implements BreadcrumbBuilderInterface { while (!empty($book['p' . ($depth + 1)])) { if (!empty($parent_books[$book['p' . $depth]]) && ($parent_book = $parent_books[$book['p' . $depth]])) { if ($parent_book->access('view', $this->account)) { - $links[] = $this->l($parent_book->label(), 'entity.node.canonical', array('node' => $parent_book->id())); + $links[] = Link::createFromRoute($parent_book->label(), 'entity.node.canonical', array('node' => $parent_book->id())); } } $depth++; diff --git a/core/modules/comment/src/CommentBreadcrumbBuilder.php b/core/modules/comment/src/CommentBreadcrumbBuilder.php index 54f4d1f33f3..f518badb1e2 100644 --- a/core/modules/comment/src/CommentBreadcrumbBuilder.php +++ b/core/modules/comment/src/CommentBreadcrumbBuilder.php @@ -9,8 +9,8 @@ namespace Drupal\comment; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Routing\LinkGeneratorTrait; use Drupal\Core\StringTranslation\StringTranslationTrait; /** @@ -18,7 +18,6 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; */ class CommentBreadcrumbBuilder implements BreadcrumbBuilderInterface { use StringTranslationTrait; - use LinkGeneratorTrait; /** * Stores the Entity manager service. @@ -53,11 +52,11 @@ class CommentBreadcrumbBuilder implements BreadcrumbBuilderInterface { public function build(RouteMatchInterface $route_match) { $breadcrumb = array(); - $breadcrumb[] = $this->l($this->t('Home'), ''); + $breadcrumb[] = Link::createFromRoute($this->t('Home'), ''); $entity = $this->entityManager ->getStorage($route_match->getParameter('entity_type')) ->load($route_match->getParameter('entity_id')); - $breadcrumb[] = \Drupal::linkGenerator()->generateFromUrl($entity->label(), $entity->urlInfo()); + $breadcrumb[] = new Link($entity->label(), $entity->urlInfo()); return $breadcrumb; } diff --git a/core/modules/forum/src/Breadcrumb/ForumBreadcrumbBuilderBase.php b/core/modules/forum/src/Breadcrumb/ForumBreadcrumbBuilderBase.php index 05af222cf7a..f595ee83047 100644 --- a/core/modules/forum/src/Breadcrumb/ForumBreadcrumbBuilderBase.php +++ b/core/modules/forum/src/Breadcrumb/ForumBreadcrumbBuilderBase.php @@ -10,8 +10,8 @@ namespace Drupal\forum\Breadcrumb; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Routing\LinkGeneratorTrait; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\forum\ForumManagerInterface; @@ -23,7 +23,6 @@ use Drupal\forum\ForumManagerInterface; */ abstract class ForumBreadcrumbBuilderBase implements BreadcrumbBuilderInterface { use StringTranslationTrait; - use LinkGeneratorTrait; /** * Configuration object for this builder. @@ -66,12 +65,12 @@ abstract class ForumBreadcrumbBuilderBase implements BreadcrumbBuilderInterface * {@inheritdoc} */ public function build(RouteMatchInterface $route_match) { - $breadcrumb[] = $this->l($this->t('Home'), ''); + $breadcrumb[] = Link::createFromRoute($this->t('Home'), ''); $vocabulary = $this->entityManager ->getStorage('taxonomy_vocabulary') ->load($this->config->get('vocabulary')); - $breadcrumb[] = $this->l($vocabulary->label(), 'forum.index'); + $breadcrumb[] = Link::createFromRoute($vocabulary->label(), 'forum.index'); return $breadcrumb; } diff --git a/core/modules/forum/src/Breadcrumb/ForumListingBreadcrumbBuilder.php b/core/modules/forum/src/Breadcrumb/ForumListingBreadcrumbBuilder.php index 8f14417d0ab..9d63772c7c8 100644 --- a/core/modules/forum/src/Breadcrumb/ForumListingBreadcrumbBuilder.php +++ b/core/modules/forum/src/Breadcrumb/ForumListingBreadcrumbBuilder.php @@ -7,6 +7,7 @@ namespace Drupal\forum\Breadcrumb; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; /** @@ -33,7 +34,7 @@ class ForumListingBreadcrumbBuilder extends ForumBreadcrumbBuilderBase { if ($parents) { foreach (array_reverse($parents) as $parent) { if ($parent->id() != $term_id) { - $breadcrumb[] = $this->l($parent->label(), 'forum.page', array( + $breadcrumb[] = Link::createFromRoute($parent->label(), 'forum.page', array( 'taxonomy_term' => $parent->id(), )); } diff --git a/core/modules/forum/src/Breadcrumb/ForumNodeBreadcrumbBuilder.php b/core/modules/forum/src/Breadcrumb/ForumNodeBreadcrumbBuilder.php index 48d2b3848ee..0e0bd04de96 100644 --- a/core/modules/forum/src/Breadcrumb/ForumNodeBreadcrumbBuilder.php +++ b/core/modules/forum/src/Breadcrumb/ForumNodeBreadcrumbBuilder.php @@ -7,6 +7,7 @@ namespace Drupal\forum\Breadcrumb; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; /** @@ -33,7 +34,7 @@ class ForumNodeBreadcrumbBuilder extends ForumBreadcrumbBuilderBase { if ($parents) { $parents = array_reverse($parents); foreach ($parents as $parent) { - $breadcrumb[] = $this->l($parent->label(), 'forum.page', + $breadcrumb[] = Link::createFromRoute($parent->label(), 'forum.page', array( 'taxonomy_term' => $parent->id(), ) diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php index 2a4c4995e4c..ebda138ac36 100644 --- a/core/modules/forum/src/Tests/ForumTest.php +++ b/core/modules/forum/src/Tests/ForumTest.php @@ -8,6 +8,7 @@ namespace Drupal\forum\Tests; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Link; use Drupal\simpletest\WebTestBase; /** @@ -550,14 +551,14 @@ class ForumTest extends WebTestBase { $this->assertResponse(200); $this->assertTitle($node->label() . ' | Drupal', 'Forum node was displayed'); $breadcrumb_build = array( - l(t('Home'), NULL), - l(t('Forums'), 'forum'), - l($this->forumContainer['name'], 'forum/' . $this->forumContainer['tid']), - l($this->forum['name'], 'forum/' . $this->forum['tid']), + Link::createFromRoute(t('Home'), ''), + Link::createFromRoute(t('Forums'), 'forum.index'), + Link::createFromRoute($this->forumContainer['name'], 'forum.page', array('taxonomy_term' => $this->forumContainer['tid'])), + Link::createFromRoute($this->forum['name'], 'forum.page', array('taxonomy_term' => $this->forum['tid'])), ); $breadcrumb = array( '#theme' => 'breadcrumb', - '#breadcrumb' => $breadcrumb_build, + '#links' => $breadcrumb_build, ); $this->assertRaw(drupal_render($breadcrumb), 'Breadcrumbs were displayed'); @@ -608,16 +609,16 @@ class ForumTest extends WebTestBase { $this->assertTitle($forum['name'] . ' | Drupal'); $breadcrumb_build = array( - l(t('Home'), NULL), - l(t('Forums'), 'forum'), + Link::createFromRoute(t('Home'), ''), + Link::createFromRoute(t('Forums'), 'forum.index'), ); if (isset($parent)) { - $breadcrumb_build[] = l($parent['name'], 'forum/' . $parent['tid']); + $breadcrumb_build[] = Link::createFromRoute($parent['name'], 'forum.page', array('taxonomy_term' => $parent['tid'])); } $breadcrumb = array( '#theme' => 'breadcrumb', - '#breadcrumb' => $breadcrumb_build, + '#links' => $breadcrumb_build, ); $this->assertRaw(drupal_render($breadcrumb), 'Breadcrumbs were displayed'); } diff --git a/core/modules/forum/tests/src/Breadcrumb/ForumBreadcrumbBuilderBaseTest.php b/core/modules/forum/tests/src/Breadcrumb/ForumBreadcrumbBuilderBaseTest.php index ad5840be920..e165418fad2 100644 --- a/core/modules/forum/tests/src/Breadcrumb/ForumBreadcrumbBuilderBaseTest.php +++ b/core/modules/forum/tests/src/Breadcrumb/ForumBreadcrumbBuilderBaseTest.php @@ -7,6 +7,7 @@ namespace Drupal\forum\Tests\Breadcrumb; +use Drupal\Core\Link; use Drupal\Tests\UnitTestCase; /** @@ -115,32 +116,19 @@ class ForumBreadcrumbBuilderBaseTest extends UnitTestCase { // Add a translation manager for t(). $translation_manager = $this->getStringTranslationStub(); - $property = new \ReflectionProperty('Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder', 'stringTranslation'); - $property->setAccessible(TRUE); - $property->setValue($breadcrumb_builder, $translation_manager); - - // Add a link generator for l(). - $link_generator = $this->getMockBuilder('Drupal\Core\Utility\LinkGeneratorInterface') - ->disableOriginalConstructor() - ->getMock(); - $link_generator->expects($this->any()) - ->method('generate') - ->will($this->returnArgument(0)); - $property = new \ReflectionProperty('Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder', 'linkGenerator'); - $property->setAccessible(TRUE); - $property->setValue($breadcrumb_builder, $link_generator); + $breadcrumb_builder->setStringTranslation($translation_manager); // Our empty data set. $route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface'); // Expected result set. $expected = array( - 'Home', - 'Fora_is_the_plural_of_forum', + Link::createFromRoute('Home', ''), + Link::createFromRoute('Fora_is_the_plural_of_forum', 'forum.index'), ); // And finally, the test. - $this->assertSame($expected, $breadcrumb_builder->build($route_match)); + $this->assertEquals($expected, $breadcrumb_builder->build($route_match)); } } diff --git a/core/modules/forum/tests/src/Breadcrumb/ForumListingBreadcrumbBuilderTest.php b/core/modules/forum/tests/src/Breadcrumb/ForumListingBreadcrumbBuilderTest.php index e32e287959b..63d9f9e7983 100644 --- a/core/modules/forum/tests/src/Breadcrumb/ForumListingBreadcrumbBuilderTest.php +++ b/core/modules/forum/tests/src/Breadcrumb/ForumListingBreadcrumbBuilderTest.php @@ -7,6 +7,7 @@ namespace Drupal\forum\Tests\Breadcrumb; +use Drupal\Core\Link; use Drupal\Tests\UnitTestCase; use Symfony\Cmf\Component\Routing\RouteObjectInterface; @@ -172,20 +173,7 @@ class ForumListingBreadcrumbBuilderTest extends UnitTestCase { // Add a translation manager for t(). $translation_manager = $this->getStringTranslationStub(); - $property = new \ReflectionProperty('Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder', 'stringTranslation'); - $property->setAccessible(TRUE); - $property->setValue($breadcrumb_builder, $translation_manager); - - // Add a link generator for l(). - $link_generator = $this->getMockBuilder('Drupal\Core\Utility\LinkGeneratorInterface') - ->disableOriginalConstructor() - ->getMock(); - $link_generator->expects($this->any()) - ->method('generate') - ->will($this->returnArgument(0)); - $property = new \ReflectionProperty('Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder', 'linkGenerator'); - $property->setAccessible(TRUE); - $property->setValue($breadcrumb_builder, $link_generator); + $breadcrumb_builder->setStringTranslation($translation_manager); // The forum listing we need a breadcrumb back from. $forum_listing = $this->getMockBuilder('Drupal\taxonomy\Entity\Term') @@ -205,20 +193,20 @@ class ForumListingBreadcrumbBuilderTest extends UnitTestCase { // First test. $expected1 = array( - 'Home', - 'Fora_is_the_plural_of_forum', - 'Something', + Link::createFromRoute('Home', ''), + Link::createFromRoute('Fora_is_the_plural_of_forum', 'forum.index'), + Link::createFromRoute('Something', 'forum.page', array('taxonomy_term' => 1)), ); - $this->assertSame($expected1, $breadcrumb_builder->build($route_match)); + $this->assertEquals($expected1, $breadcrumb_builder->build($route_match)); // Second test. $expected2 = array( - 'Home', - 'Fora_is_the_plural_of_forum', - 'Something else', - 'Something', + Link::createFromRoute('Home', ''), + Link::createFromRoute('Fora_is_the_plural_of_forum', 'forum.index'), + Link::createFromRoute('Something else', 'forum.page', array('taxonomy_term' => 2)), + Link::createFromRoute('Something', 'forum.page', array('taxonomy_term' => 1)), ); - $this->assertSame($expected2, $breadcrumb_builder->build($route_match)); + $this->assertEquals($expected2, $breadcrumb_builder->build($route_match)); } } diff --git a/core/modules/forum/tests/src/Breadcrumb/ForumNodeBreadcrumbBuilderTest.php b/core/modules/forum/tests/src/Breadcrumb/ForumNodeBreadcrumbBuilderTest.php index 86cad8ed6d7..7691801163d 100644 --- a/core/modules/forum/tests/src/Breadcrumb/ForumNodeBreadcrumbBuilderTest.php +++ b/core/modules/forum/tests/src/Breadcrumb/ForumNodeBreadcrumbBuilderTest.php @@ -7,6 +7,7 @@ namespace Drupal\forum\Tests\Breadcrumb; +use Drupal\Core\Link; use Drupal\Tests\UnitTestCase; use Symfony\Cmf\Component\Routing\RouteObjectInterface; @@ -184,17 +185,6 @@ class ForumNodeBreadcrumbBuilderTest extends UnitTestCase { $property->setAccessible(TRUE); $property->setValue($breadcrumb_builder, $translation_manager); - // Add a link generator for l(). - $link_generator = $this->getMockBuilder('Drupal\Core\Utility\LinkGeneratorInterface') - ->disableOriginalConstructor() - ->getMock(); - $link_generator->expects($this->any()) - ->method('generate') - ->will($this->returnArgument(0)); - $property = new \ReflectionProperty('Drupal\forum\Breadcrumb\ForumNodeBreadcrumbBuilder', 'linkGenerator'); - $property->setAccessible(TRUE); - $property->setValue($breadcrumb_builder, $link_generator); - // The forum node we need a breadcrumb back from. $forum_node = $this->getMockBuilder('Drupal\node\Entity\Node') ->disableOriginalConstructor() @@ -209,20 +199,20 @@ class ForumNodeBreadcrumbBuilderTest extends UnitTestCase { // First test. $expected1 = array( - 'Home', - 'Forums', - 'Something', + Link::createFromRoute('Home', ''), + Link::createFromRoute('Forums', 'forum.index'), + Link::createFromRoute('Something', 'forum.page', array('taxonomy_term' => 1)), ); - $this->assertSame($expected1, $breadcrumb_builder->build($route_match)); + $this->assertEquals($expected1, $breadcrumb_builder->build($route_match)); // Second test. $expected2 = array( - 'Home', - 'Forums', - 'Something else', - 'Something', + Link::createFromRoute('Home', ''), + Link::createFromRoute('Forums', 'forum.index'), + Link::createFromRoute('Something else', 'forum.page', array('taxonomy_term' => 2)), + Link::createFromRoute('Something', 'forum.page', array('taxonomy_term' => 1)), ); - $this->assertSame($expected2, $breadcrumb_builder->build($route_match)); + $this->assertEquals($expected2, $breadcrumb_builder->build($route_match)); } } diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index e9a381ec9bd..5790899bb6f 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Block\BlockPluginInterface; +use Drupal\Core\Link; use Drupal\Core\Menu\MenuLinkInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; @@ -566,7 +567,7 @@ function menu_ui_system_breadcrumb_alter(array &$breadcrumb, RouteMatchInterface if (($menu_link instanceof MenuLinkInterface)) { // Add a link to the menu admin screen. $menu = Menu::load($menu_link->getMenuName()); - $breadcrumb[] = \Drupal::l($menu->label(), 'menu_ui.menu_edit', array('menu' => $menu->id())); + $breadcrumb[] = Link::createFromRoute($menu->label(), 'menu_ui.menu_edit', array('menu' => $menu->id())); } } } diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php index 46c4ca0f44d..7f1bec6887a 100644 --- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php @@ -11,10 +11,10 @@ use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Controller\TitleResolverInterface; +use Drupal\Core\Link; use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Routing\LinkGeneratorTrait; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Component\Utility\Unicode; @@ -31,7 +31,6 @@ use Symfony\Component\Routing\Exception\ResourceNotFoundException; */ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { use StringTranslationTrait; - use LinkGeneratorTrait; /** * The router request context. @@ -154,16 +153,14 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { // route is missing a _title or _title_callback attribute. $title = str_replace(array('-', '_'), ' ', Unicode::ucfirst(end($path_elements))); } - // @todo Replace with a #type => link render element so that the alter - // hook can work with the actual data. - $links[] = $this->l($title, $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME), $route_request->attributes->get('_raw_variables')->all(), array('html' => TRUE)); + $links[] = Link::createFromRoute($title, $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME), $route_request->attributes->get('_raw_variables')->all()); } } } if ($path && $path != $front) { // Add the Home link, except for the front page. - $links[] = $this->l($this->t('Home'), ''); + $links[] = Link::createFromRoute($this->t('Home'), ''); } return array_reverse($links); } diff --git a/core/modules/system/src/Plugin/Block/SystemBreadcrumbBlock.php b/core/modules/system/src/Plugin/Block/SystemBreadcrumbBlock.php index ebdb67707a7..e822a72f3f5 100644 --- a/core/modules/system/src/Plugin/Block/SystemBreadcrumbBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemBreadcrumbBlock.php @@ -79,7 +79,7 @@ class SystemBreadcrumbBlock extends BlockBase implements ContainerFactoryPluginI // $breadcrumb is expected to be an array of rendered breadcrumb links. return array( '#theme' => 'breadcrumb', - '#breadcrumb' => $breadcrumb, + '#links' => $breadcrumb, ); } } diff --git a/core/modules/system/templates/breadcrumb.html.twig b/core/modules/system/templates/breadcrumb.html.twig index 8a4f438079b..f6a170509fe 100644 --- a/core/modules/system/templates/breadcrumb.html.twig +++ b/core/modules/system/templates/breadcrumb.html.twig @@ -14,7 +14,13 @@

{{ 'Breadcrumb'|t }}

    {% for item in breadcrumb %} -
  1. {{ item }}
  2. +
  3. + {% if item.url %} + {{ item.text }} + {% else %} + {{ item.text }} + {% endif %} +
  4. {% endfor %}
diff --git a/core/modules/system/tests/src/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php index 1b521cab55a..fce97dc5aaa 100644 --- a/core/modules/system/tests/src/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php +++ b/core/modules/system/tests/src/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php @@ -7,8 +7,10 @@ namespace Drupal\system\Tests\Breadcrumbs; +use Drupal\Core\Link; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\Core\Url; use Drupal\Core\Utility\LinkGeneratorInterface; use Drupal\system\PathBasedBreadcrumbBuilder; use Drupal\Tests\UnitTestCase; @@ -59,13 +61,6 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { */ protected $context; - /** - * The mocked link generator. - * - * @var \Drupal\Core\Utility\LinkGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $linkGenerator; - /** * The mocked current user. * @@ -109,9 +104,6 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { ); $this->builder->setStringTranslation($this->getStringTranslationStub()); - - $this->linkGenerator = $this->getMock('Drupal\Core\Utility\LinkGeneratorInterface'); - $this->builder->setLinkGenerator($this->linkGenerator); } /** @@ -138,10 +130,8 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { ->method('getPathInfo') ->will($this->returnValue('/example')); - $this->setupLinkGeneratorWithFrontpage(); - $links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); - $this->assertEquals(array(0 => 'Home'), $links); + $this->assertEquals(array(0 => new Link('Home', new Url(''))), $links); } /** @@ -170,20 +160,10 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { } })); - $link_example = 'Example'; - $link_front = 'Home'; - $this->linkGenerator->expects($this->at(0)) - ->method('generate') - ->with('Example', 'example', array(), array('html' => TRUE)) - ->will($this->returnValue($link_example)); - $this->linkGenerator->expects($this->at(1)) - ->method('generate') - ->with('Home', '', array(), array()) - ->will($this->returnValue($link_front)); $this->setupAccessManagerWithTrue(); $links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); - $this->assertEquals(array(0 => 'Home', 1 => $link_example), $links); + $this->assertEquals(array(0 => new Link('Home', new Url('')), 1 => new Link('Example', new Url('example'))), $links); } /** @@ -220,26 +200,14 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { } })); - $link_example_bar = 'Bar'; - $link_example = 'Example'; - $link_front = 'Home'; - $this->linkGenerator->expects($this->at(0)) - ->method('generate') - ->with('Bar', 'example_bar', array(), array('html' => TRUE)) - ->will($this->returnValue($link_example_bar)); - - $this->linkGenerator->expects($this->at(1)) - ->method('generate') - ->with('Example', 'example', array(), array('html' => TRUE)) - ->will($this->returnValue($link_example)); - $this->linkGenerator->expects($this->at(2)) - ->method('generate') - ->with('Home', '', array(), array()) - ->will($this->returnValue($link_front)); $this->setupAccessManagerWithTrue(); $links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); - $this->assertEquals(array(0 => 'Home', 1 => $link_example, 2 => $link_example_bar), $links); + $this->assertEquals(array( + new Link('Home', new Url('')), + new Link('Example', new Url('example')), + new Link('Bar', new Url('example_bar')), + ), $links); } /** @@ -259,12 +227,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { $this->requestMatcher->expects($this->any()) ->method('matchRequest') ->will($this->throwException(new $exception_class($exception_argument))); - $this->setupLinkGeneratorWithFrontpage(); $links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); // No path matched, though at least the frontpage is displayed. - $this->assertEquals(array(0 => 'Home'), $links); + $this->assertEquals(array(0 => new Link('Home', new Url(''))), $links); } /** @@ -301,12 +268,11 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { $this->requestMatcher->expects($this->any()) ->method('matchRequest') ->will($this->returnValue(array())); - $this->setupLinkGeneratorWithFrontpage(); $links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); // No path matched, though at least the frontpage is displayed. - $this->assertEquals(array(0 => 'Home'), $links); + $this->assertEquals(array(0 => new Link('Home', new Url(''))), $links); } /** @@ -344,17 +310,6 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { } })); - $link_user = 'Admin'; - $link_front = 'Home'; - $this->linkGenerator->expects($this->at(0)) - ->method('generate') - ->with('Admin', 'user_page', array(), array('html' => TRUE)) - ->will($this->returnValue($link_user)); - - $this->linkGenerator->expects($this->at(1)) - ->method('generate') - ->with('Home', '', array(), array()) - ->will($this->returnValue($link_front)); $this->setupAccessManagerWithTrue(); $this->titleResolver->expects($this->once()) ->method('getTitle') @@ -362,19 +317,7 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { ->will($this->returnValue('Admin')); $links = $this->builder->build($this->getMock('Drupal\Core\Routing\RouteMatchInterface')); - $this->assertEquals(array(0 => 'Home', 1 => $link_user), $links); - } - - /** - * Setup the link generator with a frontpage route. - */ - public function setupLinkGeneratorWithFrontpage() { - $this->linkGenerator->expects($this->once()) - ->method('generate') - ->with($this->anything(), '', array()) - ->will($this->returnCallback(function($title) { - return '' . $title . ''; - })); + $this->assertEquals(array(0 => new Link('Home', new Url('')), 1 => new Link('Admin', new Url('user_page'))), $links); } /** diff --git a/core/modules/taxonomy/src/TermBreadcrumbBuilder.php b/core/modules/taxonomy/src/TermBreadcrumbBuilder.php index 28a70876d89..307170a4165 100644 --- a/core/modules/taxonomy/src/TermBreadcrumbBuilder.php +++ b/core/modules/taxonomy/src/TermBreadcrumbBuilder.php @@ -8,8 +8,8 @@ namespace Drupal\taxonomy; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; +use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Routing\LinkGeneratorTrait; use Drupal\Core\StringTranslation\StringTranslationTrait; /** @@ -17,7 +17,6 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; */ class TermBreadcrumbBuilder implements BreadcrumbBuilderInterface { use StringTranslationTrait; - use LinkGeneratorTrait; /** * {@inheritdoc} @@ -38,9 +37,9 @@ class TermBreadcrumbBuilder implements BreadcrumbBuilderInterface { $breadcrumb = array(); while ($parents = taxonomy_term_load_parents($term->id())) { $term = array_shift($parents); - $breadcrumb[] = $this->l($term->getName(), 'entity.taxonomy_term.canonical', array('taxonomy_term' => $term->id())); + $breadcrumb[] = Link::createFromRoute($term->getName(), 'entity.taxonomy_term.canonical', array('taxonomy_term' => $term->id())); } - $breadcrumb[] = $this->l($this->t('Home'), ''); + $breadcrumb[] = Link::createFromRoute($this->t('Home'), ''); $breadcrumb = array_reverse($breadcrumb); return $breadcrumb;