Jump to content

Recommended Posts

Posted (edited)

Hi,

I habe buildt a site with a recursive menu like mindplay.dk posted here: https://processwire.com/talk/index.php?app=forums&module=post&section=post&do=reply_post&f=2&t=110&qpid=28241

But now the script produces a double </li> element after the nested <ul>

Here is my code:

<ul>
    <?php

        // top navigation consists of homepage and its visible children
        $homepage = $pages->get('/');
        $children = $homepage->children();

        // make 'home' the first item in the navigation
        $children->prepend($homepage);

/**
 * Recursive traverse and visit every child in a sub-tree of Pages.
 *
 * @param Page $parent root Page from which to traverse
 * @param callable $enter function to call upon visiting a child Page
 * @param callable|null $exit function to call after visiting a child Page (and all of it's children)
 */
function visit(Page $parent, $enter, $exit=null)
{
    foreach ($parent->children() as $child) {
        call_user_func($enter, $child);
        
        if ($child->numChildren > 0) {
            visit($child, $enter, $exit);
        }
        
        if ($exit) {
            call_user_func($exit, $child);
        }
    }
}


visit(
    $pages->get('/')
    ,
    function(Page $page) {
        echo '<li><a class="men" href="' . $page->url . '">' . $page->title . '</a>';
        if ($page->numChildren > 0) {
            echo '<ul>';
        }
    }
    ,
    function(Page $page) {
        echo '</li>';
        if ($page->numChildren > 0) {
            echo '</ul>';
        }
    }
);
        // output an "Edit" link if this page happens to be editable by the current user
        if($page->editable()) {
            echo '<li><a class="men" href="'.$page->editURL.'">Edit</a></li>';
        }

        ?>

        <!-- öffne Mailformular -->
        <li><a class="men" href="mailto:info@malabu.de"><img src="<?php echo $config->urls->templates?>styles/brief.gif" width="25" height="15" alt="info@malabu.de" title="schreib mir">
        </a></li>
        
        <!-- search form
        <form class='search' action='<?php //echo $pages->get('template=search')->url; ?>' method='get'>
            <input type='text' name='q' placeholder='Search' value='' />
            <button type='submit' name='submit'>Search</button>
        </form>
        -->
    </ul>

And this I get:

<ul>
    <li><a class="men" href="/pw/aktuelles/">Aktuelles</a></li>
<li><a class="men" href="/pw/kindheit/">Das bin ich</a></li>
<li><a class="men" href="/pw/garten/">Gärten</a></li>
<li><a class="men" href="/pw/meine-heimat/">meine Heimat</a></li>
<li><a class="men" href="/pw/pflanzen/">Pflanzen</a></li>
<li><a class="men" href="/pw/rezepte/">Rezepte</a>
   <ul><li><a class="men" href="/pw/rezepte/kochen/">Kochen</a></li>
          <li><a class="men" href="/pw/rezepte/backen/">Backen</a></li>
          <li><a class="men" href="/pw/rezepte/desserts/">Desserts</a></li></li>
  </ul><li><a class="men" href="/pw/zuhause/">Zuhause</a></li>
<li><a class="men" href="/pw/impressum/">Impressum</a></li>
<li><a class="men" href="/pw/processwire/page/edit/?id=1041">Edit</a></li>
        <!-- öffne Mailformular -->
        <li><a class="men" href="mailto:info@malabu.de"><img src="/pw/site/templates/styles/brief.gif" width="25" height="15" alt="info@malabu.de" title="schreib mir">
        </a></li>
        
        <!-- search form
        <form class='search' action='' method='get'>
            <input type='text' name='q' placeholder='Search' value='' />
            <button type='submit' name='submit'>Search</button>
        </form>
        -->
    </ul>

Can anyone help me?

Thanks in advance

Günter

Edited by Macrura
transformed quote to code
  • 2 weeks later...
Posted

Hi!

Let me give you a hint: (I am about to leave the house now, so I wont set up a testthingy now, but just stumbled about the error  ^_^ )

One of your double </li>s is just misplaced - there is one </li> missing after the "Rezepte" item. If you recap your code and look what it does I think you will find the solution! Otherwise let me know and I can try to fix it the weekend.

Hope that helps!

lg

Steffen

  • Like 2
Posted

Hi biber,

I had some time to oversee the code again, finally.

I made two adjustments:

The first was to remove the "echo </li>" from the second function in the visit call and add a </li> to the end of the output of the first function. Thats what I was hinting at before.

The second was that I wrapped the nested lists inside another list-item <li> because of the HTML specifications for lists: http://www.w3.org/TR/html5/grouping-content.html#the-ul-element

For comparison the working visit call: (with additional <ul> tags around so this can stand for its own)

echo "<ul>";
visit(
    $pages->get('/')
    ,
    function(Page $page) {
        echo '<li><a class="men" href="' . $page->url . '">' . $page->title . '</a></li>';
        if ($page->numChildren > 0) {
            echo '<li><ul>';
        }
    }
    ,
    function(Page $page) {
        if ($page->numChildren > 0) {
            echo '</ul></li>';
        }
    }
);
echo "</ul>";

best wishes

Steffen

  • Like 2
Posted

Hi Steffen,

I'm sorry, but after a while of testing I found this:

Your code produces an extra <li> around the <ul> of the submenus. This prevents the appearance of the (hidden) submenus while hovering the main menu.

Maybe, I have to live with some a little bit incorrect, but working HTML.

Günter

Posted

Another option is to implement something basic. If you do not have too many levels, you can do it without going recursive:

<ul class="menu-ul">
    <? foreach ($children as $level1): ?>
        <li<? if ($level1->id == $page->id) echo ' class="active-item"' ?>>
            <a href="<? echo $level1->url ?>"><? echo $level1->title; ?></a>
            <? if ($level1->url != $homepage->url): ?>
                <? $children = $level1->children(); ?>
                <? if ($children->count() > 0): ?>

                    <ul>
                        <? foreach ($children as $level2): ?>
                            <li<? if ($level2->id == $page->id) echo ' class="active-item"' ?>>
                                <a href="<? echo $level2->url ?>"><? echo $level2->title; ?></a>
                                <? $children = $level2->children(); ?>
                                <? if ($children->count() > 0): ?>

                                    <ul>
                                        <? foreach ($children as $level3): ?>
                                            <li<? if ($level3->id == $page->id) echo ' class="active-item"' ?>>
                                                <a href="<? echo $level3->url ?>"><? echo $level3->title; ?></a>
                                            </li>
                                        <? endforeach; ?>
                                    </ul>

                                <? endif ?>
                            </li>
                        <? endforeach; ?>
                    </ul>

                <? endif ?>
            <? endif ?>
        </li>
    <? endforeach; ?>
</ul>
  • Like 1
Posted

Hi again,

I like mindplay.dk's code because it is simple and flexible, it covers any nested list without modification.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...