Php Sub Category loop html - php

I get the data from the database. but I can not write between li,ul html tags.There is a problem in the loop. How do I write between li ul categories and subcategories. I have this pdo mysql category function.
<?php
...
function kategoriVer($ustid=0){
$result = DB::get('SELECT * FROM urunler_kategori WHERE kategori_k='.$ustid.'');
echo '<ul class="drop-down">';
foreach($result as $kategori){
echo '<li class="drop">
'.$kategori->baslik_k.'';
kategoriVer($kategori->id_k);
}
echo '</li></ul>';
}
kategoriVer();
?>
output html:
<ul class="sub-menu">
<li class="menuparent">
Çadırlar
<ul class="sub-menu">
<li class="menuparent">Hi-Tech Çadırlar<ul class="sub-menu"></li></ul>
<li class="menuparent">Çelik Konstrüksiyon<ul class="sub-menu"></li></ul>
<li class="menuparent">Tribün Çadırlar<ul class="sub-menu"></li></ul>
<li class="menuparent">Yürüyüş Yolları<ul class="sub-menu"></li></ul>
</li>
</ul>
<li class="menuparent">Şemsiyeler<ul class="sub-menu"></li></ul>
<li class="menuparent">İklimlendirme<ul class="sub-menu"></li></ul>
</li>
</ul>
i want this output:
<ul class="sub-menu">
<li class="menuparent">
Headers
<ul class="sub-menu">
<li>Standard</li>
<li>No Topbar</li>
<li>Social Icons</li>
<li>Minimal</li>
<li>Classic</li>
</ul>
</li>
</ul>

Related

PHP DOM How to get items and sub-items from UL

I'm trying to get all items and sub-items with anchor tag form the following menu:
<nav class="header-nav" id="headerLara">
<div class="menu-hauptmenu-container">
<ul id="head_nav_ul" class="menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-4">
<a>First Menu</a>
<ul class="sub-menu">
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-14002">
F menu 1
</li>
<li class="menu-item menu-item-type-post_type menu-item-object-post menu-item-12718">
F menu 2
</li>
</ul>
</li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-6">
<a>Second Menu</a>
<ul class="sub-menu">
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-1257">
S menu 1
</li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-5420">
S menu 2
</li>
</ul>
</li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-12821">
Third Menu
</li>
</ul>
</div>
</nav>
Now i want outpul like :
<nav class="header-nav" id="headerLara">
<div class="menu-hauptmenu-container">
<ul>
<li>
<a class="has-child">First Menu</a>
<ul>
<li>
F menu 1
</li>
<li>
F menu 2
</li>
</ul>
</li>
<li>
<a class="has-child">Second Menu</a>
<ul>
<li>
S menu 1
</li>
<li>
S menu 2
</li>
</ul>
</li>
<li>
Third Menu
</li>
</ul>
</div>
</nav>
I've done some R&D and tried with following PHP code :
<?php
$doc = new DomDocument;
$doc->validateOnParse = true;
$doc->loadHtml(file_get_contents('http://example.com/blabla.php'));
$header = $doc->getElementById('headerLara');
$mainUls = $header->getElementsByTagName('ul');
foreach ($mainUls as $mainUl) {
echo '<ul>';
$mainLis = $mainUl->getElementsByTagName('li');
foreach ($mainLis as $mainLi) {
echo '<li>';
$mainAnc = $mainLi->getElementsByTagName('a');
$href = $mainAnc->item(0)->getAttribute('href');
echo '<a class="has-child" href="'.$href.'">'.$mainAnc->item(0)->nodeValue.'</a>';
$secUls = $mainLi->getElementsByTagName('ul');
if($secUls->length < 2){
foreach ($secUls as $secUl) {
echo '<ul>';
$secLis = $secUl->getElementsByTagName('li');
foreach ($secLis as $secLi) {
echo '<li>';
$secAnc = $mainLi->getElementsByTagName('a');
$shref = $secAnc->item(0)->getAttribute('href');
echo ''.$secAnc->item(0)->nodeValue.'';
echo '</li>';
}
echo '</ul>';
}
}
echo '</li>';
}
echo '</ul>';
}
?>
But this is not working for me as i want and return output like:
<ul>
<li>
<a class="has-child" href="">First Menu</a>
<ul>
<li>
First Menu
</li>
<li>
First Menu
</li>
</ul>
</li>
<li>
<a class="has-child" href="http://example.com/fm1">F menu 1</a>
</li>
<li>
<a class="has-child" href="http://example.com/fm2">F menu 2</a>
</li>
<li>
<a class="has-child" href="">Second Menu</a>
<ul>
<li>
Second Menu
</li>
<li>
Second Menu
</li>
</ul>
</li>
<li>
<a class="has-child" href="http://example.com/sm1">S menu 1</a>
</li>
<li>
<a class="has-child" href="http://example.com/sm2">S menu 2</a>
</li>
</ul>
I've checked many links which seems similar to my problem but found nothing helpful.
How can i get the proper output, Thanks in advance.
There are a few minor errors (picking up from the wrong node) but there are two main problems.
The first is getElementsByTagName() selects all child elements with that tag name, this isn't limited to immediate child nodes, so each time it would be more tags than you are expecting. In this code it uses XPath as DOMDocument doesn't have a convenient way of doing a just immediate child nodes called, so XPath just uses the context node as your start point and something like a to say only <a> tags who are direct descendants of the context node.
The other (main thing) is that you are building the output using echo statements. Which may work, but is also prone to typos, invalid structure etc. This code uses the DOM API calls to create the document.
$doc = new DomDocument;
$doc->validateOnParse = true;
$doc->loadHtml($html);
$xp = new DOMXPath($doc);
$header = $doc->getElementById('headerLara');
$mainUls = $xp->query('div/ul', $header);
foreach ($mainUls as $mainUl) {
$mainULE = $doc->createElement("ul");
$mainLis = $xp->query('li', $mainUl);
foreach ($mainLis as $mainLi) {
$li = $doc->createElement("li");
$mainAnc = $xp->query('a', $mainLi)[0];
$href = $mainAnc->getAttribute('href');
$a = $doc->createElement("a", htmlspecialchars($mainAnc->nodeValue));
$href = $mainAnc->getAttribute('href');
if ( !empty($href) ) {
$a->setAttribute("href", $href);
}
$li->appendChild($a);
$secUls = $xp->query('ul', $mainLi);
if($secUls->length < 2){
foreach ($secUls as $secUl) {
$a->setAttribute("class", "has-child");
$secULE = $doc->createElement("ul");
$secLis = $xp->query('li', $secUl);
foreach ($secLis as $secLi) {
$secLIE = $doc->createElement("li");
$secAnc = $xp->query('a', $secLi);
$shref = $secAnc[0]->getAttribute('href');
$secA = $doc->createElement("a", htmlspecialchars($secAnc[0]->nodeValue));
$secA->setAttribute("href", $shref);
$secLIE->appendChild($secA);
$secULE->appendChild($secLIE);
}
$li->appendChild($secULE);
}
}
$mainULE->appendChild($li);
}
echo PHP_EOL.PHP_EOL.">>>>".$doc->saveHTML($mainULE);
// Next line replaces existing HTML
//$mainUl->parentNode->replaceChild($mainULE,$mainUl);
}

