Reputation: 100
I have to create a menu from a list with possible sub-lists. From a simple I want to create a compatible bootstrap menu So from a code like this:
<ul>
<li>Link 1</li>
<li>Link 2
<ul>
<li>Sublink A</li>
<li>Sublink B</li>
</ul>
</li>
<li>Link 3
<ul>
<li>Sublink C</li>
</ul>
</li>
</ul>
I'll have to create this:
array(
[0] => array(
[id] => 1,
[nome] => 'Link 1',
[parent] => NULL,
),
[1] => array(
[id] => 2,
[nome] => 'Link 2',
[parent] => NULL,
),
[2] => array(
[id] => 3,
[nome] => 'Sublink A',
[parent] => 2
),
[3] => array(
[id] => 4,
[nome] => 'Sublink B',
[parent] => 2
),
[4] => array(
[id] => 5,
[nome] => 'Link 3',
[parent] => NULL
),
[5] => array(
[id] => 6,
[nome] => 'Sublink C',
[parent] => 3
)
)
And finally, get back this one:
<ul class="nav navbar-nav">
<li><a class="primary" href="link_1.html">Link 1</a></li>
<li class="dropdown">
<a href="#" class="primary dropdown-toggle" data-toggle="dropdown">Link 2</a>
<ul class="dropdown-menu">
<li><a href="sublink_a.html">Sublink A</a></li>
<li><a href="sublink_b.html">Sublink B</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="primary dropdown-toggle" data-toggle="dropdown">Link 3</a>
<ul class="dropdown-menu">
<li><a href="sublink_c.html">Sublink C</a></li>
</ul>
</li>
</ul>
Conditions are: if
I use this code, but it's only for a simple list, not nested lists.
<?php
$currentPage = "";
$contents = "<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>";
// remove width, height, style
$contents = preg_replace('/(width|height|style|target)="[^"]+"/i', "", $contents);
// remove spaces form li
$contents = str_replace(array('<li >',' <li >'),"<li>",$contents);
// remove ul/ol tag and tabs
$contents = str_replace(array('\t','<ul>','<ul >','</ul>','<ol>','<ol >','</ol>'),"",$contents);
$arrNavTopList = explode("\n",trim($contents));
echo "<h4>Array:</h4>\n";
print_r($arrNavTopList);
echo "<hr>\n<h4>List:</h4>\n";
$totNavTopList = count($arrNavTopList);
if($totNavTopList>0){
echo '<ul class="nav navbar-nav">'."\n";
$countNtL=1;
foreach($arrNavTopList as $pagename) {
$pagename = str_replace("\t","",$pagename);
preg_match_all("(<li>(.*?)</li>)", $pagename, $arrLinkList);
$linktopage = $arrLinkList[1][0];
if(
strtolower($linktopage)==strtolower(str_replace("_"," ",$currentPage)) ||
strtolower($linktopage)=="home" && !(strpos($currentPage,"^")===FALSE)
) {
$active=' class="active"';
} else {
$active='';
}
echo '<li'.$active.'>';
if (strstr($linktopage,"http") || strstr($linktopage,"target")) {
$linktopage = preg_replace('/(style|target)="[^"]+"/i', "", $linktopage);
$linktopage = str_replace('<a','<a rel="external nofollow" class="_blank"',$linktopage);
echo $linktopage;
} else {
if(strtolower($linktopage)=="home" || strtolower($linktopage)=="home page") {
echo '<a href="/">'.htmlentities($linktopage).'</a>';
} else {
echo '<a href="'.str_replace(" ","_",strtolower($linktopage)).'">'.htmlentities($linktopage).'</a>';
}
}
echo '</li>'."\n";
$countNtL++;
}
echo '</ul>'."\n";
}
?>
Upvotes: 0
Views: 3444
Reputation: 49054
<?php
/**
* Traverse an elements children and collect those nodes that
* have the tagname specified in $tagName. Non-recursive
*
* @param DOMElement $element
* @param string $tagName
* @return array
*/
//from: https://stackoverflow.com/a/3049677/1596547
function getImmediateChildrenByTagName(DOMElement $element, $tagName)
{
$result = array();
foreach($element->childNodes as $child)
{
if($child instanceof DOMElement && $child->tagName == $tagName)
{
$result[] = $child;
}
}
return $result;
}
$doc = new DOMDocument();
$doc->loadHTML("<ul>
<li>Link 1</li>
<li>Link 2
<ul>
<li>Sublink A</li>
<li>Sublink B</li>
</ul>
</li>
<li>Link 3
<ul>
<li>Sublink C</li>
</ul>
</li>
</ul>");
//from: https://stackoverflow.com/a/6953808/1596547
# remove <!DOCTYPE
$doc->removeChild($doc->firstChild);
# remove <html><body></body></html>
$doc->replaceChild($doc->firstChild->firstChild->firstChild, $doc->firstChild);
$elements = $doc->getElementsByTagName('ul');
$parentitems = getImmediateChildrenByTagName($elements->item(0),'li');
$elements->item(0)->setAttribute ('class' , 'nav navbar-nav');
foreach ($parentitems as $parentitem)
{
if($parentitem->childNodes->length > 1) {
$parentitem->setAttribute ('class' , 'dropdown' );
$link = $doc->createElement('a',$parentitem->childNodes->item(0)->nodeValue);
$link->setAttribute ('class' , 'primary dropdown-toggle' );
$link->setAttribute ('href' , '#');
$link->setAttribute ('data-toggle','dropdown');
//$parentitem->nodeValue = null;
$old = $parentitem->childNodes->item(0);
$parentitem->replaceChild($link,$old);
$parentitem->childNodes->item(1)->setAttribute ('class' , 'dropdown-menu' );
$submenuitems = getImmediateChildrenByTagName($parentitem->childNodes->item(1),'li');
foreach($submenuitems as $submenuitem)
{
$link = $doc->createElement('a',$submenuitem->nodeValue);
$link->setAttribute ('href' , $submenuitem->childNodes->item(0)->nodeValue.'.html');
$submenuitem->nodeValue = null;
$submenuitem->appendChild($link);
}
}
else
{
$link = $doc->createElement('a',$parentitem->nodeValue);
$link->setAttribute ('class' , 'primary' );
$link->setAttribute ('href' , $parentitem->childNodes->item(0)->nodeValue.'.html');
$parentitem->nodeValue = null;
$parentitem->appendChild($link);
}
}
echo $doc->saveHTML();
other answers used:
Upvotes: 0