Render Custom Menu Block from Menu Tree Array of Links Programmatically

Here’s what I have: A custom menu (side nav) that mimics the main/secondary menu tree which shows the entire subtree of the root menu item (Dine, Play, Stay) you’re under.

enter image description here

This sidenav can be shortened with a checkbox field in the content type. If checked, the sidenav shows the checked page as the root and all children, recursively, but omits any parents of the checked page. I’ve successfully created that menu and this all works on the checked pages.

enter image description here

This yields:

enter image description here

This is done by creating both menus, then adding a “hide” css class to one of them in the template_preprocess_page() function, depending on the checkbox of the current node.

MY ISSUE: The final thing I need it to do is when you are on a CHILD page of a parent with the shortened nav checked, I need it to still show that shortened nav. So on the example above, when on the Visitor FAQ page, it needs to show the shortened menu from Visitor Tips (with the current page bolded or whatever). So it needs to grab the field from the parent node, and if it is true, grab the shortened submenu array, which I’ve done, but I haven’t been able to render the menu tree array into html correctly.

Here’s the current code for grabbing the submenu (from the full menu), and it saves the menu array in $alternateSecondaryMenu. I also tried saving in $vars[‘secondary_nav’], which is the key Drupal uses for the rendered menu array, but I think the menu has already rendered by the time it calls preprocess_page(). I just can’t figure out how to render that menu tree. (The menu is 4 levels deep, level 0 being the root menu item, so this only happens on level 1 or level 2.)

In template.php:

function THEME_preprocess_page(&$vars) {    // Follow active-trail and check if short/long menu is toggled   // ***********************************************************   if(!empty($vars['secondary_nav'])) {      // Level 1     foreach($vars['secondary_nav'] as &$topmenuitem) { // for each top level item       if(!empty($topmenuitem['#title'])) {          if(in_array('active-trail', $topmenuitem['#attributes']['class'])) { // check if in active-trail (parent)            // load the node of the parent menu item           $firstnid = str_replace('node/','',$topmenuitem['#href']);           $firstnode = node_load($firstnid);            // check for shortened menu checkbox           if (array_key_exists('field_show_menu_as_parent',$firstnode) && $firstnode->field_show_menu_as_parent && $firstnode->field_show_menu_as_parent['und'][0]['value']) {              dsm("1. YES, shortened menu.");              // Saving this submenu in these variables             $vars['secondary_nav'] = $topmenuitem; // this is the drupal-made array that shows the menu in question             $alternateSecondaryMenu = $topmenuitem; // just saving to some other variable, too.            } else {             dsm("1. NO shortened Menu for you!");           }            // Level 2 (same as level one)           foreach($topmenuitem['#below'] as &$secondmenuitem) {             if(!empty($secondmenuitem['#title'])) {                             if(in_array('active-trail', $secondmenuitem['#attributes']['class'])) {                 $secondnid = str_replace('node/','',$secondmenuitem['#href']);                 $secondnode = node_load($secondnid);                 if (array_key_exists('field_show_menu_as_parent',$secondnode) && $secondnode->field_show_menu_as_parent && $secondnode->field_show_menu_as_parent['und'][0]['value']) {                   dsm("2. YES, shortened menu.");                                 $vars['secondary_nav'] = $secondmenuitem;                   $alternateSecondaryMenu = $secondmenuitem;                 } else {                   dsm("2. NO shortened menu for you!");                 }                              }             }           }                   }       }     }        }    dsm(drupal_render($alternateSecondaryMenu));    // Only renders an <li> of the current node, not the <ul> or the children <li>, even though it has the whole menu tree.   dsm($vars['secondary_nav']);    // doesn't render anything because this preprocess_page() is called after the elements of the page have already rendered, right? } 

I am using Panelizer to display and Menu Block to create the menu (only modules that ones that might be relevant).

Do I need to call the theme_menu_tree() and theme_menu_link() functions on this array again to render it, somehow? I wasn’t able to get render() or drupal_render() to work. Also tried doing this with menu_preprocessing/tree functions but was having difficulty getting the checkbox value in the nodes. Any ideas or help would be GREATLY appreciated.

Thanks!

Sponsored by SupremePR
This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Render Custom Menu Block from Menu Tree Array of Links Programmatically

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.