Scrape HTML list structure with PHP

I want to scrape a html list structure, so I can save parent and child separately.
Here's the view source of html
<ul class="categories_list">
<li>Sports Nutrition
<ul class="categories_list">
<li>Protein
<ul class="categories_list">
<li>Protein Powder
<ul class="categories_list">
<li>Whey Protein
<ul class="categories_list">
<li>Whey Protein Isolate</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul class="categories_list">
<li>Pre Workout Supplements</li>
</ul>
<ul class="categories_list">
<li>Creatine
<ul class="categories_list">
<li>Creatine Monohydrate</li>
</ul>
</li>
</ul>
<ul class="categories_list">
<li>Amino Acids
<ul class="categories_list">
<li>Essential Amino Acids
<ul class="categories_list">
<li>BCAA</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul class="categories_list">
<li>Joint Supplements
<ul class="categories_list">
<li>Curcumin
<ul class="categories_list">
<li>Curcumin Phytosome</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul class="categories_list">
<li>Energy & Endurance
<ul class="categories_list">
<li>Stimulants</li>
</ul>
</li>
</ul>
</li>
</ul>
I am using simple HTML DOM for scraping. I am able to get all categories, but I cannot get them in proper the hierarchy.
I also tried the children approach, but that didn't work.
So I am looking for some help in my existing to make it working.
Here's my existing code:
$html= file_get_html($url);
foreach ($html->find('ul.categories_list li') as $link) {
echo $link->plaintext.'<br>';
}
There is this script which tried to get all elements. This needs to be improved upon:
<?php
require_once("simple_html_dom.php");
$dom = file_get_html("source.php");
getCategory($dom);
print_r($categoryList);
function getCategory(simple_html_dom $dom){
global $categoryList;
foreach($dom->find('ul.categories_list li') as $ul){
//extract the a tag if found
$categoryName = $ul->find('a',0)->href;
$categoryLabel = $ul->find('a',0)->innertext;
$categoryList[] = array(
"categoryName" => $categoryName,
"categoryLabel" => $categoryLabel,
);
//remove a node
$ul->find('a',0)->outertext = '';
$string = $ul->innertext;
if(trim($string) == ''){
continue;
}else{
// die($string);
$dom2 = str_get_html($string);
getCategory($dom2);
}
}
}
It basically does recursion filling the $categoryList on each call.

