Jump to content

Menu issue


webhoes
 Share

Recommended Posts

Hello, the following code is for rendering my menu. The templates articles (child is article) and blogs (child is blog) have no childeren (yet). For some reason every menu item gets a "dropdown" class. Also the pages that should not have them. What am I doing wrong here?

<ul class='nav navbar-nav' role='navigation'><?php
    echo "<li><a href='/'>Home</a></li>";
        // top navigation consists of homepage and its visible children
        foreach($homepage->children as $item) {

            if($item->id == $page->rootParent->id) {
               echo "<li class='"; if($item->children->find('template!=blog|article')) echo "dropdown"; echo " active' aria-current='true'>";
            } else {
                echo "<li class='"; if($item->children->find('template!=blog|article')) echo "dropdown"; echo "'>";
            }

            echo "<a href='$item->url'"; if($item->children->find('template!=blog|article')) echo "class='dropdown-toggle' data-toggle='dropdown' role= 'button' aria-haspopup='true' aria-expanded='false'"; echo ">" . $item->title . "<span class='caret'></span></a>";

            if ($item->children) {
                echo "<ul class='dropdown-menu sub-menu'>";
                foreach ($item->children as $child) {
                    echo "<li><a href='" . $child->url . "'><i class='fa fa-angle-double-right' aria-hidden='true'></i>" . $child->title . "</a></li>";

                }
                echo "</ul>";
            }
            echo "</li>";
            $item->children = Null;
        }

        // output an "Edit" link if this page happens to be editable by the current user
        if($page->editable()) echo "<li class='edit'><a href='$page->editUrl'>" . __('Edit') . "</a></li>";
        ?>



    <!-- language switcher / navigation -->
    <?php
        foreach($languages as $language) {
            if(!$page->viewable($language)) continue; // is page viewable in this language?
            if($language->id == $user->language->id) {
                echo "<li class='active'>";
            } else {
                echo "<li>";
            }
            $url = $page->localUrl($language);
            $hreflang = $homepage->getLanguageValue($language, 'name');
            echo "<a hreflang='$hreflang' href='$url'>$language->title</a></li>";
        }
        ?>


</ul>
Link to comment
Share on other sites

Thanks @bernhard, that did not work as expected.

I ended up using this multiple times.

if($item->template->name == 'basic-page')

This works as expected, but the only downside that a basic-page has to be the parent. On this site that will do just fine.

It is rather inefficient, but this is a Multi language site so the menu title have to come from the pages.

  • Like 1
Link to comment
Share on other sites

1 hour ago, webhoes said:

Getting a flexible menu in a loop remains a tricky thing.

sometimes it can be a little tricky, that's true. but usually it is not.

do you know the rendernav function of the default site profile?

/** 
 * Given a group of pages, render a <ul> navigation
 *
 * This is here to demonstrate an example of a shared function and usage is completely optional.
 *
 * @param array|PageArray $items
 * @param int $maxDepth How many levels of navigation below current should it go?
 * @param string $fieldNames Any extra field names to display (separate multiple fields with a space)
 * @param string $class CSS class name for containing <ul>
 * @return string
 *
 */
function renderNav($items, $maxDepth = 0, $fieldNames = '', $class = 'nav') {

    // if we were given a single Page rather than a group of them, we'll pretend they
    // gave us a group of them (a group/array of 1)
    if($items instanceof Page) $items = array($items); 

    // $out is where we store the markup we are creating in this function
    $out = '';

    // cycle through all the items
    foreach($items as $item) {

        // markup for the list item...
        // if current item is the same as the page being viewed, add a "current" class to it
        $out .= $item->id == wire('page')->id ? "<li class='uk-active'>" : "<li>";

        // markup for the link
        $out .= "<a href='$item->url'>$item->title</a>";

        // if there are extra field names specified, render markup for each one in a <div>
        // having a class name the same as the field name
        if($fieldNames) foreach(explode(' ', $fieldNames) as $fieldName) {
            $value = $item->get($fieldName); 
            if($value) $out .= " <div class='$fieldName'>$value</div>";
        }

        // if the item has children and we're allowed to output tree navigation (maxDepth)
        // then call this same function again for the item's children 
        if($item->hasChildren() && $maxDepth) {
            if($class == 'nav') $class = 'nav nav-tree';
            $out .= renderNav($item->children, $maxDepth-1, $fieldNames, $class); 
        }

        // close the list item
        $out .= "</li>";
    }

    // if output was generated above, wrap it in a <ul>
    if($out) $out = "<ul class='$class'>$out</ul>";

    // return the markup we generated above
    return $out; 
}

another hint that may help: sometimes it is a lot easier to use the has() method to check wheter to append an active-class or not.

for example:

// create a pagearray that has all the parents of the current page + the page itself, but not the homepage (id=1)
$active = $page->parents('id>1')->append($page);

// loop all items
foreach($menuitems as $item) {
  // set menuitemclass active if the current item is part of the "$active" pagearray
  $cls = $active->has($item) ? 'active' : '';
  
  // echo the item
  echo "<li class='$cls'><a href='{$item->url}'>{$item->title}</a></li>";
}

...would make the code much more readable than a lot of if-statements. also recursive functions help a lot to make the code cleaner.

:)

  • Like 1
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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