diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index fb11da253089cfe4e5412a3f905e656f115072f2..bdb4da2f7c3f0acc6f775b7bf891184389d822b4 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1573,93 +1573,82 @@ function _menu_tree_data(&$links, $parents, $depth) {
}
/**
- * Implements template_preprocess_HOOK() for theme_menu_tree().
+ * Prepares variables for menu tree templates.
+ *
+ * Default template: menu-tree.html.twig.
+ *
+ * @param array $variables
+ * An associative array containing:
+ * - tree: A render array for a menu tree.
*/
function template_preprocess_menu_tree(&$variables) {
$variables['tree'] = $variables['tree']['#children'];
}
/**
- * Returns HTML for a wrapper for a menu sub-tree.
+ * Prepares variables for menu link plus submenu templates.
*
- * @param $variables
- * An associative array containing:
- * - tree: An HTML string containing the tree's items.
+ * Default template: menu-link.html.twig.
*
- * @see template_preprocess_menu_tree()
- * @ingroup themeable
- */
-function theme_menu_tree($variables) {
- return '
';
-}
-
-/**
- * Returns HTML for a menu link and submenu.
- *
- * @param $variables
+ * @param array $variables
* An associative array containing:
* - element: Structured array data for a menu link.
- *
- * @ingroup themeable
*/
-function theme_menu_link(array $variables) {
+function template_preprocess_menu_link(&$variables) {
$element = $variables['element'];
- $sub_menu = '';
- if ($element['#below']) {
- $sub_menu = drupal_render($element['#below']);
- }
- $output = l($element['#title'], $element['#href'], $element['#localized_options']);
- return '' . $output . $sub_menu . "\n";
+ $variables['sub_menu'] = $element['#below'];
+ $variables['link'] = l($element['#title'], $element['#href'], $element['#localized_options']);
+ $variables['wrapper_attributes'] = new Attribute($element['#attributes']);
}
/**
- * Returns HTML for a single local task link.
+ * Prepares variables for single local task link templates.
+ *
+ * Default template: menu-local-task.html.twig.
*
- * @param $variables
+ * @param array variables
* An associative array containing:
* - element: A render element containing:
* - #link: A menu link array with 'title', 'href', and 'localized_options'
* keys.
* - #active: A boolean indicating whether the local task is active.
- *
- * @ingroup themeable
*/
-function theme_menu_local_task($variables) {
+function template_preprocess_menu_local_task(&$variables) {
$link = $variables['element']['#link'];
$link += array(
'localized_options' => array(),
);
- $link_text = $link['title'];
+ $variables['wrapper_attributes'] = new Attribute();
+ $variables['active'] = FALSE;
if (!empty($variables['element']['#active'])) {
- // Add text to indicate active tab for non-visual users.
- $active = '' . t('(active tab)') . '';
+ $variables['wrapper_attributes']['class'] = array('active');
+ $variables['active'] = TRUE;
// If the link does not contain HTML already, check_plain() it now.
- // After we set 'html'=TRUE the link will not be sanitized by l().
+ // After we set 'html' = TRUE, the link will not be sanitized by l().
if (empty($link['localized_options']['html'])) {
$link['title'] = check_plain($link['title']);
}
$link['localized_options']['html'] = TRUE;
- $link_text = t('!local-task-title!active', array('!local-task-title' => $link['title'], '!active' => $active));
}
- return '' . l($link_text, $link['href'], $link['localized_options']) . '';
+ $variables['link'] = l($link['title'], $link['href'], $link['localized_options']);
}
/**
- * Returns HTML for a single local action link.
+ * Prepares variables for single local action link templates.
+ *
+ * Default template: menu-local-action.html.twig.
*
- * @param $variables
+ * @param array $variables
* An associative array containing:
* - element: A render element containing:
* - #link: A menu link array with 'title', 'href', and 'localized_options'
* keys.
- *
- * @ingroup themeable
*/
-function theme_menu_local_action($variables) {
+function template_preprocess_menu_local_action(&$variables) {
$link = $variables['element']['#link'];
$link += array(
'href' => '',
@@ -1668,11 +1657,7 @@ function theme_menu_local_action($variables) {
$link['localized_options']['attributes']['class'][] = 'button';
$link['localized_options']['attributes']['class'][] = 'button-action';
- $output = '';
- $output .= l($link['title'], $link['href'], $link['localized_options']);
- $output .= "";
-
- return $output;
+ $variables['link'] = l($link['title'], $link['href'], $link['localized_options']);
}
/**
@@ -2239,36 +2224,6 @@ function menu_local_tabs() {
}
/**
- * Returns HTML for primary and secondary local tasks.
- *
- * @param $variables
- * An associative array containing:
- * - primary: (optional) An array of local tasks (tabs).
- * - secondary: (optional) An array of local tasks (tabs).
- *
- * @ingroup themeable
- * @see menu_local_tasks()
- */
-function theme_menu_local_tasks(&$variables) {
- $output = '';
-
- if (!empty($variables['primary'])) {
- $variables['primary']['#prefix'] = '' . t('Primary tabs') . '
';
- $variables['primary']['#prefix'] .= '';
- $variables['primary']['#suffix'] = '
';
- $output .= drupal_render($variables['primary']);
- }
- if (!empty($variables['secondary'])) {
- $variables['secondary']['#prefix'] = '' . t('Secondary tabs') . '
';
- $variables['secondary']['#prefix'] .= '';
- $variables['secondary']['#suffix'] = '
';
- $output .= drupal_render($variables['secondary']);
- }
-
- return $output;
-}
-
-/**
* Sets (or gets) the active menu for the current page.
*
* The active menu for the page determines the active trail.
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 782b5620170d816bad4e8b0acf53299b22722ae8..cd1420b4a25b1fe05bafb497035a39aac21c5128 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -3340,18 +3340,23 @@ function drupal_common_theme() {
// From menu.inc.
'menu_link' => array(
'render element' => 'element',
+ 'template' => 'menu-link',
),
'menu_tree' => array(
'render element' => 'tree',
+ 'template' => 'menu-tree',
),
'menu_local_task' => array(
'render element' => 'element',
+ 'template' => 'menu-local-task',
),
'menu_local_action' => array(
'render element' => 'element',
+ 'template' => 'menu-local-action',
),
'menu_local_tasks' => array(
'variables' => array('primary' => array(), 'secondary' => array()),
+ 'template' => 'menu-local-tasks',
),
// From form.inc.
'input' => array(
diff --git a/core/modules/system/system.theme-rtl.css b/core/modules/system/system.theme-rtl.css
index eb50ab36e877240240373b4f0f3db38d341363fd..ac34f9f75b531fdac5c3384f2f83f1e38f23aa7b 100644
--- a/core/modules/system/system.theme-rtl.css
+++ b/core/modules/system/system.theme-rtl.css
@@ -71,7 +71,7 @@ ul.menu {
}
/**
- * Markup generated by theme_menu_local_tasks().
+ * Markup generated by menu-local-tasks.html.twig.
*/
.tabs > li {
margin-left: 0.3em;
diff --git a/core/modules/system/system.theme.css b/core/modules/system/system.theme.css
index a3c770a8aa8c21ca87f711eeae6956621fdcd56d..e83f72f0bc1139a898c8c0e5db13673bbaefddcf 100644
--- a/core/modules/system/system.theme.css
+++ b/core/modules/system/system.theme.css
@@ -370,7 +370,7 @@ ul.inline li {
}
/**
- * Markup generated by theme_menu_local_tasks().
+ * Markup generated by menu-local-tasks.html.twig.
*/
div.tabs {
margin: 1em 0;
diff --git a/core/modules/system/templates/menu-link.html.twig b/core/modules/system/templates/menu-link.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..5035ea2bf56713a49c9f09f50e41ce440c9182af
--- /dev/null
+++ b/core/modules/system/templates/menu-link.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a menu link and submenu.
+ *
+ * Available variables:
+ * - wrapper_attributes: HTML attributes for the wrapper element.
+ * - link: An HTML link element.
+ * - sub_menu: Rendered list item children of the element.
+ *
+ * Note: This template renders the content for each individual menu item in
+ * menu-local-tasks.html.twig.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_menu_link()
+ *
+ * @ingroup themeable
+ */
+#}
+
+ {{ link }}{{ sub_menu }}
+
diff --git a/core/modules/system/templates/menu-local-action.html.twig b/core/modules/system/templates/menu-local-action.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..08bd68b89a1f63f7892cf483c5c05a58d22e3ebc
--- /dev/null
+++ b/core/modules/system/templates/menu-local-action.html.twig
@@ -0,0 +1,15 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a single local action link.
+ *
+ * Available variables:
+ * - link: A rendered link element.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_menu_local_action()
+ *
+ * @ingroup themeable
+ */
+#}
+{{ link }}
diff --git a/core/modules/system/templates/menu-local-task.html.twig b/core/modules/system/templates/menu-local-task.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..63f9135f5ec85e8214a4870aa4bee6bbf0c58fae
--- /dev/null
+++ b/core/modules/system/templates/menu-local-task.html.twig
@@ -0,0 +1,27 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a local task link.
+ *
+ * Available variables:
+ * - wrapper_attributes: HTML attributes for the wrapper element.
+ * - link: The rendered link ( tag).
+ *
+ * Note: This template renders the content for each individual task item in
+ * menu-local-tasks.html.twig.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_menu_local_task()
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+
+ {{ link }}
+ {% if active %}
+ {# Add text to indicate active tab for non-visual users. #}
+ ({{ 'active tab'|t }})
+ {% endif %}
+
+{% endspaceless %}
diff --git a/core/modules/system/templates/menu-local-tasks.html.twig b/core/modules/system/templates/menu-local-tasks.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..c290cefc466583c14d2620a23d0bffea0f6bdfd8
--- /dev/null
+++ b/core/modules/system/templates/menu-local-tasks.html.twig
@@ -0,0 +1,26 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display primary and secondary local tasks.
+ *
+ * Available variables:
+ * - primary_tasks: HTML list items representing primary tasks.
+ * - secondary_tasks: HTML list items representing primary tasks.
+ *
+ * Note: Each item for both sets of tasks can be individually themed in
+ * menu-local-task.html.twig.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_menu_local_tasks()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if primary %}
+ {{ 'Primary tabs'|t }}
+
+{% endif %}
+{% if secondary %}
+ {{ 'Secondary tabs'|t }}
+
+{% endif %}
diff --git a/core/modules/system/templates/menu-tree.html.twig b/core/modules/system/templates/menu-tree.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..0dc857e050be00ab8c5b16029a42d3b865db3501
--- /dev/null
+++ b/core/modules/system/templates/menu-tree.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the wrapper of a menu tree.
+ *
+ * Available variables:
+ * - tree: An HTML string containing the tree's items.
+ *
+ * Note: Each item in the menu tree can be individually themed in
+ * menu-link.html.twig.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_menu_tree()
+ *
+ * @ingroup themeable
+ */
+#}
+
diff --git a/core/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme
index 0593a3c7d69b907cd440312f4ee18c4a55f61c2c..ed337aa389e790424a8d98166bec355947b55879 100644
--- a/core/themes/bartik/bartik.theme
+++ b/core/themes/bartik/bartik.theme
@@ -136,13 +136,6 @@ function bartik_preprocess_node(&$variables) {
}
/**
- * Implements theme_menu_tree().
- */
-function bartik_menu_tree($variables) {
- return '';
-}
-
-/**
* Implements theme_field__field_type().
*/
function bartik_field__taxonomy_term_reference($variables) {
diff --git a/core/themes/bartik/templates/menu-tree.html.twig b/core/themes/bartik/templates/menu-tree.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..0a88f422400e42705713716d19e161d2d5fe8b39
--- /dev/null
+++ b/core/themes/bartik/templates/menu-tree.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Bartik's theme implementation for the wrapper of a menu tree.
+ *
+ * Available variables:
+ * - tree: An HTML string containing the tree's items.
+ *
+ * Note: Each item in the menu tree can be individually themed in
+ * menu-link.html.twig.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_menu_tree()
+ *
+ * @ingroup themeable
+ */
+#}
+