Heine

  • home
  • drupal
  • drupal core commits
  • about
Home › Drupal Core Commits

Commit 264404 by dries

- Patch #283723 by pwolanin, sun | eddified, moshe weitzman, Dries, aether, Arancaytar: Added Make menu_tree_output() return renderable output.

--- includes/common.inc 2009/09/18 00:04:21     1.991
+++ includes/common.inc 2009/09/18 10:54:20     1.992
@@ -4634,15 +4634,12 @@
       'arguments' => array('form' => NULL),
     ),
     // from menu.inc
-    'menu_item_link' => array(
-      'arguments' => array('item' => NULL),
+    'menu_link' => array(
+      'arguments' => array('element' => NULL),
     ),
     'menu_tree' => array(
       'arguments' => array('tree' => NULL),
     ),
-    'menu_item' => array(
-      'arguments' => array('link' => NULL, 'has_children' => NULL, 'menu' => ''),
-    ),
     'menu_local_task' => array(
       'arguments' => array('link' => NULL, 'active' => FALSE),
     ),

--- includes/menu.inc   2009/09/17 04:07:39     1.345
+++ includes/menu.inc   2009/09/18 10:54:20     1.346
@@ -552,6 +552,14 @@
 function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
   $callback = $item['title_callback'];
   $item['localized_options'] = $item['options'];
+  // All 'class' attributes are assumed to be an array during rendering, but
+  // links stored in the database may use an old string value.
+  // @todo In order to remove this code we need to implement a database update
+  //   including unserializing all existing link options and running this code
+  //   on them, as well as adding validation to menu_link_save().
+  if (isset($item['options']['attributes']['class']) && is_string($item['options']['attributes']['class'])) {
+    $item['localized_options']['attributes']['class'] = explode(' ', $item['options']['attributes']['class']);
+  }
   // If we are translating the title of a menu link, and its title is the same
   // as the corresponding router item, then we can use the title information
   // from the router. If it's customized, then we need to use the link title
@@ -805,16 +813,21 @@
 /**
  * Returns a rendered menu tree.
  *
+ * The menu item's LI element is given one of the following classes:
+ * - expanded: The menu item is showing its submenu.
+ * - collapsed: The menu item has a submenu which is not shown.
+ * - leaf: The menu item has no submenu.
+ *
  * @param $tree
  *   A data structure representing the tree as returned from menu_tree_data.
  * @return
- *   The rendered HTML of that data structure.
+ *   A structured array to be rendered by drupal_render().
  */
 function menu_tree_output($tree) {
-  $output = '';
+  $build = array();
   $items = array();
 
-  // Pull out just the menu items we are going to render so that we
+  // Pull out just the menu links we are going to render so that we
   // get an accurate count for the first/last classes.
   foreach ($tree as $data) {
     if (!$data['link']['hidden']) {
@@ -824,23 +837,47 @@
 
   $num_items = count($items);
   foreach ($items as $i => $data) {
-    $extra_class = array();
+    $class = array();
     if ($i == 0) {
-      $extra_class[] = 'first';
+      $class[] = 'first';
     }
     if ($i == $num_items - 1) {
-      $extra_class[] = 'last';
+      $class[] = 'last';
     }
-    $extra_class = implode(' ', $extra_class);
-    $link = theme('menu_item_link', $data['link']);
+    // Set a class if the link has children.
     if ($data['below']) {
-      $output .= theme('menu_item', $link, $data['link']['has_children'], menu_tree_output($data['below']), $data['link']['in_active_trail'], $extra_class);
+      $class[] = 'expanded';
+    }
+    elseif ($data['link']['has_children']) {
+      $class[] = 'collapsed';
     }
     else {
-      $output .= theme('menu_item', $link, $data['link']['has_children'], '', $data['link']['in_active_trail'], $extra_class);
+      $class[] = 'leaf';
     }
+    // Set a class if the link is in the active trail.
+    if ($data['link']['in_active_trail']) {
+      $class[] = 'active-trail';
+      $data['localized_options']['attributes']['class'][] = 'active-trail';
+    }
+
+    $element['#theme'] = 'menu_link';
+    $element['#attributes']['class'] = $class;
+    $element['#title'] = $data['link']['title'];
+    $element['#href'] = $data['link']['href'];
+    $element['#localized_options'] = !empty($data['localized_options']) ? $data['localized_options'] : array();
+    $element['#below'] = $data['below'] ? menu_tree_output($data['below']) : $data['below'];
+    $element['#original_link'] = $data['link'];
+    // Index using the link's unique mlid.
+    $build[$data['link']['mlid']] = $element;
+  }
+  if ($build) {
+    // Make sure drupal_render() does not re-order the links.
+    $build['#sorted'] = TRUE;
+    // Add the theme wrapper for outer markup.
+    $build['#theme_wrappers'][] = 'menu_tree';
   }
-  return $output ? theme('menu_tree', $output) : '';
+
+  return $build;
 }
 
 /**
@@ -1254,20 +1291,16 @@
 }
 
 /**
- * Generate the HTML output for a single menu link.
+ * Preprocess the rendered tree for theme_menu_tree.
  *
  * @ingroup themeable
  */
-function theme_menu_item_link($link) {
-  if (empty($link['localized_options'])) {
-    $link['localized_options'] = array();
-  }
-
-  return l($link['title'], $link['href'], $link['localized_options']);
+function template_preprocess_menu_tree(&$variables) {
+  $variables['tree'] = $variables['tree']['#children'];
 }
 
 /**
- * Generate the HTML output for a menu tree
+ * Theme wrapper for the HTML output for a menu sub-tree.
  *
  * @ingroup themeable
  */
@@ -1276,56 +1309,47 @@
 }
 
 /**
- * Generate the HTML output for a menu item and submenu.
+ * Generate the HTML output for a menu link and submenu.
  *
- * The menu item's LI element is given one of the following classes:
- * - expanded: The menu item is showing its submenu.
- * - collapsed: The menu item has a submenu which is not shown.
- * - leaf: The menu item has no submenu.
+ * @param $element
+ *   Structured array data for a menu link.
  *
  * @ingroup themeable
- *
- * @param $link
- *   The fully-formatted link for this menu item.
- * @param $has_children
- *   Boolean value indicating if this menu item has children.
- * @param $menu
- *   Contains a fully-formatted submenu, if one exists for this menu item.
- *   Defaults to NULL.
- * @param $in_active_trail
- *   Boolean determining if the current page is below the menu item in the
- *   menu system. Defaults to FALSE.
- * @param $extra_class
- *   Extra classes that should be added to the class of the list item.
- *   Defaults to NULL.
- */
-function theme_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
-  $class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
-  if (!empty($extra_class)) {
-    $class .= ' ' . $extra_class;
-  }
-  if ($in_active_trail) {
-    $class .= ' active-trail';
+ */
+function theme_menu_link(array $element) {
+  $sub_menu = '';
+
+  if ($element['#below']) {
+    $sub_menu = drupal_render($element['#below']);
   }
-  return '<li class="' . $class . '">' . $link . $menu . "</li>\n";
+  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
+  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
 }
 
 /**
  * Generate the HTML output for a single local task link.
  *
+ * @param $link
+ *   A menu link array with 'title', 'href', and 'localized_options' keys.
+ * @param $active
+ *   A boolean indicating whether the local task is active.
+ *
  * @ingroup themeable
  */
 function theme_menu_local_task($link, $active = FALSE) {
-  return '<li ' . ($active ? 'class="active" ' : '') . '>' . $link . "</li>\n";
+  return '<li ' . ($active ? 'class="active" ' : '') . '>' . l($link['title'], $link['href'], $link['localized_options']) . "</li>\n";
 }
 
 /**
  * Generate the HTML output for a single local action link.
  *
+ * @param $link
+ *   A menu link array with 'title', 'href', and 'localized_options' keys.
+ *
  * @ingroup themeable
  */
 function theme_menu_local_action($link) {
-  return '<li>' . $link . "</li>\n";
+  return '<li>' . l($link['title'], $link['href'], $link['localized_options']) . "</li>\n";
 }
 
 /**
@@ -1528,17 +1552,18 @@
       $action_count = 0;
       foreach ($children[$path] as $item) {
         if ($item['access']) {
+          $link = $item;
           // The default task is always active.
           if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) {
             // Find the first parent which is not a default local task or action.
             for ($p = $item['tab_parent']; $tasks[$p]['type'] == MENU_DEFAULT_LOCAL_TASK; $p = $tasks[$p]['tab_parent']);
-            $link = theme('menu_item_link', array('href' => $tasks[$p]['href']) + $item);
+            // Use the path of the parent instead.
+            $link['href'] = $tasks[$p]['href'];
             $tabs_current .= theme('menu_local_task', $link, TRUE);
             $next_path = $item['path'];
             $tab_count++;
           }
           else {
-            $link = theme('menu_item_link', $item);
             if ($item['type'] == MENU_LOCAL_TASK) {
               $tabs_current .= theme('menu_local_task', $link);
               $tab_count++;
@@ -1574,17 +1599,16 @@
         }
         if ($item['access']) {
           $count++;
+          $link = $item;
           if ($item['type'] == MENU_DEFAULT_LOCAL_TASK) {
             // Find the first parent which is not a default local task.
             for ($p = $item['tab_parent']; $tasks[$p]['type'] == MENU_DEFAULT_LOCAL_TASK; $p = $tasks[$p]['tab_parent']);
-            $link = theme('menu_item_link', array('href' => $tasks[$p]['href']) + $item);
+            // Use the path of the parent instead.
+            $link['href'] = $tasks[$p]['href'];
             if ($item['path'] == $router_item['path']) {
               $root_path = $tasks[$p]['path'];
             }
           }
-          else {
-            $link = theme('menu_item_link', $item);
-          }
           // We check for the active tab.
           if ($item['path'] == $path) {
             $tabs_current .= theme('menu_local_task', $link, TRUE);

--- modules/book/book-all-books-block.tpl.php   2009/04/08 03:23:46     1.3
+++ modules/book/book-all-books-block.tpl.php   2009/09/18 10:54:20     1.4
@@ -8,13 +8,12 @@
  * all pages" which presents Multiple independent books on all pages.
  *
  * Available variables:
- * - $book_menus: Array of book outlines rendered as an unordered list. It is
- *   keyed to the parent book ID which is also the ID of the parent node
- *   containing an entire outline.
+ * - $book_menus: Array of book outlines keyed to the parent book ID. Call
+ *   render() on each to print it as an unordered list.
  */
 ?>
 <?php foreach ($book_menus as $book_id => $menu) : ?>
 <div id="book-block-menu-<?php print $book_id; ?>" class="book-block-menu">
-  <?php print $menu; ?>
+  <?php print render($menu); ?>
 </div>
 <?php endforeach; ?>

--- modules/book/book.module    2009/09/10 12:33:43     1.513
+++ modules/book/book.module    2009/09/18 10:54:20     1.514
@@ -248,7 +248,8 @@
         $book_menus[$book_id] = menu_tree_output($pseudo_tree);
       }
     }
-    $block['content'] = theme('book_all_books_block', $book_menus);
+    $book_menus['#theme'] = 'book_all_books_block';
+    $block['content'] = $book_menus;
   }
   elseif ($current_bid) {
     // Only display this block when the user is browsing a book.
@@ -705,7 +706,7 @@
     }
   }
 
