Настройка меню Zend_Navigation для работы с jQuery Fisheye

Я использую Zend_Navigation (кстати, приятное дополнение к фреймворку) для создания своего меню, после чего оно должно отображаться на странице (очевидно). Сначала я установил контейнер где-нибудь в контроллере:

// $pages is the array containing all page information
$nav = new Zend_Navigation($pages);
$this->view->navigation($nav);

Затем в макете это отображается так:

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

который отлично работает. Теперь: я хочу, чтобы меню отображалось немного по-другому. Страница, которую я создаю, использует jQuery плагин Fisheye. для создания Mac-подобного Dock-меню. Однако этому плагину нужна определенная разметка...

На самом деле, он принимает список из <a> элементов, содержащих как <img> (для значка), так и <span> (для всплывающей подсказки). Стандартный помощник представления меню отображает все внутри неупорядоченного списка (логически) с параметром 'label' в качестве текста ссылки.

Кажется, что содержимое, переданное параметру 'label', экранируется перед рендерингом, поэтому вставка html туда мне не поможет. Кроме того, Fisheye обычно не берет свои элементы, содержащиеся в теге <li>, со всем, обернутым в <ul></ul>, а просто одноуровневый список из <a> элементов.

Я думал о написании собственного вспомогательного представления для дока, который мог бы позаботиться о вставке <img> и <span>, но мне очень трудно получить вспомогательное вспомогательное средство пользовательского представления, прикрепленное к классу навигации. Я просто не могу понять, где его разместить и каким образом, хотя обо всех других моих пользовательских классах (моделях и т. д.) сладко заботится автозагрузчик. Любые идеи по этому поводу?

С другой стороны, даже если я смогу заставить этот помощник представления работать, я все равно останусь с неупорядоченным списком HTML — я знаю, что могу потерять и его, используя настраиваемый помощник представления, но я всегда был поклонником содержания основного меню навигации внутри списка для семантики.

Если кто-нибудь может мне немного помочь, буду очень признателен. Если Fisheye просто не предназначен для работы с <ul>, это очень плохо... будет ли в этом случае веская причина вообще отказаться от Zend_Navigation?


person JorenB    schedule 07.08.2009    source источник


Ответы (2)


Я еще не видел способа сделать собственный рендерер. Вот что я в итоге сделал:

Во-первых, вместо рендеринга вызова menu() по умолчанию создайте партиал для рендеринга:

// menu.phtml is partial, cms is module
$partial = array('menu.phtml', 'cms');
$this->navigation()->menu()->setPartial($partial);
echo $this->navigation()->menu()->render();

Затем (из документов) вы можете создать «пользовательский» рендеринг следующим образом:

// -- inside menu.phtml
foreach ($this->container as $page) 
{
    // this just prints a "<a>" or "<span>" tag
    // depending on whether the page has a uri
    echo $this->menu()->htmlify($page), PHP_EOL;
}

В итоге я сделал то, что у меня было изначально (меню с одним уровнем подменю) с помощью этого скрипта:

// -- another menu.phtml
<ul class="navigation">

<?php

$html = array();

foreach ($this->container as $page) 
{
    $html[] = "<li>";
    $html[] = $this->menu()->htmlify($page) . PHP_EOL;

    if (!empty($page->pages))
    {
        $html[] = "<ul>";
        foreach ($page->pages as $subpage) 
        {
            $html[] = "<li>";
            if ($href = $subpage->getHref()) $html[] = "<a href=\"{$href}\">";
            else $html[] = "<span>";
            $html[] = "<img src=\"/ui/cms/img/icons/edit.png\" alt=\"\"/>";
            $html[] = $subpage->getLabel();
            if ($href) $html[] = "</a>";
            else $html[] = "</span>";            
            $html[] = "</li>";
        }
        $html[] = "</ul>";
    }

    $html[] = "</li>";
}

echo join(PHP_EOL, $html);

?>
</ul>

Вы можете просто изменить разметку в партиале и добавить туда свои изображения/значки.

person typeoneerror    schedule 10.08.2009
comment
Вау, идеальный ответ. Кажется, над Zend_Navigation еще нужно поработать, но это приведет меня туда, куда мне нужно. Спасибо! - person JorenB; 14.08.2009
comment
@JorenB, чтобы вы тоже знали, я только что спросил Мэтью П. (ведущий разработчик ZF), будут ли они включать декораторы для навигации в любой момент. Он сказал (вкратце), что не запланировано, потому что у партиалов очень мало накладных расходов, а декораторы не нравятся сообществу ... кажется, что Zend_Nav сам по себе является хитом производительности. - person typeoneerror; 18.08.2009
comment
Я пробовал это, но контейнер пуст... object(Zend\Navigation\Navigation)#509 (3) { [pages:protected] =› array(0) { } [index:protected] =› array(0) { } [dirtyIndex:protected] =› bool(false) } - person cwhisperer; 16.10.2013
comment
Замените $this->menu()->htmlify($page) . PHP_EOL; на $this->navigation()->menu()->htmlify($page) . PHP_EOL;. - person Indrasinh Bihola; 30.05.2016

Извините за проблему с форматированием в предыдущем посте

Чтобы добавить свой собственный помощник, выполните следующие действия в начальной загрузке:

protected function _initNavigation()
{
    $this->bootstrap('view');           // make sure we have a view
    $view = $this->getResource('view');     // get the view resource
    $config = new Zend_Config_Xml(APPLICATION_ROOT . '/config/navigation.xml','nav');
    $container = new Zend_Navigation($config);
    $view->navigation($container);

    // Tell Zend were it can find your custom helpers and what
    // the prefix is going to be.

   $view->addHelperPath(
          APPLICATION_ROOT . '/library/MyApp/View/Helper/Navigation',
          'MyApp_View_Helper_'
          );

}

Затем создайте свой пользовательский помощник представления и поместите его в путь «addHelperPath». В зависимости от того, что вы хотите сделать, вам нужно реализовать хотя бы собственную функцию htmlify. Взгляните на Zend/View/Help/Navigation/Menu.php в качестве примера.

class MyApp_View_Helper_MyMenu extends Zend_View_Helper_Navigation_Menu
{
    public function myMenu(Zend_Navigation_Container $container = null)
    {
        if (null !== $container) {
            $this->setContainer($container);
        }
        return $this;
    }

    protected function htmlify(Zend_Navigation_Page $page ) 
    {
        ...
    }
}

Далее в вашем phtml-скрипте:

   <?php echo $this->navigation()->myMenu()->setMaxDepth(0); ?>

или просто

   <?php echo $this->navigation()->myMenu(); ?>

Теперь, если вы хотите добавить свои собственные пользовательские свойства в сгенерированный HTML-код, вы можете добавить их в свой навигационный файл ini или xml. Например:

<home>
  <label>Home</label>
  <uri>/</uri>
  <img>
      <src>/images/MyIcon.gif</src>
  <img>
</home>

Пользовательский тег xml <img> будет сохранен как свойство страницы навигации и может быть получен следующим образом:

foreach ($iterator as $page) {

    ...

    $properties = new Zend_Config($page->GetCustomProperties());
    $myPicture = $properties->img->src;

    ...
}

Надеюсь это поможет. Питер

person Peter    schedule 29.11.2009
comment
Ваше решение помогло мне с моим вопросом. Спасибо! stackoverflow.com/questions/2364695/ - person Sonny; 02.03.2010