Search code examples
phpzend-frameworktwitter-bootstrapzend-navigation

Zend Navigation - Mark parent active if a child is active


I'm currently creating my new website using Zend Framework 1.12.3 and I saw something I hate about Zend Navigation:

When a children route is active (exemple: a blog single post, route blog-post), it doesn't mark the parent page (route blog in this case) as active.

Here's my code: (navigation.xml)

<blog>
    <label>BLOG</label>
    <route>blog</route>
    <title>BLOG_TITLE</title>
    <pages>
        <blog-post>
            <route>blog-post</route>
            <visible>false</visible>
        </blog-article>
        <blog-category>
            <route>blog-category</route>
            <visible>false</visible>
        </blog-category>
    </pages>
</blog>

In clear, I would the page blog to be marked as active if a child route like blog-post is active. It doesn't do that unfortunately without using subpages (which I don't want). So if there's a way to mark active the route name blog and all routes who start with blog (exemple: blog-post, blog-category, blog-author) it would be very useful!

I don't want to use subpage for this because of my menu partial render a empty dropdown (Twitter Bootstrap). See by yourself:

Empty dropdown in Zend


Solution

  • I know it's already been answered, but I found different solution, because one posted by Marshall didn't work for me. I guess it's because I am not using action/controller in my menu, but routes instead.

    My menu entry looks like this:

    array(
        'label' => 'cms-nav_users',
        'access_module' => 'user',
        'resource' => 'user_admin',
        'route' => 'admin_user',
        'pages' => array(
            array(
                'label' => 'cms-nav_companies',
                'access_module' => 'user',
                'route' => 'company_admin',
                'resource' => 'company_admin',
            ),
            array(
                'label' => 'cms-nav_users-list',
                'access_module' => 'company',
                'route' => 'admin_user',
                'resource' => 'user_admin',
            ),
        ),
    ),
    

    I came up with a solution based on my own menu template (partial). Basically there is a foreach loop which checks if any of subpages is active and if there is one - marks parent as active, it looks like this:

    $active = false;
    
    if (!empty($page->pages))
    {
        foreach ($page->pages as $subpage) 
        {
            if ($subpage->isActive()) $active = true;
        }
    }
    
    $html[] = ($active) ?  'class="active"' : '';
    

    Hope it helps someone :)

    UPDATE

    Actually I found out that you can use Zend Framework's own isActive() with true parameter, as seen in source code:

    Zend_Navigation_Page_Mvc::isActive($recursive = false)
    

    Both ways will work, but this one seams more proper.