我有对象$pages
通过
foreach ($pages as $p):
echo str_repeat(' ', 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
但我需要所有的孩子才能进入父母李:http://pastebin.com/JteBPGqb
我花了半天时间没有任何想法?
答案 0 :(得分: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>';
答案 1 :(得分:0)
此实现应该允许更容易的自定义。
用法:
<?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;
}
}