1

I am using two menu modules to display parent and children items in different locations in the website header. The simplified code below shows how it is written in index.php.

I am needing to check to see if a menu item has children. If it does, the following class has-nested-nav should be added to the <header> div. This class will adjust the bottom padding on the header depending on if the nested nav module is displayed.

I have tested the code, but it does not yield the results I am needing. Please advise on what should be changed to get the code working.

Cheers.

Template HTML

<header class="**Add has-nested-nav class here**">
    <!-- Parent menu items -->
    <section>
    <?php if($this->countModules('global-navigation')): ?>
        <jdoc:include type="modules" name="global-navigation" />
    <?php endif; ?>
    </section>

    <!-- Children menu items -->
    <section>
    <?php if($this->countModules('global-nested-navigation')): ?>
        <jdoc:include type="modules" name="global-nested-navigation" />
    <?php endif; ?>
    </section>
</header>

Template includes/helper.php file

$hasParent = $menu->getItem( $menu->getActive()->parent_id );
if ($hasParent == 1) {
    $hasNestedNav = true;
} else {
    $hasNestedNav = false;
}

$mrwcNavClass = '';
if ($hasNestedNav) {
    $mrwcNavClass .= ' has-nested-nav';
}

if (!defined( 'MRWC_NAV_CLASS' )) {
    define( 'MRWC_NAV_CLASS', $mrwcNavClass);
}

Current Code - Not working

$active = $menu->getActive();
// $childCount = count($menu->getItems('parent_id', $active->id));
$children = $menu->getItems('parent_id', $active->id);
$visibleChildren = array_filter($children, function($child) {
    return ($child->getParams('menu_show', 1) === 1);
});

$childCount = count($visibleChildren);
if ($childCount == 1) {
    $hasNestedNav = true;
} else {
    $hasNestedNav = false;
}

$active menu item dump

object(Joomla\CMS\Menu\MenuItem)[699]
public 'id' => string '122' (length=3)
public 'menutype' => string 'global-navigation' (length=17)
public 'title' => string 'Education' (length=9)
public 'alias' => string 'education' (length=9)
public 'note' => string '' (length=0)
public 'route' => string 'education' (length=9)
public 'link' => string 'index.php?option=com_content&view=article&id=2' (length=46)
public 'type' => string 'component' (length=9)
public 'level' => string '1' (length=1)
public 'language' => string '*' (length=1)
public 'browserNav' => string '0' (length=1)
public 'access' => string '1' (length=1)
protected 'params' => 
  object(Joomla\Registry\Registry)[913]
  protected 'data' => 
    object(stdClass)[915]
      public 'show_title' => string '' (length=0)
      public 'link_titles' => string '' (length=0)
      public 'show_intro' => string '' (length=0)
      public 'info_block_position' => string '' (length=0)
      public 'info_block_show_title' => string '' (length=0)
      public 'show_category' => string '' (length=0)
      public 'link_category' => string '' (length=0)
      public 'show_parent_category' => string '' (length=0)
      public 'link_parent_category' => string '' (length=0)
      public 'show_associations' => string '' (length=0)
      public 'show_author' => string '' (length=0)
      public 'link_author' => string '' (length=0)
      public 'show_create_date' => string '' (length=0)
      public 'show_modify_date' => string '' (length=0)
      public 'show_publish_date' => string '' (length=0)
      public 'show_item_navigation' => string '' (length=0)
      public 'show_vote' => string '' (length=0)
      public 'show_icons' => string '' (length=0)
      public 'show_print_icon' => string '' (length=0)
      public 'show_email_icon' => string '' (length=0)
      public 'show_hits' => string '' (length=0)
      public 'show_tags' => string '' (length=0)
      public 'show_noauth' => string '' (length=0)
      public 'urls_position' => string '' (length=0)
      public 'menu-anchor_title' => string 'Education' (length=9)
      public 'menu-anchor_css' => string '' (length=0)
      public 'menu_image' => string 'images/media/images/svg/nav-current-marker.svg' (length=46)
      public 'menu_image_css' => string '' (length=0)
      public 'menu_text' => int 1
      public 'menu_show' => int 1
      public 'page_title' => string '' (length=0)
      public 'show_page_heading' => string '' (length=0)
      public 'page_heading' => string 'Education' (length=9)
      public 'pageclass_sfx' => string '' (length=0)
      public 'menu-meta_description' => string '' (length=0)
      public 'menu-meta_keywords' => string '' (length=0)
      public 'robots' => string '' (length=0)
      public 'secure' => int 0
  protected 'initialized' => boolean true
  public 'separator' => string '.' (length=1)
  public 'home' => string '0' (length=1)
  public 'img' => string ' ' (length=1)
  public 'template_style_id' => string '0' (length=1)
  public 'component_id' => string '22' (length=2)
  public 'parent_id' => string '1' (length=1)
  public 'component' => string 'com_content' (length=11)
  public 'tree' => 
      array (size=1)
      0 => string '122' (length=3)
      public 'query' => 
          array (size=3)
          'option' => string 'com_content' (length=11)
          'view' => string 'article' (length=7)
          'id' => string '2' (length=1)

$children menu items dump