-  return $children ? menu_tree_output($children) : '';
+  return $children ? drupal_render(menu_tree_output($children)) : '';
 }
 
 /**
@@ -892,6 +893,27 @@
 }
 
 /**
+ * Process variables for book-all-books-block.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $book_menus
+ *
+ * All non-renderable elements are removed so that the template has full
+ * access to the structured data but can also simply iterate over all
+ * elements and render them (as in the default template).
+ *
+ * @see book-navigation.tpl.php
+ */
+function template_preprocess_book_all_books_block(&$variables) {
+  // Remove all non-renderable elements.
+  $elements = $variables['book_menus'];
+  $variables['book_menus'] = array();
+  foreach (element_children($elements) as $index) {
+    $variables['book_menus'][$index] = $elements[$index];
+  }
+}
+
+/**
  * Process variables for book-navigation.tpl.php.
  *
  * The $variables array contains the following arguments:

No votes yet
  • Drupal Core
  • Download patch

Recent posts

  • Bugfix woes for Drupal 6
  • Arbitrary PHP code execution in modx 1.0.0 via CSRF
  • The #drupal consultant
  • Varnish vs. page cache graph
  • FAPI - How to decrease/increase the text limit of textfields?
more

Tags

Captcha CSRF Drupal Let's hope it doesn't become popular modx Performance PHP Pitfalls Planet Drupal Security V-PowerServer Varnish
more tags
  • home
  • drupal
  • drupal core commits
  • about

Copyright © 2009 by Heine Deelstra. All rights reserved.