Search code examples
phpmenudomdocumentsidebar

Create sidebar menu with subpages, from existing string using PHP


I want to create a sidebar menu. I have the complet website menu in a variable. Now I want to collect the subpages/parents of current page.

To my help I have class "ancestor" and "current".

Se my code below. I need help with Q1, Q2, Q3 and Q4. Please comment if it is to hard to understand and I will explain better.

<?php


// this is the menu for the complete site
$menu = '
<ul>
<li class="ancestor">page1
    <ul class="child">
    <li>page11</li>
    <li class="parent">page12
        <ul class="child">
        <li>page111</li>
        <li class="current">page112</li>
        <li>page113</li>
        <li>page114</li>
        </ul>
    </li>
    <li>page13</li>
    <li>page14</li>
    </ul>
</li>
<li>page2</li>
<li>page3</li>
<li>page4</li>
</ul>
';



// I guess that DOM document is the right metodh for the job?
$doc = new DOMDocument();
$doc->loadHTML($menu);


$doc->removeChild($doc->firstChild); // remove doctype
$doc->replaceChild($doc->firstChild->firstChild->firstChild, $doc->firstChild); // remove <html><body></body></html>



// START
if ('Q1: check to see if li with class "current" has subpages or parent pages. With other words, determine if there shall be a sidebar menu or not')
{

    if ('Q2: If there is a li with class "ancestor", then get all the children of this class')
    {

    }

    elseif ('Q3: if there is no li with class "ancestor", then get all the children of "current" instead')
    {

    }


    // Q4 remove the first ul



    $wanted_li_s = $doc->saveHTML();
    $sidebar = '<ul class="new-class">'.$wanted_li_s.'</ul>';
} // END if has subpages

else
{
$sidebar = ''; // if there are no subpages sidebar menu should return nothing
}


?>

In the example above I want $sidebar to be the same as:

<ul class="new-class">
<li>page11</li>
    <li class="parent">page12
        <ul class="child">
        <li>page111</li>
        <li class="parent">page112</li>
        <li>page113</li>
        <li>page114</li>
        </ul>
    </li>
    <li>page13</li>
    <li>page14</li>
</ul>

Solution

  • By this method you can create submenu's easy in almoast any CMS (without learning the CMS language). All you need to do is to get the HTML in a variable and figure out a way to detect subpages.

    Allso you need to include this http://simplehtmldom.sourceforge.net/ (think of it like jQuery for PHP, you will not regret)

    Here is a example for creating submenus for wordpress custom menus.

    include('simple_html_dom.php');
    
    $meny = wp_nav_menu( array(
    'fallback_cb' => '' ,
    'echo' => 0,
    'container' => false,
    'container' => '',
    'items_wrap' => '%3$s'
    ));
    
    
    $menu_string = str_get_html($meny);
    
    
    foreach($menu_string->find('li[class=current-menu-item]') as $foreach_current_menu_item) // for each current-menu-item (only one of this)
    {
    
    
    
    if (strpos($foreach_current_menu_item->parent()->class,'sub-menu') !== false) // if you are on a subpage
    {
        foreach($menu_string->find('li[class=current-menu-ancestor]') as $foreach_current_menu_item2) //
        {
        $sidebar_menu= $foreach_current_menu_item2;
        }
    }
    
    
    
    elseif (strpos($foreach_current_menu_item->last_child()->class,'sub-menu') !== false) // if you are on a head page WITH subpages
    {
    $sidebar_menu= $foreach_current_menu_item;
    }
    
    
    
    else // if you are on a head page WITHOUT subpages
    {
    $sidebar_menu = '';
    }
    
    
    }
    
    // echo the menu where ever you want in your page
    echo '<ul id="new-id-for-the-menu">'.sidebar_menu.'</ul>';
    

    To make it work for level 3 pages in the sidebar menu you can use:

    if (strpos($foreach_current_menu_item->parent()->class,'sub-menu') !== false) 
    {
        $i = 0;
        foreach($menu_string->find('li[class=current-menu-ancestor]') as $foreach_current_menu_ancestor) 
        {
            if ($i == 0)
            {
            $sidomeny = $foreach_current_menu_ancestor;
            }
            $i++;
        }
    }