Zend导航菜单手风琴

时间:2014-05-08 14:48:06

标签: php jquery zend-framework

我目前在Zend项目中有一个导航菜单。我现在要做的是为它添加一个手风琴,有点像http://jsfiddle.net/Yb23C/2/。但我似乎无法将其添加到当前的Zend Navigation设置中。

我的Bootstrap.php中有这个:

$userconfig = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'menuLoggedUser');    
$usercontainer = new Zend_Navigation($userconfig);
Zend_Registry::set('user',$usercontainer);

在layout.phtml中我有这个:

$menu = $this->navigation()->menu(Zend_Registry::get('user'));

$menuNoUl = explode("\n",$menu);
array_pop($menuNoUl);
array_shift($menuNoUl);

echo join(" ",$menuNoUl);

出现在<ul>个标记内。

我修改了我的navigation.xml以在文件集组中添加<pages>标记以开始测试:

   <menuLoggedUser>
         <home>
            <label>Home</label>
            <uri>/test/index</uri>
         </home>
         <filesets>
            <label>Filesets</label>
            <uri>javascript:void(0)</uri>
            <pages>
                <owner>
                    <label>Owner</label>
                    <uri>/test/filesets/owner</uri>
                </owner>
                <info>          
                    <label>Info</label>
                    <uri>/test/filesets/info</uri>
                </info>
                <quota>
                    <label>Quota</label>
                    <uri>/test/filesets/quota</uri>
                </quota>
            </pages>
         </filesets>
         <group>
        <label>Group</label>
        <uri>/test/groups/group</uri>
         </group>
          <user>
        <label>User Info</label>
        <uri>/test/user/usermanagement</uri>
         </user>
         <logout>
            <label>Logout</label>
            <uri>/test/index/logout</uri>
         </logout>
   </menuLoggedUser>

目前给我这个:

Current menu without accordion

我希望这些项目符号出现在手风琴中,因此当用户点击“文件集”时,菜单会展开以显示这些项目符号,再次点击时会隐藏它们。

我尝试在->setMaxDepth(0)之后添加->setMinDepth(1)$menu = $this->navigation()->menu(Zend_Registry::get('user')),但它没有提供我想要的结果。我找不到任何关于如何使用Zend Navigation完成任务的信息,我知道我不能成为第一个。感谢任何可以提供帮助的人!

编辑

导航的生成HTML代码,之前:

<!-- NAVIGATION_BEGIN -->
<div id="proj-navigation">
 <h2 class="proj-access">Start of left navigation</h2>
<ul id="proj-primary-links">
<li id="proj-overview"><a href="">W3</a></li>
    <li>         <a href="/index">Home</a>     </li>     
    <li>         <a href="/filesets/fileset">Filesets</a>     </li>     
    <li>         <a href="/index/logout">Logout</a>     </li>
</ul>
</div>
<!-- NAVIGATION_END -->

导航的生成HTML代码,包含当前更改:

<!-- NAVIGATION_BEGIN -->
<div id="proj-navigation">
 <h2 class="proj-access">Start of left navigation</h2>
<ul id="proj-primary-links">
<li id="proj-overview"><a href="">W3</a></li>
    <li>    <a href="/index.php/index">Home</a>     </li>     
    <li>    <a href="javascript:void(0)">Filesets</a>         
        <ul>

            <li>    <a href="/index.php/filesets/owner">Owner</a>   </li>             
            <li>    <a href="/index.php/filesets/info">Info</a> </li>             
            <li>    <a href="/index.php/filesets/quota">Quota</a>   </li>             

        </ul>
    </li> 
    <li>    <a href="/index/logout">Logout</a>     </li>
</ul>
</div>
<!-- NAVIGATION_END -->

编辑2

如果我能让嵌套的<ul>得到一个班级或ID,我相信我能够让我的手风琴导航工作,但无论我尝试什么,它都没有似乎工作。

2 个答案:

答案 0 :(得分:2)

