Zend framework2 导航中的ZF2自定义属性

Zend framework2 导航中的ZF2自定义属性,zend-framework2,Zend Framework2,如何将自定义属性添加到Zend Framework 2导航中? 我知道我可以添加id或类->但仅此而已 1) 例如,如何添加data test='blahblah'属性? 2) 我可以为包含实际链接的li元素添加属性吗 $container = new Zend\Navigation\Navigation(array( array( 'label' => 'Page 1', 'id' => 'home-link', 'uri'

如何将自定义属性添加到Zend Framework 2导航中?
我知道我可以添加id或类->但仅此而已

1) 例如,如何添加
data test='blahblah'
属性?
2) 我可以为包含实际链接的
li
元素添加属性吗

$container = new Zend\Navigation\Navigation(array(
    array(
        'label' => 'Page 1',
        'id' => 'home-link',
        'uri' => '/',
    ),
    array(
        'label' => 'Zend',
        'uri' => 'http://www.zend-project.com/',
        'order' => 100,
    ),
);
编辑:

@布拉姆·格瑞森:谢谢你的回答


是-我可以添加
'data-test'=>'blahblah'
并将其作为
$page->get('data-test')
检索-但这仍然不会将其作为属性附加到
中。。。。我必须重写htmlify吗?

页面类有一些专用的公共属性设置器(
setLabel
setId
setUri
等),如果设置器不存在,将调用
\u set
。有关这方面的更多信息以及扩展
AbstractPage
类的更多信息,请参见

array(
    'label' => 'Page 1',
    'id' => 'home-link',
    'uri' => '/',
    'data-test' => 'blahblah'
),
现在您可以执行
$page->get('data_test')
,它将返回blahblah

第二个问题是关于更改菜单的呈现方式(向
li
添加属性)。ZF2正在使用来呈现导航菜单。 所有导航视图帮助程序都可以使用
setPartial()
使用自己的局部视图进行渲染

在viewscript中:

$partial = array('menu.phtml', 'default');
$this->navigation()->menu()->setPartial($partial);
echo $this->navigation()->menu()->render();
在局部视图
菜单中.phtml
执行以下操作:

<ul>
<?php foreach ($this->container as $page): ?>
    <li data-test="<?=$page->get('data_test')?>"><?=$this->navigation()->menu()->htmlify($page)?></li>
<?php endforeach; ?>
<ul>
<nav class="navbar navbar-default navbar-static-top" role="navigation">
    <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
    </div>
    <div class="collapse navbar-collapse navbar-ex1-collapse">
    <?php
        // Use Zend\Navigation to create the menu
        $container = $this->navigation('navigation')->getContainer();
        echo $this->NewMenu($container)->setUlClass('nav navbar-nav')->escapeLabels(false);
    ?>
    </div><!-- /.navbar-collapse -->
</nav>

    Bram的回答帮助我找到了一个解决方案,以下是我需要的以及我是如何解决的(因为我是ZF2和名称空间的新手,所以我花了比它应该花的时间更长的时间,所以希望这能帮助其他人)

    问题

    • 希望使用
      Zend\Navigation
      从其
      isActive()
      方法和内置的翻译、ACL等支持中获益
    • 需要将CSS类名添加到
    • 元素和
      元素。(ZF2的菜单视图帮助程序当前支持“非此即彼”方法)
    • 需要将CSS类名添加到嵌套的
      元素中
    • 需要向
      元素添加其他属性,如
      数据-*=“…”
    • 需要这些更改来支持Bootstrap 3标记

    解决方案说明

    • 通过扩展
      Zend\View\Helper\Navigation\Menu
    • 稍微修改
      renderNormalMenu()
      htmlify()
      方法
    • 利用向
      Zend\Pages
      添加自定义属性的功能,向某些元素添加CSS类和其他属性

    解决方案

    步骤1

    在应用程序模块
    src\Application\View\Helper\NewMenu.php

    <?php
    /**
     * Zend Framework (http://framework.zend.com/) ...*/
    
    namespace Application;
    
    use Zend\Mvc\ModuleRouteListener;
    use Zend\Mvc\MvcEvent;
    
    class Module
    {
        // ** snip **
    
        public function getViewHelperConfig()   {
            return array(
                'invokables' => array(
                    // The 'key' is what is used to call the view helper
                    'NewMenu' => 'Application\View\Helper\NewMenu',
                )
            );
        }
    }
    
    NewMenu.php

    <?php
    namespace Application\View\Helper;
    
    // I'm extending this class, need to include it
    use Zend\View\Helper\Navigation\Menu;
    
    // Include namespaces we're using (from Zend\View\Helper\Navigation\Menu)
    use RecursiveIteratorIterator;
    use Zend\Navigation\AbstractContainer;
    use Zend\Navigation\Page\AbstractPage;
    
    
    class NewMenu extends Menu
    {
        // copied fromZend\View\Helper\Navigation\Menu
        protected function renderNormalMenu(...){} 
    
        // copied from Zend\View\Helper\Navigation\Menu
        public function htmlify(...){}
    }
    
    步骤3

    在我的
    layout.phtml
    脚本中,我获取导航容器并将其传递给NewMenu视图帮助程序。我还设置了一些选项,如添加父类
      类名和不转义标签,以便我可以将引导使用的标准“下拉插入符号”(即
      )添加到带有下拉菜单的标签中

      $container = $this->navigation('navigation')->getContainer();
      echo $this->NewMenu($container)->setUlClass('nav navbar-nav')->escapeLabels(false);
      

      间歇

      在这一点上,我们应该或多或少地复制菜单视图辅助程序。它应该像标准视图辅助程序那样生成导航


      步骤4

      NewMenu.php
      类中,我删除了
      $addClassToListItem
      代码,以避免它意外地将类放在错误的元素上

      受保护的函数renderNormalMenu(…)

      现在,在导航配置文件中,我们只需添加一个名为
      wrapClass
      的属性,即可将CSS类应用于包装元素(
    • config\autoload\global.php

      在配置文件中,您现在可以添加一个具有附加属性数组的属性:

      config\autoload\global.php

      需要注意的重要事项是,UL类需要放在子类的第一个子页上,因为条件语句包装在以下条件中:

      if ($depth > $prevDepth) {
          // start new ul tag
          ...
      }
      
      调用第一个子级后,$dept=$prevDepth和嵌套的
      将已发送到字符串缓冲区


      这个解决方案还没有经过严格的测试,但是它的想法是,它只需要获取当前的菜单视图帮助器,并重载两个必要的方法,并且只对其进行轻微的修改

      我曾尝试使用
      setPartial()
      ,但这只对
    • 生成有所帮助,它仍然使用菜单视图助手的
      htmlify()
      方法(所有这些都在Bram上面的讨论中提到)

      因此,通过将这些小tweek添加到to方法,并使用Page类具有自定义属性的功能,我可以添加一些额外的逻辑来获取
    • 和嵌套的
        类上的类名,以及在
        元素上添加额外的属性,以便配置
        >Zend\Navigation
        从配置中弹出,基本上是Bootstrap 3导航条标记

        末端布局如下所示:

        <ul>
        <?php foreach ($this->container as $page): ?>
            <li data-test="<?=$page->get('data_test')?>"><?=$this->navigation()->menu()->htmlify($page)?></li>
        <?php endforeach; ?>
        <ul>
        
        <nav class="navbar navbar-default navbar-static-top" role="navigation">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div class="collapse navbar-collapse navbar-ex1-collapse">
            <?php
                // Use Zend\Navigation to create the menu
                $container = $this->navigation('navigation')->getContainer();
                echo $this->NewMenu($container)->setUlClass('nav navbar-nav')->escapeLabels(false);
            ?>
            </div><!-- /.navbar-collapse -->
        </nav>
        
        这行不通:

        $this->navigation('navigation')->NewMenu();
        
        我之所以这样想,是因为
        NewMenu
        的名称空间问题没有在导航视图助手类中注册,我不打算为此扩展它

        所以,希望这个(长的)答案能帮助那些正在与这种需求作斗争的人


        干杯

        问题 标签上的插入符号标签会导致以下问题:

        • 面包屑
        • 菜单翻译
        泼洒 要防止在标签中添加标记插入符号,您可以在菜单配置中添加此参数的支持。您应该

        受保护的函数renderNormalMenu()

        ps.jmbertucci,你就是那个人。

        ... 'navigation' => array( 'default' => array( ... array( 'label' => 'Products <b class="caret"></b>', 'route' => 'products', 'wrapClass' => 'dropdown', // class to <li> 'class' => 'dropdown-toggle', // class to <a> like usual 'attribs' => array( 'data-toggle' => 'dropdown', // Key = Attr name, Value = Attr Value ), 'pages' => array( array( 'label' => 'Cars', 'route' => 'products/type', ... ), ... ), ), ...
        if ($depth > $prevDepth) {
            // start new ul tag
            if ($ulClass && $depth ==  0) {
                $ulClass = ' class="' . $ulClass . '"';
            }
        
            // Added ElseIf below
        
            else if($ulClass = $page->get('pagesContainerClass')){
                $ulClass = ' class="' . $ulClass . '"';
            }
        
            else {
                $ulClass = '';
            }
            $html .= $myIndent . '<ul' . $ulClass . '>' . self::EOL;
        
        ...
        'navigation' => array(
            'default' => array(
                ...
                array(
                    'label' => 'Products <b class="caret"></b>',
                    'route' => 'products',
                    'wrapClass' => 'dropdown',         // class to <li>
                    'class'     => 'dropdown-toggle',  // class to <a> like usual
        
                    'attribs'   => array(
                        'data-toggle' => 'dropdown',  // Key = Attr name, Value = Attr Value
                    ),
        
                    'pages' => array(
                        array(
                            'label' => 'Cars',
                            'route' => 'products/type',
                            // Give child <ul> a class name
                            'pagesContainerClass' => 'dropdown-menu',
                            ...
                        ),
                        ...
                    ),
                ),
        ...
        
        if ($depth > $prevDepth) {
            // start new ul tag
            ...
        }
        
        <nav class="navbar navbar-default navbar-static-top" role="navigation">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <div class="collapse navbar-collapse navbar-ex1-collapse">
            <?php
                // Use Zend\Navigation to create the menu
                $container = $this->navigation('navigation')->getContainer();
                echo $this->NewMenu($container)->setUlClass('nav navbar-nav')->escapeLabels(false);
            ?>
            </div><!-- /.navbar-collapse -->
        </nav>
        
        $this->navigation('navigation')->menu();
        
        $this->navigation('navigation')->NewMenu();
        
        src\Application\View\Helper\NewMenu.php
        
        /// add 4th parameter $page->get('caret')
        $html .= $myIndent . '    <li' . $liClass . '>' . PHP_EOL .
        $myIndent . '        ' .
        $this->htmlify($page, $escapeLabels, $addClassToListItem, $page->get('caret')) . PHP_EOL;
        
        } else {
            $html .= $label;
        }
        //// add this if
        if($caret === true){
            $html .= '<b class="caret"></b>';
        }
        
        $html .= '</' . $element . '>';
        
         array(
                        'label' => 'Some label',
                        'caret' => true,
                        'route' => 'someroute',
                        'wrapClass' => 'dropdown',
                        'class' => 'dropdown-toggle',