Issue #2102777 by damiankloip, dawehner: Allow theme_links() to use routes as well as href.

8.0.x
Alex Pott 2013-11-15 09:09:50 -04:00
parent 115b40c9f8
commit c4b089f5d9
9 changed files with 103 additions and 47 deletions

View File

@ -19,6 +19,7 @@ use Drupal\Core\Template\RenderWrapper;
use Drupal\Core\Utility\ThemeRegistry;
use Drupal\Core\Theme\ThemeSettings;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\MapArray;
/**
* @defgroup content_flags Content markers
@ -1645,8 +1646,6 @@ function template_preprocess_status_messages(&$variables) {
* http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
*/
function theme_links($variables) {
$language_url = language(Language::TYPE_URL);
$links = $variables['links'];
$attributes = $variables['attributes'];
$heading = $variables['heading'];
@ -1678,9 +1677,18 @@ function theme_links($variables) {
$num_links = count($links);
$i = 0;
$active = \Drupal::linkGenerator()->getActive();
$language_url = \Drupal::languageManager()->getLanguage(Language::TYPE_URL);
foreach ($links as $key => $link) {
$i++;
$link += array(
'href' => NULL,
'route_name' => NULL,
'route_parameters' => NULL,
);
$class = array();
// Use the array key as class name.
$class[] = drupal_html_class($key);
@ -1693,44 +1701,46 @@ function theme_links($variables) {
$class[] = 'last';
}
$link += array(
'href' => NULL,
$link_element = array(
'#type' => 'link',
'#title' => $link['title'],
'#options' => array_diff_key($link, MapArray::copyValuesToKeys(array('title', 'href', 'route_name', 'route_parameters'))),
'#href' => $link['href'],
'#route_name' => $link['route_name'],
'#route_parameters' => $link['route_parameters'],
);
// Handle links.
if (isset($link['href']) || isset($link['route_name'])) {
// @todo Reconcile Views usage of 'ajax' as a boolean with the rest of
// core's usage of it as an array.
if (isset($link['ajax']) && is_array($link['ajax'])) {
$link_element['#ajax'] = $link['ajax'];
}
// Handle links and ensure that the active class is added on the LIs.
if (isset($link['route_name'])) {
$variables = array(
'options' => array(),
);
if (!empty($link['language'])) {
$variables['options']['language'] = $link['language'];
}
if (($link['route_name'] == $active['route_name'])
// The language of an active link is equal to the current language.
&& (empty($variables['options']['language']) || ($variables['options']['language']->id == $active['language']))
&& ($link['route_parameters'] == $active['parameters'])) {
$class[] = 'active';
}
$item = drupal_render($link_element);
}
elseif (isset($link['href'])) {
$is_current_path = ($link['href'] == current_path() || ($link['href'] == '<front>' && drupal_is_front_page()));
$is_current_language = (empty($link['language']) || $link['language']->id == $language_url->id);
if ($is_current_path && $is_current_language) {
$class[] = 'active';
}
// @todo Reconcile Views usage of 'ajax' as a boolean with the rest of
// core's usage of it as an array.
if (isset($link['ajax']) && is_array($link['ajax'])) {
// To attach Ajax behavior, render a link element, rather than just
// call l().
$link_element = array(
'#type' => 'link',
'#title' => $link['title'],
'#href' => $link['href'],
'#ajax' => $link['ajax'],
'#options' => array_diff_key($link, drupal_map_assoc(array('title', 'href', 'ajax'))),
);
$item = drupal_render($link_element);
}
else {
// @todo theme_links() should *really* use the same parameters as l(),
// and just take an array of '#type' => 'link' elements, see
// https://drupal.org/node/2102777.
// Pass in $link as $options, as they share the same keys.
if (isset($link['href'])) {
$item = l($link['title'], $link['href'], $link);
}
else {
$link += array('route_parameters' => array());
$item = \Drupal::l($link['title'], $link['route_name'], $link['route_parameters'], $link);
}
}
$item = drupal_render($link_element);
}
// Handle title-only text items.
else {

View File

@ -84,6 +84,13 @@ class LinkGenerator implements LinkGeneratorInterface {
);
}
/**
* {@inheritdoc}
*/
public function getActive() {
return $this->active;
}
/**
* {@inheritdoc}
*/

View File

@ -71,4 +71,16 @@ interface LinkGeneratorInterface {
*/
public function generate($text, $route_name, array $parameters = array(), array $options = array());
/**
* Returns information for the currently active route.
*
* @return array
* An array of active route information, containing the following keys:
* - route_name: The currently active route_name
* - language: The current language
* - parameters: An array of request parameters and any query string
* parameters.
*/
public function getActive();
}

View File

@ -186,19 +186,23 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
$links = array();
$links['edit'] = array(
'title' => $this->t('Edit'),
'href' => "admin/config/services/aggregator/edit/feed/$feed->fid",
'route_name' => 'aggregator.feed_edit',
'route_parameters' => array('aggregator_feed' => $feed->fid),
);
$links['delete'] = array(
'title' => $this->t('Delete'),
'href' => "admin/config/services/aggregator/delete/feed/$feed->fid",
'route_name' => 'aggregator.feed_delete',
'route_parameters' => array('aggregator_feed' => $feed->fid),
);
$links['remove'] = array(
'title' => $this->t('Remove items'),
'href' => "admin/config/services/aggregator/remove/$feed->fid",
'route_name' => 'aggregator.feed_items_delete',
'route_parameters' => array('aggregator_feed' => $feed->fid),
);
$links['update'] = array(
'title' => $this->t('Update items'),
'href' => "admin/config/services/aggregator/update/$feed->fid",
'route_name' => 'aggregator.feed_refresh',
'route_parameters' => array('aggregator_feed' => $feed->fid),
'query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")),
);
$row[] = array(
@ -228,11 +232,13 @@ class AggregatorController extends ControllerBase implements ContainerInjectionI
$links = array();
$links['edit'] = array(
'title' => $this->t('Edit'),
'href' => "admin/config/services/aggregator/edit/category/$category->cid",
'route_name' => 'aggregator.category_admin_edit',
'route_parameters' => array('cid' => $category->cid),
);
$links['delete'] = array(
'title' => $this->t('Delete'),
'href' => "admin/config/services/aggregator/delete/category/$category->cid",
'route_name' => 'aggregator.category_delete',
'route_parameters' => array('cid' => $category->cid),
);
$row[] = array(
'data' => array(

View File

@ -63,7 +63,8 @@ class BanAdmin extends FormBase {
$links = array();
$links['delete'] = array(
'title' => $this->t('delete'),
'href' => "admin/config/people/ban/delete/$ip->iid",
'route_name' => 'ban.delete',
'route_parameters' => array('ban_id' => $ip->iid),
);
$row[] = array(
'data' => array(

View File

@ -53,12 +53,14 @@ function theme_book_admin_table($variables) {
if ($access) {
$links['edit'] = array(
'title' => t('Edit'),
'href' => "node/$nid/edit",
'route_name' => 'node.page_edit',
'route_parameters' => array('node' => $nid),
'query' => $destination,
);
$links['delete'] = array(
'title' => t('Delete'),
'href' => "node/$nid/delete",
'route_name' => 'node.delete_confirm',
'route_parameters' => array('node' => $nid),
'query' => $destination,
);
}

View File

@ -77,7 +77,8 @@ class BookController implements ContainerInjectionInterface {
$links = array();
$links['edit'] = array(
'title' => t('Edit order and titles'),
'href' => 'admin/structure/book/' . $book['nid'],
'route_name' => 'book.admin_edit',
'route_parameters' => array('node' => $book['nid']),
);
$row[] = array(
'data' => array(

View File

@ -155,13 +155,15 @@ function comment_admin_overview($form, &$form_state, $arg) {
$links = array();
$links['edit'] = array(
'title' => t('edit'),
'href' => 'comment/' . $comment->id() . '/edit',
'route_name' => 'comment.edit_page',
'route_parameters' => array('comment' => $comment->id()),
'query' => $destination,
);
if (module_invoke('content_translation', 'translate_access', $comment)) {
$links['translate'] = array(
'title' => t('translate'),
'href' => 'comment/' . $comment->id() . '/translations',
'route_name' => 'content_translation.translation_overview_comment',
'route_parameters' => array('comment' => $comment->id()),
'query' => $destination,
);
}

View File

@ -13,6 +13,14 @@ use Drupal\simpletest\WebTestBase;
* Tests for common theme functions.
*/
class FunctionsTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('router_test');
public static function getInfo() {
return array(
'name' => 'Theme functions',
@ -172,13 +180,19 @@ class FunctionsTest extends WebTestBase {
'title' => 'Front page',
'href' => '<front>',
),
'router-test' => array(
'title' => 'Test route',
'route_name' => 'router_test.1',
'route_parameters' => array(),
),
);
$expected_links = '';
$expected_links .= '<ul id="somelinks">';
$expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '">' . check_plain('A <link>') . '</a></li>';
$expected_links .= '<li class="plain-text even">' . check_plain('Plain "text"') . '</li>';
$expected_links .= '<li class="front-page odd last active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
$expected_links .= '<li class="front-page odd active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
$expected_links .= '<li class="router-test even last"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
$expected_links .= '</ul>';
// Verify that passing a string as heading works.
@ -210,7 +224,8 @@ class FunctionsTest extends WebTestBase {
$expected_links .= '<ul id="somelinks">';
$expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '" class="a/class">' . check_plain('A <link>') . '</a></li>';
$expected_links .= '<li class="plain-text even"><span class="a/class">' . check_plain('Plain "text"') . '</span></li>';
$expected_links .= '<li class="front-page odd last active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
$expected_links .= '<li class="front-page odd active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
$expected_links .= '<li class="router-test even last"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
$expected_links .= '</ul>';
$expected = $expected_heading . $expected_links;
$this->assertThemeOutput('links', $variables, $expected);