Search code examples
javascriptphpnavigationconcrete5concrete5-8.x

Displaying custom attribute in (autonav) template Concrete5


I want to display 2 custom attributes in the navigation. So I created the attribute nav_item_class and beschrijving.

The attribute nav_item_class displays the page icon and works correctly. The attribute beschrijving (description) is the same on all navigation items. It should show the different attribute of the different pages instead of the last attribute added at all the navigation items.


<?php View::getInstance()->requireAsset('javascript', 'jquery');

$navItems = $controller->getNavItems();

foreach ($navItems as $ni) {
    $classes = array();


    if ($ni->isCurrent) {
        //class for the page currently being viewed
        $classes[] = 'nav-selected';
    }

    if ($ni->inPath) {
        //class for parent items of the page currently being viewed
        $classes[] = 'nav-path-selected';
    }


    if ($ni->hasSubmenu) {
        //class for items that have dropdown sub-menus
        $classes[] = 'dropdown';
    }

    if (!empty($ni->attrClass)) {
        //class that can be set by end-user via the 'nav_item_class' custom page attribute
        $classes[] = $ni->attrClass;
    }

    if ($ni->cObj->getAttribute('beschrijving')) {
        //custom beschrijving
        $beschrijving = $ni->cObj->getAttribute('beschrijving');
    }

    //Put all classes together into one space-separated string
    $ni->classes = implode(" ", $classes);
}

//*** Step 2 of 2: Output menu HTML ***/

echo '<ul class="nav navbar-nav navbar-right">'; //opens the top-level menu

foreach ($navItems as $ni) {

    echo '<li class="' . $ni->classes . '">'; //opens a nav item

    if ($ni->isEnabled) {
        $ni->hasSubmenu;
    }

    if ($ni->hasSubmenu) {
        echo '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">' . $ni->name . '</a>';
    } else {
        echo '<a href="' . $ni->url . '" target="' . $ni->target . '" class="' . $ni->classes . '"><span class="navwrap"><span class="navimg"><i class="material-icons">' . $ni->attrClass . '</i></span><span class="navtit">' . $ni->name . '</span><span class="navtxt">' . $beschrijving . '</span></span></a>';
    }

    if ($ni->hasSubmenu) {
        echo '<ul class="dropdown-menu">'; //opens a dropdown sub-menu
    } else {
        echo '</li>'; //closes a nav item
        echo str_repeat('</ul></li>', $ni->subDepth); //closes dropdown sub-menu(s) and their top-level nav item(s)
    }
}

echo '</ul>'; //closes the top-level menu

What I want:

(Home icon) - Home, Home description

(Info icon) - Info, Info description

(Contact icon) - Info, Contact Description

etc.

What is happening:

(Home icon) - Home, Contact description

(Info icon) - Info, Contact Description

(Contact icon) - Contact, Contact Description


Solution

  • What you are doing here is, you assign a variable while looping the navItems. Then you go further and loop the navItems again. In this loop, the variable has the value of the last navItem. What you need to do is, assign the attribute value to the navItem on the first loop. The navItem is a simple php StdClass object and can assign new variables, which you can retrieve later.

    Somthing like following in the first loop:

    foreach ($navItems as $ni) {
        $classes = array();
    
    
        if ($ni->isCurrent) {
            //class for the page currently being viewed
            $classes[] = 'nav-selected';
        }
    
        if ($ni->inPath) {
            //class for parent items of the page currently being viewed
            $classes[] = 'nav-path-selected';
        }
    
    
        if ($ni->hasSubmenu) {
            //class for items that have dropdown sub-menus
            $classes[] = 'dropdown';
        }
    
        if (!empty($ni->attrClass)) {
            //class that can be set by end-user via the 'nav_item_class' custom page attribute
            $classes[] = $ni->attrClass;
        }
    
        if ($ni->cObj->getAttribute('beschrijving')) {
            //custom beschrijving
            $ni->beschrijving = $ni->cObj->getAttribute('beschrijving');
        } else {
            $ni->beschrijving = '';
        }
    
        //Put all classes together into one space-separated string
        $ni->classes = implode(" ", $classes);
    }
    

    And then in the 2nd loop:

    foreach ($navItems as $ni) {
    
        echo '<li class="' . $ni->classes . '">'; //opens a nav item
    
        if ($ni->isEnabled) {
            $ni->hasSubmenu;
        }
    
        if ($ni->hasSubmenu) {
            echo '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">' . $ni->name . '</a>';
        } else {
            echo '<a href="' . $ni->url . '" target="' . $ni->target . '" class="' . $ni->classes . '"><span class="navwrap"><span class="navimg"><i class="material-icons">' . $ni->attrClass . '</i></span><span class="navtit">' . $ni->name . '</span><span class="navtxt">' . $ni->beschrijving . '</span></span></a>';
        }
    
        if ($ni->hasSubmenu) {
            echo '<ul class="dropdown-menu">'; //opens a dropdown sub-menu
        } else {
            echo '</li>'; //closes a nav item
            echo str_repeat('</ul></li>', $ni->subDepth); //closes dropdown sub-menu(s) and their top-level nav item(s)
        }
    }