Dynamic nested menu has Improper placed <ul> tags and <li>not wrapping around submenu items

I'm trying to create a dynamic nested menu and am running into some issues that I don't know how to handle. After each top menu item I am getting a empty UL tag set.
Also when there is a drop down menu the LI tag set is not properly wrapping the UL tags.
here is the code I am trying to modify....thanks!
$sql = "SELECT menuID, menuTitle, menuURL, menuParentID, menuOrderID FROM menu ORDER BY menuParentID, menuOrderID ASC";
$items = mysql_query($sql);
while ($obj = mysql_fetch_object($items)) {
if ($obj->menuParentID == 0) {
$parent_menu[$obj->menuID]['menuTitle'] = $obj->menuTitle;
$parent_menu[$obj->menuID]['link'] = $obj->menuURL;
} else {
$sub_menu[$obj->menuID]['parent'] = $obj->menuParentID;
$sub_menu[$obj->menuID]['menuTitle'] = $obj->menuTitle;
$sub_menu[$obj->menuID]['link'] = $obj->menuURL;
if (!isset($parent_menu[$obj->menuParentID]['count'])) {
$parent_menu[$obj->menuParentID]['count'] = 0;
}
$parent_menu[$obj->menuParentID]['count']++;
}
}
mysql_free_result($items);
function dyn_menu_folded($parent_array, $sub_array, $qs_val = "menu", $main_id = "nav", $sub_id = "dropdown-menu", $dd_style = "dropdown") {
$menu = "<ul class=\"".$main_id."\">\n";
foreach ($parent_array as $pkey => $pval) {
if (!empty($pval['count'])) {
$menu .= " <li class=\"".$dd_style."\">".$pval['menuTitle']."<b class=\"caret\"></b></li>\n";
} else {
$menu .= " <li>".$pval['menuTitle']."</li>\n";
}
//if (!empty($_REQUEST[$qs_val])) {
$menu .= "<ul class=\"".$sub_id."\">\n";
foreach ($sub_array as $sval) {
if ($pkey == $sval['parent']) { //
$menu .= "<li>".$sval['menuTitle']."</li>\n";
}
}
$menu .= "</ul>\n";
//}
}
$menu .= "</ul>\n";
return $menu;
}
?>
<?php
echo dyn_menu_folded($parent_menu, $sub_menu, "menu", "nav", "dropdown-menu");
?>
//this is a sample of the result.
<ul class="nav">
<li >ITEM A</li>
<ul class="dropdown-menu"></ul> //IMPROPER UL TAGS
<li >ITEM B</li>
<ul class="dropdown-menu"></ul>
<li >ITEM C</li>
<ul class="dropdown-menu"></ul>
<li >ITEM D</li>
<ul class="dropdown-menu"></ul>
<li class="dropdown">ITEM E<b class="caret"></b>
</li> //LI TAG NOT WRAPPING AROUND UL TAG
<ul class="dropdown-menu">
<li >ITEM E1</li>
<li >ITEM E2</li>
<li >ITEM E3</li>
<li >ITEM E4</li>
<li >ITEM E5</li>
</ul>
<li class="dropdown">ITEM F<b class="caret"></b>
</li>
<ul class="dropdown-menu">
<li >ITEM F1</li>
<li >ITEM F2</li>
<li >ITEM F3</li>
<li >ITEM F4</li>
<li >ITEM F5</li>
<li >ITEM F6</li>
</ul>
<li >ITEM G</li>
<ul class="dropdown-menu"></ul>
<li >ITEM H</li>
<ul class="dropdown-menu"></ul>
<li >ITEM I</li>
<ul class="dropdown-menu"></ul>
<li >ITEM J</li>
<ul class="dropdown-menu"></ul>
</ul>
//This is how it should look.
<ul class="nav">
<li >ITEM A</li>
<li >ITEM B</li>
<li >ITEM C</li>
<li >ITEM D</li>
<li class="dropdown">ITEM E<b class="caret"></b>
<ul class="dropdown-menu">
<li >ITEM E1</li>
<li >ITEM E2</li>
<li >ITEM E3</li>
<li >ITEM E4</li>
<li >ITEM E5</li>
</ul>
</li>
<li class="dropdown">ITEM F<b class="caret"></b>
<ul class="dropdown-menu">
<li >ITEM F1</li>
<li >ITEM F2</li>
<li >ITEM F3</li>
<li >ITEM F4</li>
<li >ITEM F5</li>
<li >ITEM F6</li>
</ul>
</li>
<li >ITEM G</li>
<li >ITEM H</li>
<li >ITEM I</li>
<li >ITEM J</li>
</ul>
Without knowing for sure how $parent_menu and $sub_menu is structured, I can't say for sure if this will do the job, but give it a go anyway.
function create_menu($parent_array, $sub_array, $qs_val = "menu", $main_id = "nav", $sub_id = "dropdown-menu", $dd_style = "dropdown")
{
$menu = "<ul class=\"{$main_id}\">\n";
foreach ($parent_array as $pkey => $pval) {
if ( ! empty($pval['count'])) {
$menu .= "\t<li class=\"{$dd_style}\">{$pval['menuTitle']}<b class=\"caret\"></b>\n";
$menu .= "\t\t<ul class=\"{$sub_id}\">\n";
foreach ($sub_array as $sval) {
if ($pkey == $sval['parent']) {
$menu .= "\t\t\t<li>{$sval['menuTitle']}</li>\n";
}
}
$menu .= "</ul></li>\n";
} else {
$menu .= "\t<li>{$pval['menuTitle']}</li>\n";
}
}
return $menu . "</ul>\n";
}
If your still having issues, please post the var_dump() output of $parent_menu and $sub_menu.

