zendframework / zend-navigation

Navigation component from Zend Framework
BSD 3-Clause "New" or "Revised" License
20 stars 25 forks source link

Zend\Navigation\Page\Mvc - IsActive Function "improvement ?" #53

Closed h3christophe closed 7 years ago

h3christophe commented 7 years ago

Hello Right now to check if a Mvc Page is active you guys check if

$this->routeMatch->getMatchedRouteName() === $this->getRoute()

and that the parameters match

 (count(array_intersect_assoc($reqParams, $pageParams)) == count($pageParams)

I was wondering if we could improve this behavior by checking first if the Page route is actually contained in the Matched Route

Lets take an example: Router conf:

'routes' => array(
            'production' => [
                'type' => 'segment',
                'may_terminate' => true,
                'options' => [
                    'route' => '/production',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Production\Controller',
                        'controller' => 'Index',
                        'action' => 'index'
                    )
                ],
                'child_routes' => [
                    'project' => [
                        'type' => 'segment',
                        'options' => [
                            'route' => '/project[/:action[/:id]]',
                            'defaults' => array(
                                'controller' => 'Project',
                                'action' => 'index'
                            )
                        ],
                    ],

This assume that the child route project is under production

so route "production/project" is a child of "production"

Navigation Conf:

 'navigation' => [
            'production' => [
                'id' => 'project',
                'label' => 'Production label',
                'route' => 'production'

The current isActive function does not work in this situation because the routes are different The workaround it to create a child navigation under "production" but i feel like it is overkill (as i dont want to display the child page in the navigation (so i use the param visible = 0 ))

My solution would be to check that the page route is contained in the Matched route

strpos($this->routeMatch->getMatchedRouteName(), $this->getRoute().'/') === 0

In my scenario It would check if "production/" is contained in the "production/project" (at the beginning of the string)

And make the Page active

so if you are viewing the site via the "production/project" route it will make all navigation set up to use the route "production" active

Please let me know if that make sense or if I am missing something that would make this solution incorrect

Thank you

froschdesign commented 7 years ago

@h3christophe

Sorry for the late response.

so if you are viewing the site via the "production/project" route it will make all navigation set up to use the route "production" active

This is your scenario! And all the others?

<ul>
    <li>
        <a href="/products/server/faq">FAQ</a>
    </li>
    <li>
        <a href="/products/server/editions">Editions</a>
    </li>
    <li>
        <a href="/products/server/requirements">System Requirements</a>
    </li>
</ul>

The current matched route name is "products/server/faq". Which list item should selected?

Also the breadcrumbs will not work.