【问题标题】:ZF2 Dynamic Menu with Zend\Navigation\NavigationZF2 动态菜单与 Zend\Navigation\Navigation
【发布时间】:2012-09-13 22:17:45
【问题描述】:

我想问你这个问题。 使用 Zend\Navigation\Navigation 创建动态菜单需要什么?

在 ZF1 中我是这样制作的:

$container = new Zend_Navigation();
$pages = array(
array(
    'label'  => 'Save',
    'action' => 'save',
),
array(
    'label'  => 'Delete',
    'action' => 'delete',
),
);
// add two pages
$container->addPages($pages);

然后在视野中:

$this->navigation()->menu();

但在 ZF2 中,页面取自配置。 现在我创建 \config\autoload\nav.global.php 并在这里创建页面数组。但我需要在方法中做页面数组并将其发送到导航助手,但我不知道如何((

我试图在我的控制器中这样做:

use Zend\Navigation\Navigation;
$pages =array(
        // All navigation-related configuration is collected in the 'navigation' key
        'navigation' => array(
            // The DefaultNavigationFactory we configured in (1) uses 'default' as the sitemap key
            'default' => array(
                // And finally, here is where we define our page hierarchy
                'account' => array(
                    'label' => 'faq',
                    'route' => 'faq',
                    'pages' => array(
                        'news' => array(
                            'label' => 'news',
                            'route' => 'news',
                            ),
                            'manual' => array(
                            'label' => 'manual',
                            'route' => 'manual',
                            ),               
                    ),
                ),
            ),
        ),
    );
$Menu = new Navigation($pages);

然后在视图中:

$this->Menu()->menu();

但我有很多错误......

我想你理解我的问题。 请帮忙。 对不起我的英语。

【问题讨论】:

    标签: php dynamic menu navigation zend-framework2


    【解决方案1】:

    按照这些简单的步骤动态创建多级菜单 1:创建一个部分 menu.phtml 文件并将其保存在布局文件夹或 模块,例如application/view/layout/menu.phtml

     <ul  id="menu" >
    
        <?php foreach ($this->container as $page): ?>
    
            <li <?= $page->isActive()? 'class="active"' : 'class="drop"' ?>>
    
                <?php echo $this->navigation()->menu()->htmlify($page). PHP_EOL ?>
    
         <div class="dropdown_2columns" >
    
    
                               <?php  foreach ($page as $catpage) :?>
    
                        <div  class="col_1" >
    
                                  <h3 <?= $page->isActive()? 'class="active"' : 'class="drop"' ?> >
                <?= $this->navigation()->menu()->htmlify($catpage). PHP_EOL ?>
                       </h3>
                            <ul  >
    
                               <?php  foreach ($catpage as $subpage) :?>
    
                               <li  <?= $subpage->isActive()? 'class="active"' : 'class="drop"' ?>>
                <?= $this->navigation()->menu()->htmlify($subpage). PHP_EOL ?>
    
    
                               <?php endforeach; ?>
                            </ul>   
    
                        </div>
    
                          <?php endforeach; ?>
    
                    </div><!-- End dropdown container -->
    
                        </li>
    
                    <?php endforeach; ?>
     </ul>
    

    module.php 中的第 2 步

    public function getServiceConfig()
        {
            return array(
                    'initializers' => array(
                            function ($instance, $sm) {
                                if ($instance instanceof \Zend\Db\Adapter\AdapterAwareInterface) {
                                    $instance->setDbAdapter($sm->get('Zend\Db\Adapter\Adapter'));
                                }
                            }
                    ),
                    'invokables' => array(
                            'menu' => 'Application\Model\MenuTable',
    
                    ),
    
                    'factories' => array(
                            'Navigation' => 'Application\Navigation\YourNavigationFactory'
                    )
            );
        } 
    

    在模块的 src/navigation 文件夹中创建 YourNavigation.php 和 YourNavigationFactory.php

    namespace Application\Navigation;
    
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\Navigation\Service\DefaultNavigationFactory;
    use Admin\Model\Entity\Tablepages;
    class YourNavigation extends DefaultNavigationFactory
    {
    
    
    
    
        protected function getPages(ServiceLocatorInterface $serviceLocator)
        {
    
            if (null === $this->pages) {
    
                $fetchMenu = $serviceLocator->get('menu')->fetchAll();
    
    
                $configuration['navigation'][$this->getName()] = array();
    
    
    
                foreach($fetchMenu as $key=>$row)
                {
    
                    $subMenu = $serviceLocator->get('menu')->fetchAllSubMenus($row['id']);
    
               if($subMenu){
                  $pages = array();
                    foreach($subMenu as $k=>$v)
                    {
                        foreach($v as $field=>$value){
                            $page['label'] =$value['heading'];
                            $page['route'] = 'visas';
                            if ($value['path'] == $row['path']){
                            $page['params'] = array('action'=>'index',
                                                     'category'=> $this->$row['path'],
    
                            );
    
    
                            }
    
                            $subCatMenu = $serviceLocator->get('menu')->fetchAllSubCatMenus($value['id']);
    
                            $subcatpages = array();
                            $subcatgroup = array();
                            $group = array();
                            if($subCatMenu>0){
    
                            foreach($subCatMenu as $k=>$v)
                            {
                                foreach($v as $field=>$value1){
    
                                    $subpage['label'] =$value1['heading'];
                                    $subpage['route'] = 'visas';
                                    if ($value['path'] ==$row['path']){
    
                                        $subpage['params'] = array('action'=>'index',
                                              'category'=> $row['path'],
                                              'sub_category'=> $value1['path']);
    
    
                                    }elseif($row['id'] ==76){
                                        $subpage['params'] = array('action'=>'index',
                                                'category'=>$value['path'],
                                                'sub_category'=>$value1['path']);
    
    
                                    }else{
    
                                    $subpage['params'] = array('action'=>'index',
                                                'category'=> $row['path'],
                                                'sub_category'=> $value['path'],
                                                'id'=> $value1['path']);
                                    }
    
                                }
                                $group[] =$subpage;
    
    
                             }
    
                           $page['pages'] =$group;
                           $pages[] =$page;
    
    
                            }
    
    
                            }
    
                   }
    
    
               }
    
    
                   $configuration['navigation'][$this->getName()][$row['name']] = array(
                        'label' => $row['name'],
    
                         'route' => 'visas',
                        'params'       => array(
                                'action' => 'index',
                                'category' => $row['path'],
    
                        ),
    
                       'pages' =>  $pages,
    
                    );
    
    
                }
    
    
    
                if (!isset($configuration['navigation'])) {
    
                    throw new Exception\InvalidArgumentException('Could not find navigation configuration key');
                }
                if (!isset($configuration['navigation'][$this->getName()])) {
    
                    throw new Exception\InvalidArgumentException(sprintf(
                        'Failed to find a navigation container by the name "%s"',
                        $this->getName()
                    ));
                }
    
                $application = $serviceLocator->get('Application');
    
                $routeMatch  = $application->getMvcEvent()->getRouteMatch();
    
                $router      = $application->getMvcEvent()->getRouter();
                $pages       = $this->getPagesFromConfig($configuration['navigation'][$this->getName()]);
    
    
                $this->pages = $this->injectComponents($pages, $routeMatch, $router);
            }
    
            return $this->pages;
        }
    }
    

    YourNavigationFactory.php

     namespace Application\Navigation;
    
        use Zend\ServiceManager\FactoryInterface;
        use Zend\ServiceManager\ServiceLocatorInterface;
    
            class YourNavigationFactory implements FactoryInterface
            {
                public function createService(ServiceLocatorInterface $serviceLocator)
                {
                    $navigation =  new MyNavigation();
                    return $navigation->createService($serviceLocator);
                }
            }
    

    在你的 layout.phtml 中

     <?php  echo $this->navigation('navigation')->menu()->setPartial('menu')->render();  ?>
    

    从导航创建动态站点地图

        $this->navigation('navigation')
              ->sitemap()
              ->setUseXmlDeclaration(false)
              ->setServerUrl('http://www.yourdomain.com')
              ->setFormatOutput(true);?>
    
       echo $this->navigation()->menu()->setMinDepth(null)->setMaxDepth(null)->setOnlyActiveBranch(false)->setRenderInvisible(true);
    

    创建面包屑

    echo $this->navigation()
                      ->breadcrumbs()
                      ->setLinkLast(true)                 
                      ->setMaxDepth(1)                     
                      ->setSeparator(' ▶' . PHP_EOL);
    

    我希望它可以帮助您节省时间

    【讨论】:

    • 请解释一下您的 Application\Model\MenuTable 中有什么
    • Siwei ,基本上我已经构建了我的自定义 CMS,它具有三层,例如 category->subcategory->sub subcategories。所以树是这样创建的,从上到下都有链接。与我进行查询以获取数据并进行循环以生成导航结构的方式相同。示例可以在brightervisas.com 上找到。如果您对您的问题有任何疑问,请给我留言,我可以帮助您解决问题
    【解决方案2】:

    对于某些背景,您可能会在另一个上阅读 this answer,但关于 Zend\Navigation 的类似问题。关键是您希望 MVC 页面和 Zend Framework 2 中的 MVC 页面需要一种方法来组装 url 并找到我们的 url 是否处于活动状态。

    每个 MVC 页面都有一个路由名称。路由堆栈路由请求并获得路由匹配。您必须将此路由匹配注入到导航中,以便每个页面都可以根据匹配的路由检查自己的路由。

    与 url 程序集类似。如果要将路由名称转换为 url,则需要路由堆栈('router')。在你的应用程序中也注入路由器,你就可以组装了。

    简而言之:

    use Zend\Navigation\Service\ConstructedNavigationFactory;
    
    class MyController extends AbstractActionController
    {
    
      public function indexAction()
      {
        $config = array(
          // your config here
        );
    
        $factory    = new ConstructedNavigationFactory($config);
        $navigation = $factory->createService($this->getServiceLocator());
    
        return new ViewModel(array(
            'navigation' => $navigation;
        ));
      }
    }
    

    在您看来,与上述答案类似:

    <?php echo $this->navigation($navigation)->menu()?>
    

    【讨论】:

      【解决方案3】:

      我之前的回答不正确。以下代码有效。一页。在控制器中,编辑操作:

      $page = new \Zend\Navigation\Page\Mvc(array(
          'route' => 'application/default',
          'controller' => 'album',
          'action'     => 'edit',
          'use_route_match' => true,
      ));
      
      $r = $this->getEvent()->getRouter();
      $rm = $this->getEvent()->getRouteMatch();
      $page->setRouter($r);
      $page->setRouteMatch($rm);
      
      echo $page->isActive() ? 'true' : 'false'; // true
      echo $page->getHref(); // /test_app/public/application/album/edit/id1
      

      【讨论】:

        【解决方案4】:

        你需要这样做

        在控制器中

        $pages = new \Zend\Navigation\Page\Mvc(array(
                'pages'=>
                    array(
                        'album' => array(
                            'label' => 'Album3',
                            'controller' => 'album',
                            'action' => 'edit',
                            'params' => array('id'=>2),
                            'route' => 'album/default',
                        )
                    )
        ));
        
        $navigation = new \Zend\Navigation\Navigation();
        $serviceLocator = $this->getServiceLocator()->get('Application');
        $routeMatch  = $serviceLocator->getMvcEvent()->getRouteMatch();
        $router      = $serviceLocator->getMvcEvent()->getRouter();
        $pages->setRouteMatch($routeMatch);
        $pages->setDefaultRouter($router);
        
        $navigation->addPage($pages);
        

        在视图中

        <?php echo $this->navigation($this->navigation)->menu() ?>
        

        【讨论】:

        • 应用不需要抓取,路由匹配和路由栈在控制器的事件中都有。
        • 顺便说一句,这也根本不起作用,因为“相册”页面不包含路由匹配并且永远不会被标记为活动。路由器可以设置为默认,路由不匹配。因此,我对你的答案投了反对票。
        【解决方案5】:

        Eremite 的答案并没有错。我已经测试了这里给出的所有建议,实际上当默认路由有几个 child_routes 标记为默认时,菜单没有正确标记活动标志。因此需要将匹配的路由作为参数传递。但也许我做错了什么。

        干杯

        【讨论】:

          猜你喜欢
          • 2012-11-28
          • 1970-01-01
          • 1970-01-01
          • 2011-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-19
          相关资源
          最近更新 更多