显然,查看代码时,我们无法将类添加到不在第1级的ul标记。
所以你可以创建自己的视图助手 要做到这一点:

  1. application.ini中定义视图助手 例如,使用“我的”库:

    resources.view.helperPath.My_View_Helper = "My/View/Helper"
    
  2. 添加My\View\Helper\Navigation.php文件

    <?php
    require_once 'Zend/View/Helper/Navigation.php';
    
    class My_View_Helper_Navigation
        extends Zend_View_Helper_Navigation
    {
        const NS = 'My_View_Helper_Navigation';
    
        public function findHelper($proxy, $strict = true)
        {
            if (isset($this->_helpers[$proxy])) {
                return $this->_helpers[$proxy];
            }
    
            if (!$this->view->getPluginLoader('helper')->getPaths(self::NS)) {
                // Add navigation helper path at the beginning
                $paths = $this->view->getHelperPaths();
                $this->view->setHelperPath(null);
    
                $this->view->addHelperPath(
                        str_replace('_', '/', self::NS),
                        self::NS);
    
                foreach ($paths as $ns => $path) {
                    $this->view->addHelperPath($path, $ns);
                }
            }
    
            if ($strict) {
                $helper = $this->view->getHelper($proxy);
            } else {
                try {
                    $helper = $this->view->getHelper($proxy);
                } catch (Zend_Loader_PluginLoader_Exception $e) {
                    return null;
                }
            }
    
            if (!$helper instanceof Zend_View_Helper_Navigation_Helper) {
                if ($strict) {
                    require_once 'Zend/View/Exception.php';
                    $e = new Zend_View_Exception(sprintf(
                            'Proxy helper "%s" is not an instance of ' .
                            'Zend_View_Helper_Navigation_Helper',
                            get_class($helper)));
                    $e->setView($this->view);
                    throw $e;
                }
    
                return null;
            }
    
            $this->_inject($helper);
            $this->_helpers[$proxy] = $helper;
    
            return $helper;
        }   
    }
    
  3. 添加My\View\Helper\Navigation\Menu.php文件

    <?php
    require_once 'Zend/View/Helper/Navigation/Menu.php';
    
    class My_View_Helper_Navigation_Menu
        extends Zend_View_Helper_Navigation_Menu
    {
        protected $_ulClassDepth = '';
    
        protected function _renderMenu(Zend_Navigation_Container $container,
                                       $ulClass,
                                       $indent,
                                       $minDepth,
                                       $maxDepth,
                                       $onlyActive,
                                       $expandSibs,
                                       $ulId,
                                       $ulClassDepth)
        {
            $html = '';
            // find deepest active
            if ($found = $this->findActive($container, $minDepth, $maxDepth)) {
                $foundPage = $found['page'];
                $foundDepth = $found['depth'];
            } else {
                $foundPage = null;
            }
    
            // create iterator
            $iterator = new RecursiveIteratorIterator($container,
                                RecursiveIteratorIterator::SELF_FIRST);
            if (is_int($maxDepth)) {
                $iterator->setMaxDepth($maxDepth);
            }
    
            // iterate container
            $prevDepth = -1;
            foreach ($iterator as $page) {
                $depth = $iterator->getDepth();
                $isActive = $page->isActive(true);
                if ($depth < $minDepth || !$this->accept($page)) {
                    // page is below minDepth or not accepted by acl/visibilty
                    continue;
                } else if ($expandSibs && $depth > $minDepth) {
                    // page is not active itself, but might be in the active branch
                    $accept = false;
                    if ($foundPage) {
                        if ($foundPage->hasPage($page)) {
                            // accept if page is a direct child of the active page
                            $accept = true;
                        } else if ($page->getParent()->isActive(true)) {
                            // page is a sibling of the active branch...
                        $accept = true;
                    }
                }
                if (!$isActive && !$accept) {
                    continue;
                }
            } else if ($onlyActive && !$isActive) {
                // page is not active itself, but might be in the active branch
                $accept = false;
                if ($foundPage) {
                    if ($foundPage->hasPage($page)) {
                        // accept if page is a direct child of the active page
                        $accept = true;
                    } else if ($foundPage->getParent()->hasPage($page)) {
                        // page is a sibling of the active page...
                        if (!$foundPage->hasPages() ||
                            is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
                            // accept if active page has no children, or the
                            // children are too deep to be rendered
                            $accept = true;
                        }
                    }
                }
    
                if (!$accept) {
                    continue;
                }
            }
    
            // make sure indentation is correct
            $depth -= $minDepth;
            $myIndent = $indent . str_repeat('        ', $depth);
    
            if ($depth > $prevDepth) {
                $attribs = array();
    
                // start new ul tag
                if (0 == $depth) {
                    $attribs = array(
                        'class' => $ulClass,
                        'id'    => $ulId,
                    );
                }
                else{
                    $attribs = array(
                        'class' => $ulClassDepth,
                    );
                }
    
    
                // We don't need a prefix for the menu ID (backup)
                $skipValue = $this->_skipPrefixForId;
                $this->skipPrefixForId();
    
                $html .= $myIndent . '<ul'
                                   . $this->_htmlAttribs($attribs)
                                   . '>'
                                   . self::EOL;
    
                // Reset prefix for IDs
                $this->_skipPrefixForId = $skipValue;
            } else if ($prevDepth > $depth) {
                // close li/ul tags until we're at current depth
                for ($i = $prevDepth; $i > $depth; $i--) {
                    $ind = $indent . str_repeat('        ', $i);
                    $html .= $ind . '    </li>' . self::EOL;
                    $html .= $ind . '</ul>' . self::EOL;
                }
                // close previous li tag
                $html .= $myIndent . '    </li>' . self::EOL;
            } else {
                // close previous li tag
                $html .= $myIndent . '    </li>' . self::EOL;
            }
    
            // render li tag and page
            $liClass = $isActive ? ' class="active"' : '';
            $html .= $myIndent . '    <li' . $liClass . '>' . self::EOL
                   . $myIndent . '        ' . $this->htmlify($page) . self::EOL;
    
            // store as previous depth for next iteration
            $prevDepth = $depth;
        }
    
        if ($html) {
            // done iterating container; close open ul/li tags
            for ($i = $prevDepth+1; $i > 0; $i--) {
                $myIndent = $indent . str_repeat('        ', $i-1);
                $html .= $myIndent . '    </li>' . self::EOL
                       . $myIndent . '</ul>' . self::EOL;
            }
            $html = rtrim($html, self::EOL);
        }
    
        return $html;
    }
    
    public function renderMenu(Zend_Navigation_Container $container = null,
                               array $options = array())
    {
        if (null === $container) {
            $container = $this->getContainer();
        }
    
        $options = $this->_normalizeOptions($options);
    
        if ($options['onlyActiveBranch'] && !$options['renderParents']) {
            $html = $this->_renderDeepestMenu($container,
                                              $options['ulClass'],
                                              $options['indent'],
                                              $options['minDepth'],
                                              $options['maxDepth'],
                                              $options['ulId']);
        } else {
            $html = $this->_renderMenu($container,
                                       $options['ulClass'],
                                       $options['indent'],
                                       $options['minDepth'],
                                       $options['maxDepth'],
                                       $options['onlyActiveBranch'],
                                       $options['expandSiblingNodesOfActiveBranch'],
                                       $options['ulId'],
                                       $options['ulClassDepth']);
        }
    
        return $html;
    }
    
    protected function _normalizeOptions(array $options = array())
    {
        $options = parent::_normalizeOptions($options);
        if (!isset($options['ulClassDepth'])) {
            $options['ulClassDepth'] = $this->getUlClassDepth();
        }
    
        return $options;
    }
    
    public function setUlClassDepth($ulClassDepth)
    {
        if (is_string($ulClassDepth)) {
            $this->_ulClassDepth = $ulClassDepth;
        }
    
        return $this;
    }
    
    public function getUlClassDepth()
    {
        return $this->_ulClassDepth;
    }
    

    }

  4. 使用新级别ulClassDepth为第二级

    调用您的菜单
    echo $this->navigation()->menu()->renderMenu(Zend_Registry::get('user'),
                                                 array('ulClassDepth' => 'sub-menu')
    );
    

答案 1 :(得分:1)

另一种可能性是使用这样的jquery:

<script>
$("li>ul").addClass("'sub-menu'");
</script>