array (size=2)
0 => 
    object(Joomla\CMS\Menu\MenuItem)[726]
    public 'id' => string '1544' (length=4)
    public 'menutype' => string 'global-navigation' (length=17)
    public 'title' => string 'Classrooms' (length=10)
    public 'alias' => string 'classroom' (length=9)
    public 'note' => string '' (length=0)
    public 'route' => string 'education/classroom' (length=19)
    public 'link' => string 'index.php?option=com_content&view=article&id=261' (length=48)
    public 'type' => string 'component' (length=9)
    public 'level' => string '2' (length=1)
    public 'language' => string '*' (length=1)
    public 'browserNav' => string '0' (length=1)
    public 'access' => string '1' (length=1)
    protected 'params' => 
        object(Joomla\Registry\Registry)[1490]
        protected 'data' => 
            object(stdClass)[1492]
            ...
            protected 'initialized' => boolean true
            public 'separator' => string '.' (length=1)
            public 'home' => string '0' (length=1)
            public 'img' => string ' ' (length=1)
            public 'template_style_id' => string '0' (length=1)
            public 'component_id' => string '22' (length=2)
            public 'parent_id' => string '122' (length=3)
            public 'component' => string 'com_content' (length=11)
            public 'tree' => 
                array (size=2)
                0 => string '122' (length=3)
                1 => string '1544' (length=4)
            public 'query' => 
                array (size=3)
                'option' => string 'com_content' (length=11)
                'view' => string 'article' (length=7)
                'id' => string '261' (length=3)
   1 => 
      object(Joomla\CMS\Menu\MenuItem)[725]
      public 'id' => string '1545' (length=4)
      public 'menutype' => string 'global-navigation' (length=17)
      public 'title' => string 'In The Community' (length=16)
      public 'alias' => string 'community' (length=9)
      public 'note' => string '' (length=0)
      public 'route' => string 'education/community' (length=19)
      public 'link' => string 'index.php?option=com_content&view=article&id=262' (length=48)
      public 'type' => string 'component' (length=9)
      public 'level' => string '2' (length=1)
      public 'language' => string '*' (length=1)
      public 'browserNav' => string '0' (length=1)
      public 'access' => string '1' (length=1)
      protected 'params' => 
          object(Joomla\Registry\Registry)[1491]
          protected 'data' => 
              object(stdClass)[1494]
              ...
              protected 'initialized' => boolean true
              public 'separator' => string '.' (length=1)
              public 'home' => string '0' (length=1)
              public 'img' => string ' ' (length=1)
              public 'template_style_id' => string '0' (length=1)
              public 'component_id' => string '22' (length=2)
              public 'parent_id' => string '122' (length=3)
              public 'component' => string 'com_content' (length=11)
              public 'tree' => 
                  array (size=2)
                  0 => string '122' (length=3)
                  1 => string '1545' (length=4)
                  public 'query' => 
                      array (size=3)
                      'option' => string 'com_content' (length=11)
                      'view' => string 'article' (length=7)
                      'id' => string '262' (length=3)

1 Answer 1

1

If I'm correctly understanding what you're wanting to do, this code doesn't do it. I think you're wanting $hasNestedNav to be true when the active menu item has children, and what it's doing is actually setting $hasNestedNav true always (every menu item has a parent, the root items in every menu will have parent_id == 1).

If what you're wanting is a test for the existence of children of the current item, try this:

$menu = JFactory::getApplication()->getMenu()
$active = $menu->getActive();
$childCount = count($menu->getItems('parent_id', $active->id);

And then test $childCount to see if there are children of the active menu item. (Interesting side note: the return from the getItems call is an array of the child menu items, so you could stuff that into a variable if you wanted to do any further checking or filtering -- for example walking the array to filter out the menu items that have the parameter menu_show set to off (hides them from navigation menus) to keep them from counting towards the total.)

Obviously, this code isn't testing for the Bad Stuff that could happen if any of those calls fail, it's just the 'happy path' to the answer. I'll leave the error handling as an exercise for the reader.

Filtering

$children = $menu->getItems('parent_id', $active->id);
$visibleChildren = array_filter($children, function($child) {
    $params = $child->getParams();
    return ($params->get('menu_show', 1) === 1);
});

After which the array $visibleChildren will contain only the ones with "menu_show" set to 1. You can then count it to know if there are visible children.

Or, if this doesn't work on your version of PHP (or if it just seems like too much work) you could simply walk the $children array with a foreach and test each child's "menu_show" param, breaking out of the loop on the first occurrence of a "true" (after all, for your purposes how many there are doesn't matter, all you need to know is there is at least one visible child).

16
  • Thanks for the code. It has got me most of the way. Now I need to check to see if any of the children menu items have the "Display in menu" parameter set to "No". Would I need to grab that param and perform a second check? Feb 27, 2020 at 20:46
  • Probably the simplest way to do that is to pass the getItems() array into array_filter(). That way you can test the param in the callback, and the resulting array will have only the visible items left in it.
    – Arlen
    Feb 27, 2020 at 22:12
  • Thanks for the code. I have implemented it in my template and have modified $childCount = count($menu->getItems('parent_id', $active->id)); to be $childCount = count($visibleChildren);. When I use var_dump($childCount), the value is always 0 even if there are a mix of Display in Menu menu items. Using PHP 7.3.9. Feb 29, 2020 at 2:44
  • The result from the call to getActive drives that, so which menu item is returned from it? The other important value is what the parent_id is: $active->parent_id, because what this code is doing is getting all the menu items with that parent_id (Libraries/src/Menu/SiteMenu.php). Things that can effect this include various SEF add-ons.
    – Arlen
    Mar 2, 2020 at 14:15
  • Nothing is being returned. Outputting a var_dump in the browser using $visibleChildren displays an empty array. I have updated my original question with the code that you suggested and am currently using. Mar 2, 2020 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.