利用 步驟1
Creat在\module\Application\Module.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',
)
);
}
}
步驟3版自定義視圖助手應用程序模塊src\Application\View\Helper\NewMenu.php
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(...){}
}
步驟2
註冊新視圖助手下與getViewHelperConfig()
在我的layout.phtml
腳本中,我得到我的導航容器並將它傳遞給NewMenu視圖助手。我還設置了一些選項,例如添加父級<ul>
類名稱而不是轉義標籤,以便我可以將Bootstrap使用的標準'dropdown caret'(即<b class="caret"></b>
)添加到帶有下拉菜單的標籤。
$container = $this->navigation('navigation')->getContainer();
echo $this->NewMenu($container)->setUlClass('nav navbar-nav')->escapeLabels(false);
中場
在這一點上,我們應該有更多或更少的只是複製了菜單視圖助手。它應該像標準的View Helper一樣產生一個導航。
步驟4
在NewMenu.php
類,我刪除$addClassToListItem
代碼,以避免它從由事故放置類錯誤的元件上。
protected function renderNormalMenu(...)
// Add CSS class from page to <li>
//if ($addClassToListItem && $page->getClass()) {
// $liClasses[] = $page->getClass();
//}
公共職能htmlify(...)
// Always apply page class to <a> tag. We'll use a diff. method for <li>
//if ($addClassToListItem === false) {
$attribs['class'] = $page->getClass();
//}
步驟5
添加一個方法來CSS類名適用於<li>
標籤,因爲我們去掉了$addClassTolistItem
方法。我們只需使用Page類的能力,具有自定義屬性,並做到這一點:
保護功能renderNormalMenu現在
// Is page active?
if ($isActive) {
$liClasses[] = 'active';
}
if($wrapClass = $page->get('wrapClass')){
$liClasses[] = $wrapClass;
}
...
,在我們的導航配置文件,我們只需添加一個名爲wrapClass
應用CSS屬性類包裝元素(<li>
)。
設置\自動加載\ global.php
...
'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
'pages' => array(
array(
'label' => 'Cars',
'route' => 'products/type',
...
),
...
),
),
...
步驟6
添加到對<a>
附加屬性等data-*
的能力。對於Bootstrap 3,例如,您需要data-toggle="dropdown"
。
公共職能htmlify(...)
// get attribs for element
$attribs = array(
'id' => $page->getId(),
'title' => $title,
);
// add additional attributes
$attr = $page->get('attribs');
if(is_array($attr)){
$attribs = $attribs + $attr;
}
在您的配置文件,你現在可以添加一個屬性與附加屬性的數組:
配置\自動加載\全球。 PHP
...
'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',
...
),
...
),
),
...
步驟7
添加在嵌套列表容器上放置類名的功能(例如, <ul>
)。
保護功能renderNormalMenu()
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;
原來的代碼基本上說:「如果這是第一次<ul>
,有一個UL類,添加它,別的什麼也不做。所以,我增加了一個額外的檢查。就是說,如果一個屬性叫pagesContainerClass
是可用的,對類適用於<ul>
以及
這意味着我們需要在我們的配置中添加右側頁面的屬性:
config \ autoload \ global。PHP
...
'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',
...
),
...
),
),
...
重要的是注意,UL類需要放在一個孩子的第一個子頁面是因爲條件語句被包裹在以下條件:
if ($depth > $prevDepth) {
// start new ul tag
...
}
第一後孩子被調用,$ dept = $ prevDepth和嵌套的<ul>
已經被髮送到字符串緩衝區。
該解決方案還沒有被嚴格的測試,但這個想法是簡單地取當前菜單視圖助手,和過載的兩個必要方法和僅略微修改了。
我試着使用setPartial()
,但只有具有<li>
代的幫助下,該公司仍使用菜單視圖助手htmlify()
方法(所有這些都在布拉姆的討論上面提到的)。
因此,與使這些小tweeks的方法和使用Page類的具有自定義屬性的能力,我可以添加一些額外的邏輯來獲得關於<li>
,<a>
和嵌套<ul>
類的類名,以及添加額外的屬性的<a>
元素,所以我可以配置我的Zend\Navigation
從配置吐出來,基本上,Bootstrap 3 Navbar標記。
最終佈局則看起來就像這樣:
<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>
我一直運行到的煩惱是更好地瞭解PHP命名空間,並具有需要包括相應的合格的命名空間在我的自定義視圖助手,即使我正在擴展它。
的另一個問題,是導航視圖助手可以調用菜單視圖助手從本身就像這樣:
$this->navigation('navigation')->menu();
這是行不通的:
$this->navigation('navigation')->NewMenu();
我想是因爲與NewMenu
沒有在Navigation View Helper類中註冊的命名空間問題,我不打算僅僅爲此而擴展它。
所以,希望這(長)答案將有助於其他誰正在努力滿足這種需求。
乾杯!
謝謝您的回答。 是 - 我可以添加「數據測試」 =>「blahblah」和檢索它作爲$頁面級>的get(「數據測試」) - 但仍無法將其追加爲屬性爲 .. ..我必須重寫htmlify到那個? – 2013-02-24 00:56:20
是的,你需要擴展菜單視圖助手,並且只能覆蓋htmlify方法。看看htmlify方法,你會看到數組定義的attrib。你可以在那裏添加你的自定義屬性。看到我的【答案】(http://stackoverflow.com/questions/15017288/injecting-custom-navigation-using-a-view-helper-through-the-servicemanager/15019924#15019924)上的另一SO如何註冊質疑您自己的導航視圖助手。 – 2013-02-24 01:31:35
感謝您的回覆。所以 - 我的菜單實際上有2個層次的深度...所以基本上 - 視圖部分 - 我必須遞歸迭代容器 - 正確嗎?我不能只是簡單地對頁面項目進行foreach ... – 2013-02-24 04:01:21