【问题标题】:MPTT tree to menuMPTT 树到菜单
【发布时间】:2012-03-23 13:24:22
【问题描述】:

我有 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

但我需要所有孩子 ul li 都在父母 li 里面:http://pastebin.com/JteBPGqb

我用了半天,一无所获,有什么想法吗?

【问题讨论】:

    标签: php mysql html treeview mptt


    【解决方案1】:

    您应该等待数组的下一个子元素关闭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>';
    

    【讨论】:

      【解决方案2】:

      此实现应该允许更轻松的自定义。

      用法:

      <?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;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-11
        • 1970-01-01
        • 2012-09-02
        • 1970-01-01
        • 2012-03-16
        • 1970-01-01
        • 2012-09-04
        • 1970-01-01
        相关资源
        最近更新 更多