Bramの回答は、私が必要としていたものと解決方法を示しています(私はZF2と名前空間が初めてだったので、必要以上に時間がかかったので、これが他の人に役立つことを願っています)
問題
Zend\Navigation
そのisActive()
メソッドと組み込みの変換、ACL などのサポートを活用して使用したい。
<li>
要素と 要素に CSS クラス名を追加する必要がありました<a>
。(ZF2 のメニュー ビュー ヘルパーは現在、「どちらか一方」のアプローチをサポートしています)
- ネストされた
<ul>
要素に CSS クラス名を追加する必要がありました。
<a>
次のような追加の属性を要素に追加する必要がありましたdata-*="..."
- Bootstrap 3 マークアップをサポートするには、これらの変更が必要でした
ソリューションの説明
- 拡張して顧客ビュー ヘルパーを作成する
Zend\View\Helper\Navigation\Menu
renderNormalMenu()
およびhtmlify()
メソッドを少し変更します。
- カスタム プロパティを追加する機能を利用し
Zend\Pages
て、CSS クラスと追加の属性をいくつかの要素に追加します。
解決
ステップ1
Application モジュールの下にカスタム View Helper を作成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
に新しい View Helper を登録しgetViewHelperConfig()
ました\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
私のlayout.phtml
スクリプトでは、Navigation コンテナーを取得し、それを NewMenu ビュー ヘルパーに渡します。また、親<ul>
クラス名を追加し、ラベルをエスケープしないなどのオプションを設定して、Bootstrap が使用する標準の「ドロップダウン キャレット」(つまり<b class="caret"></b>
) をドロップダウン メニュー付きのラベルに追加できるようにします。
$container = $this->navigation('navigation')->getContainer();
echo $this->NewMenu($container)->setUlClass('nav navbar-nav')->escapeLabels(false);
休憩
この時点で、Menu View Helper をほぼ複製したはずです。標準の View Helper と同じ方法でナビゲーションを生成する必要があります。
ステップ 4
クラスでは、誤って間違った要素にクラスを配置することを避けるためにNewMenu.php
、コードを削除します。$addClassToListItem
保護された関数 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
ここで、Navigation 構成ファイルに、 CSS クラスをラッピング要素 ( ) に適用するために呼び出されるプロパティを追加するだけ<li>
です。
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
'pages' => array(
array(
'label' => 'Cars',
'route' => 'products/type',
...
),
...
),
),
...
ステップ 6
<a>
likeに追加の属性を持つ機能を追加します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;
}
構成ファイルで、追加の属性の配列を持つプロパティを追加できるようになりました。
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',
...
),
...
),
),
...
ステップ 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>
されたものは既に文字列バッファーに送信されています。
このソリューションは厳密にはテストされていませんが、現在のメニュー ビュー ヘルパーを単純に取得し、必要な 2 つのメソッドをオーバーロードし、それをわずかに変更するだけという考え方です。
私は使用しようとしましたが、それは生成にsetPartial()
役立つだけでし<li>
た.メニュービューヘルパーのhtmlify()
メソッドをまだ使用していました.
したがって、これらの小さな調整を to メソッドに加え、Page クラスのカスタム プロパティを持つ機能を使用することで、いくつかの追加ロジックを追加して<li>
、<a>
およびネストされたクラスのクラス名を取得し、要素に<ul>
追加のプロパティを追加することができたので、 config から<a>
myZend\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 名前空間をよりよく理解することと、カスタム ビュー ヘルパーを拡張していたとしても、適切な限定名前空間を含める必要があることでした。
もう 1 つの問題は、Navigation View Helper が次のように Menu View Helper を呼び出すことができることです。
$this->navigation('navigation')->menu();
これはうまくいきません:
$this->navigation('navigation')->NewMenu();
Navigation View Helper クラスに登録されていないという名前空間の問題が原因で考えてNewMenu
います。そのためだけに拡張するつもりはありません。
したがって、うまくいけば、この (長い) 回答が、この必要性に苦しんでいる他の人に役立つことを願っています.
乾杯!