我正在尝试将小型CMS附加到我正在创建的网站上。但是我遇到了一个小问题。 CMS使用PHP函数插入菜单,这些PHP函数创建HTML。我想使用的特定函数(treemenu)创建了一个嵌套的ul li,然后可以用于下拉菜单。但是,嵌套的ul li的结构如下:
<li>Projects (Menu Level 1)</li>
<ul>
<li>Project 1 (Menu Level 2)</li>
<li>Project 2 (Menu Level 2)</li>
<li>Project 3 (Menu Level 2)</li>
</ul>
<li>News (Menu Level 1)</li>
<li>Contact (Menu Level 1)</li>
在CSS中创建下拉菜单时,我相信菜单级别1 li应该像这样包装它的子项:
<li>Projects (Menu Level 1)
<ul>
<li>Project 1 (Menu Level 2)</li>
<li>Project 2 (Menu Level 2)</li>
<li>Project 3 (Menu Level 2)</li>
</ul>
</li>
<li>News (Menu Level 1)</li>
<li>Contact (Menu Level 1)</li>
我之前从未使用PHP,因此不知道如何更改函数以完成上述操作。我希望这将是一个简单的改变。下面是输出第一个示例结构的PHP函数:
function treemenu($generat=0) {
global $pagenum, $menu, $selected, $extension, $set;
$count=0;
$out="\n";
$intend=0;
while($menu[$count][0] != "") {
if(strpos($menu[$count][3],"#") === false) {
if($menu[$count][2]=="0" && $intend==2) {
$intend--;
$out.="</ul>\n";
}
if($menu[$count][1]=="0" && $intend==1) {
$intend--;
$out.="</ul>\n";
}
if($menu[$count][1]!="0" && $intend<1) {
$intend=1;
$out.="<ul>\n";
}
if($menu[$count][2]!="0" && $intend<2) {
$intend=2;
$out.="<ul>\n";
}
$out.="<li class=\"LNE_menu\"><a ";
if($menu[$count][4]==$selected['name'])
$out.= 'class="selected" ';
if(strpos($menu[$count][3],"*"))
$out.='href="'.str_replace("*", "",$menu[$count][3]).'">';
elseif($generat)
$out.='href="'.$menu[$count][3].".".$set['extension'].'">';
else
$out.='href="'.$set['indexfile'].'?page='.$menu[$count][3].'">';
$out.=$menu[$count][4]."</a></li>\n";
}
$count++;
}
return $out;
}
有没有人可能指出我正确的方向,如何使第1级菜单项的结束li标签立即包装ul,如第二个例子?
答案 0 :(得分:8)
这将是使用递归的一个很好的例子。数组(其中包含子数组)定义每个级别,并且函数循环,每当找到要处理的新数组时调用它自己。只要该函数适当地清理(关闭</li> & </ol>
),它就很大程度上是自动的。
<?php
// I know which function I'd rather write....
$tree = array('Projects (Menu Level 1)',
array('Project 1 (Menu Level 2)',
'Project 2 (Menu Level 2)',
'Project 3 (Menu Level 2)'),
'News (Menu Level 1)',
'Contact (Menu Level 1)');
// now quake beneath the power of this fully operational recursive function!
function olLiTree($tree)
{
echo '<ul>';
foreach($tree as $item) {
if (is_array($item)) {
olLiTree($item);
} else {
echo '<li>', $item, '</li>';
}
}
echo '</ul>';
}
olLiTree($tree); // kick off from the top level
答案 1 :(得分:3)
看起来Topbit已经打败了我,但我的略有的不同之处在于它不直接将值回显到输出流,而是将其保存在您可能{{{ 1}}在您方便的时候:
echo
修改强>
感谢Gumbo和Topbit,现在我已经在我的机器上安装了PHP,我已经测试过它并且工作正常。
答案 2 :(得分:3)
您只需要一个简单的功能。
function unorderedList($val)
{
if (is_array($val)) {
return '<ul><li>' .
implode('</li><li>',
array_map('unorderedList', $val)) .
'</li></ul>';
} else {
return $val;
}
}
测试代码:
$menu = array('Projects (Menu Level 1)',
array('Project 1 (Menu Level 2)',
'Project 2 (Menu Level 2)',
'Project 3 (Menu Level 2)'),
'News (Menu Level 1)',
'Contact (Menu Level 1)');
echo unorderedList($menu);
答案 3 :(得分:0)
我认为这会输出正确的HTML结构。
function GenerateMenu($arr)
{
foreach($arr as $val) {
if (next($arr)) { $nextitem = current($arr); }
if (is_array($val)) {
$output .= "\n<ul>\n" . GenerateMenu($val, $output) . "</ul>\n</li>\n\n";
}
elseif (is_array($nextitem)) { $output .= "<li>" . $val; }
else { $output .= "<li>" . $val . "</li>\n"; }
}
return $output;
}
$html = GenerateMenu($menu);
echo("<ul>\n" . $html . '</ul>');
与上述测试代码相同:
$menu = array('Projects (Menu Level 1)',
array('Project 1 (Menu Level 2)',
'Project 2 (Menu Level 2)',
'Project 3 (Menu Level 2)'),
'News (Menu Level 1)',
'Contact (Menu Level 1)');
答案 4 :(得分:0)
我使用PHP DOMDocument类编写了这个。它将使用一个简单易用的循环创建您的列表,与列表一样长。如果您希望它有条理,只需先向数据库询问按标题(或其他)排序的列表。 它假设您的查询对象数据包含在$ menu_categories中,并且它至少具有 - &gt; id - &gt; parent_id&amp;的属性。 - &gt;标题(根据您的需求而变化)
$dom = new DOMDocument();
$dom->validateOnParse = true;
$dom->loadHTML("<html>");
$root = $dom->createElement('ul');
$root->setAttribute('class', 'menu');
$dom->appendChild($root);
foreach($menu_categories as $count => $category){
$pid = $category->parent_id;
$parent = $dom->getElementById('simple-li-'.$pid);
if($parent != null){
$ul = $dom->getElementById('simple-ul-'.$pid);
if($ul == null){
$ul = $dom->createElement('ul');
$ul->setAttribute('id', 'simple-ul-'.$pid);
$parent->appendChild($ul);
}
$target = $ul;
}else{
$target = $root;
}
$li = $dom->createElement('li', $category->title);
$li->setAttribute('id', 'simple-li-'.$category->id);
$target->appendChild($li);
}
echo $dom->saveHTML($root);
return;
这是评论版......
/**
* This is pure and simple PHP!
* @author Jamin Szczesny - Mar 2014
* Assuming you have a returned query list of related rows named...
* $menu_categories (the list can be in any order)
* and it has valid attributes of..
* ->id (category id)
* ->title (category title\name)
* ->parent_id (categories parent)
*
*/
$dom = new DOMDocument();//create a document
$dom->validateOnParse = true;//this is a must
$dom->loadHTML("<html>");//you must load some valid html
//add a root list to the dom
$root = $dom->createElement('ul');
$root->setAttribute('class', 'menu');
$dom->appendChild($root);
//loop through all of your category rows
foreach($menu_categories as $count => $category){
$pid = $category->parent_id;
$parent = $dom->getElementById('simple-li-'.$pid);
//see if we found a parent
if($parent != null){ //parent found...
//look for a ul within the parent
$ul = $dom->getElementById('simple-ul-'.$pid);
//check to see if that ul exists
if($ul == null){//ul not created yet so create one
$ul = $dom->createElement('ul');
$ul->setAttribute('id', 'simple-ul-'.$pid);
$parent->appendChild($ul);
}
$target = $ul;
}else{ //no parent found...
$target = $root;
}
//create this list item
$li = $dom->createElement('li', $category->title);
$li->setAttribute('id', 'simple-li-'.$category->id);
$target->appendChild($li);
}
//output only the html from our list
echo $dom->saveHTML($root);
return;