MPTT дерево в меню - PullRequest
       14

MPTT дерево в меню

1 голос
/ 23 марта 2012

У меня есть объект mptt $pages Через

foreach ($pages as $p):
    echo str_repeat('&nbsp;', 2 * $p->lvl).$p->nav.'<br/>';
endforeach;

его структура выглядит как http://pastebin.com/CSGenz7y

Мне нужно сделать меню навигации. Используя следующий код:

    echo '<ul id="jMenu">';
    $idn = 1;
    foreach ($pages as $s):
      if($s->lvl > $idn)
      {
        for($i=$s->lvl-$idn; $i>=1; $i--) echo '<ul>';
      }
      elseif($s->lvl < $idn)
      {
        for($i=$idn-$s->lvl; $i>=1; $i--) echo '</ul>';
      }
      $idn = $s->lvl;
      echo '<li>'.$s->nav.'</li>';
    endforeach;
    for($i=$s->lvl; $i>=1; $i--) echo '</ul>';
    echo '</ul>';

Я получаю следующий вывод: http://pastebin.com/MDMM2FcD

Но мне нужно, чтобы все дети были у родителей, чтобы быть внутри: li: http://pastebin.com/JteBPGqb

Я провел полдня и пришел ни с чем, есть идеи?

Ответы [ 2 ]

1 голос
/ 23 марта 2012

Вам следует дождаться закрытия следующего потомка массива li. Попробуйте этот код:

echo '<ul id="jMenu">';
$idn = 1;
foreach ($pages as $s):

    echo '<li>'.$s->nav;

    if($s->lvl > $idn){
        for($i=$s->lvl-$idn; $i>=1; $i--) echo '<ul>';
    }
    elseif($s->lvl < $idn) {
        for($i=$idn-$s->lvl; $i>=1; $i--) echo '</li></ul></li>';
    }
    else {
        echo '</li>';
    }

    $idn = $s->lvl;


endforeach;
for($i=$s->lvl; $i>=1; $i--) echo '</ul></li>';
echo '</ul>';
0 голосов
/ 05 ноября 2015

Эта реализация должна позволить более легкую настройку.

Использование:

<?php $orderLevelList = new OrderedLevelList; ?>
<ul class="main-menu">
<?php echo $orderLevelList->render($pages) ?>
</ul>

Код:

<?php
/**
 * Menu generator - expects that outer UL already exists (to allow custom class for example)
 */
class OrderedLevelList
{
    /**
     * Renders list
     *
     * @param array $pages array
     * @return string
     */
    public function render($pages)
    {
        $result = '';
        $lastLevel = $this->_getIntialLevel();
        foreach ($pages as $page) {
            $pageLevel = $this->_getLevel($page);
            if ($pageLevel > $lastLevel) {
                $result .= $this->_openList($pageLevel);
            } elseif ($pageLevel < $lastLevel) {
                $levelDiff = $lastLevel - $pageLevel;
                for ($i = $levelDiff; $i >= 0; $i--) {
                    $result .= $this->_closeList($pageLevel);
                    $result .= $this->_closeItem();
                }
            } else {
                $result .= $this->_closeItem();
            }
            $result .= $this->_openItem($page);
            $result .= $this->_renderItem($page);
            $lastLevel = $pageLevel;
        }
        $result .= $this->_closeItem();
        return $result;
    }

    /**
     * Renders contents of the item (what's inside the item)
     *
     * @param mixed $page
     * @return string
     */
    protected function _renderItem($page)
    {
        return sprintf('<a href="%s">%s</a>', $page['url'], $page['name']);
    }

    /**
     * Accessor for the level attribute
     *
     * Can be overridden if you use objects instead of associative arrays
     *
     * @param mixed $page
     * @return int
     */
    protected function _getLevel($page)
    {
        return $page['level'];
    }

    /**
     * Opens new level of list
     *
     * Can be overridden if you want for example OLs
     *
     * @param int $currentLevel
     * @return string
     */
    protected function _openList($currentLevel)
    {
        return sprintf('<ul class="%s">', 'level-' . $currentLevel);
    }

    /**
     * Opens new item of list
     *
     * Override if you need more complex markup of items
     *
     * @param mixed $page
     * @return string
     */
    protected function _openItem($page)
    {
        return sprintf('<li class="%s">', 'item-' . $page['id']);
    }

    /**
     * Closes current level of the list
     *
     * @param int $currentLevel
     * @return string
     */
    protected function _closeList($currentLevel)
    {
        return '</ul>';
    }

    /**
     * Closes the previous item
     *
     * The actual item being closed cannot be accessed due to
     * the way the algorithm works
     *
     * @return string
     */
    protected function _closeItem()
    {
        return '</li>';
    }

    /**
     * @return int
     */
    protected function _getIntialLevel()
    {
        return 1;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...