Dynamic dropdown menu using php with twitter bootstrap

Thank you for reading... I have a 2 layer of navigation. which sort the content by good, bad and comment count. if user clicks on good it will bring another nav which is sort the content by time. such as today, last one week, last one month.
I can add class='active' using $_SERVER['PHP_SELF'] but twitter bootsrap dropdown menu does not have simple class='active' it is complicated. I am not able to come up with a solution. should I use for? foreach? I don't know. please see the html command in the code. this is my code.
<ul class="nav nav-tabs">
<li <?php if (basename($_SERVER['PHP_SELF']) == '/?Top'): ?> class="active"<?php endif; ?>>Top Content</li>
<li <?php if (basename($_SERVER['PHP_SELF']) == '/?Bad'): ?> class="active"<?php endif; ?>>Bad Content</li>
<li <?php if (basename($_SERVER['PHP_SELF']) == '/?Comments'): ?> class="active"<?php endif; ?>>Most Commented</li>
<!-- It's confusing me when It comes here... because as you see active option is not li tag. it's bunch of html code and also any url bellow can ben any of those up -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-time"></i> Today <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="URL=week" />Last 1 Week</a></li>
<li><a href="URL=month" />Last 1 Month </a></li>
<li><a href="URL=all" />All</a></li>
</ul>
</li>
</ul>
html commend: It's confusing me when It comes here... because as you see active li is not li it's bunch of html code and also also any url below can be any of those up
You can use the "active" class for the outter li (the one has class "dropdown") and another "active" class in your child dropdown.
This is an example
<ul class="nav nav-tabs">
<li class="">Home</li>
<li>Help</li>
<li class="dropdown active">
Dropdown <b class="caret"></b>
<ul class="dropdown-menu">
<li>Action</li>
<li class="active">Another action</li>
<li>Something else here</li>
<li class="divider"></li>
<li>Separated link</li>
</ul>
</li>
</ul>
A live demo in JSBin

Generating divs in php?

Say I have the following div:
<div id="nav">
<ul>
<li class="navButton">Home</li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Bodies</a></li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Pickguards</a></li>
<li class="navButton">Contact Us</li>
</ul>
</div>
I would want this to be repeated a certain number of times so the resulting html would look like:
<div id="nav">
<ul>
<li class="navButton">Home</li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Bodies</a></li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Pickguards</a></li>
<li class="navButton">Contact Us</li>
</ul>
</div> <div id="nav">
<ul>
<li class="navButton">Home</li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Bodies</a></li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Pickguards</a></li>
<li class="navButton">Contact Us</li>
</ul>
</div> <div id="nav">
<ul>
<li class="navButton">Home</li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Bodies</a></li>
<li class="navButton"><a href="http://www.freewebsitetemplates.com">Guitar
Pickguards</a></li>
<li class="navButton">Contact Us</li>
</ul>
</div>
If the number was 3. What php command is used to do this sort of thing? (I know I use a for loop, but I mean the code in between)
Essentially what I will eventually have is something like this:
for each product
div product
text from product file
close div product
Thanks
Just use the foreach or while like this:
foreach($array as $value){
?>
<div>
whatever <?php other php here ?>
</div>
<?php
}
<div class='nav'>
<ul>
<?php foreach ($products as $product): ?>
<li class='navbutton'><?php echo $product->text; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
if you have multiple different divs, make a foreach loop for that too, if you want same div to repeat 3 times, wrap it around a for loop
<?
for ($results as $value) {
echo '<div id="nav">';
echo ' <ul>';
echo ' <li class="navButton">Home</li>';
echo ' <li class="navButton">'.$value['name1'].'</li>';
echo ' <li class="navButton">'.$value['name2'].'</li>';
echo ' <li class="navButton">Contact Us</li>';
echo ' </ul>';
echo ' </div>';
}
?>

Categories