Jump to content

Mega Menu


anyway
 Share

Recommended Posts

Hi everybody,

I want to set up a mega menu. I have been experimenting for a couple of hours, but I am stuck. What would be the best approach for this?  Can someone guide me in the right direction please? Any hint will be greatly appreciated! This is the HTML I want to use:

<ul class="mega-menu">

    <li><a href="#">Home</a></li>
   
    
    <!-- slideout -->
    <li aria-haspopup="true">
    
        <a href="#">Menu Item</a>
        
        <div class="grid-container12">
            
            <div class="grid-column3">
            <h4>Headline</h4>
                <ul>
                    <li><a href="#">First element</a></li>
                    <li><a href="#">Second element</a></li>
                    <li><a href="#">Third element</a></li>
                </ul>
            </div>
            
            <div class="grid-column3">
            <h4>Headline</h4>
                <ul>
                    <li><a href="#">First element</a></li>
                    <li><a href="#">Second element</a></li>
                    <li><a href="#">Third element</a></li>
                </ul>
            </div>
            
            <div class="grid-column3">
            <h4>Headline</h4>
                <ul>
                    <li><a href="#">First element</a></li>
                    <li><a href="#">Second element</a></li>
                    <li><a href="#">Third element</a></li>
                </ul>
            </div>
            
            <div class="grid-column3">
            <h4>Headline</h4>
                <ul>
                    <li><a href="#">First element</a></li>
                    <li><a href="#">Second element</a></li>
                    <li><a href="#">Third element</a></li>
                </ul>
            </div>
            
        </div>
        
    </li>
    <!--/slideout -->
    

    <li><a href="#">Menu Item</a></li>

    <li><a href="#">Menu Item</a></li>
    
    <li><a href="#">Menu Item</a></li>

    <li><a href="#">Menu Item</a></li>

</ul>
Link to comment
Share on other sites

if you're asking about how to structure the code to output that markup, then i can say that if i had to do a mega menu, i would setup a page tree branch for the menu items and use fields and templates to create the nested structure you need;

either that or use options/page selects to specify the structure and then create a function to parse the pages into the megamenu

if you could post your current code that might help... it really comes down to where you're getting the pages from and where these headlines are coming from... are they the parent page of the menu item, or parent page of a page that you're pulling into the menu

Link to comment
Share on other sites

Hi Macrura,

thanks for your quick reply! My problem is not about the HTML/CSS, in which I am good enough. It's about the implementation with PHP and Processwire. Sorry that I have not communicated that clearly enough.

Link to comment
Share on other sites

right - ok cool.. i'm sure once you see how easy it is to build a mega menu with PW you'll be awestruck...

so initially to get it going, can you provide some details of the page structure, and whether you want to build a custom menu or build the menu off pages..

Link to comment
Share on other sites

The menu can use the normal tree, which is looking like that:

|--  Level 1  
+-- Level 1
|    |
|    +-- Level 2
|         |-- Level 3
|         |-- Level 3
|         |-- Level 3
|    
|    +-- Level 2
|    +-- Level 2
|    +-- Level 2
|    
|-- Level 1
|-- Level 1
|-- Level 1
|-- Level 1

All Level 2 items are empty pages and unclickable from somewhere. They are only for holding and ornanizing the 3rd level pages. The headlines inside the HTML are the titles of the level 2 pages and not clickable. Just plain text.

My main problem is that I have too little php knowledge yet. I'm coming from the Wordpress world and did the most things with plugins, so far. Stupid, I know, but I want to change that now. So I have studied this posting from you with great interest, but only understood half, unfortunately ;-)

https://processwire.com/talk/topic/2787-custom-menu-not-related-to-page-tree/

Link to comment
Share on other sites

here's a first try though untested as of yet...

worked on this a bit...

/**
 *  render markup menu for bootstrap nested navigation
 *
 * @param  PageArray  $pa     pages of the top level items
 * @param  Page  $root   root page optional, if you use other root than home page (id:1)
 * @param  string  $output for returned string collection
 * @param  integer $level  internally used to count levels
 * @return string          menu html string
 */
function renderChildrenOf($pa, $root = null, $output = '', $level = 0) {
    
    if(!$root) $root = wire("pages")->get(1);
    $output = '';
    
    $level++;
    foreach($pa as $child) {
        $has_children = count($child->children()) ? true : false;
        $opening = '';
        $closing = '';
        
        if($has_children && $child === $root) {
            $output .= "\n\t<li><a href='{$child->url}'>{$child->title}</a></li>\n";
        }
        
        if(!$has_children) {
            $output    .= "\t<li><a href='{$child->url}'>{$child->title}</a></li>\n";
        }
        
        if($has_children && $child !== $root) {
            if($level == 1) {
                $opening  = "\t<li aria-haspopup='true'>\n<a href='{$child->url}'>{$child->title}</a>\n<div class='grid-container12'>\n";
                $closing  = "</div>\n</li>\n";
            }
            if($level == 2) {
                $opening = "\n<div class=\"grid-column3\">\n<h4>{$child->title}</h4>\n<ul>\n";
                $closing = "</ul>\n</div>\n";
            }
        }
        
        $output .= $opening;
        
        // If this child is itself a parent and not the root page, then render its children in their own menu too...
        if($has_children && $child !== $root) {
            $output .= renderChildrenOf($child->children(), $root, $output, $level);
        }
        
        $output .= $closing;

    }
      
    return $output . "\n";
}

it's also easier in this case to specify the outer markup and let the function do the rest..

$root = $pages->get(1);
$pa = $root->children();
$pa->prepend($root);
echo '<ul class="mega-menu">';
echo renderChildrenOf($pa,$root);
echo '</ul>';

but probably you'll need to work on it because this really only works with that exact page tree structure..

  • Like 3
Link to comment
Share on other sites

Ah okay, I understand and have completed it. Thank you, Pauline! Now there is an output, but only the outer html:

<ul class="mega-menu"></ul>

The inner part ($output) is missing. What am I doing wrong?

Link to comment
Share on other sites

Thanks for the hint, diego! It is something like that, isn't it?

$root = $pages->get(1);
$pa = $root->children;
$pa = $pa->prepend($root);

echo renderChildrenOf($pa);

Now, the li's are there, but the hierarchy is wrong. I'm getting only "home" and 3rd-level items. I've tried around with ->parents and so on, without success, but it feels pretty close...

Link to comment
Share on other sites

yeah - sorry forgot to tell you how to echo it.. that should work in think, but you can also do this:

$root = $pages->get(1); 
$pa = $root->children();
echo renderChildrenOf($pa,$root);

didn't test that code so not totally sure it will work yet... will try and test later...

Link to comment
Share on other sites

No problem, I'm learning a lot with this process.

Few things are still mixed up a bit. So, the grid-container12 div is empty and the li's are not really inside the grid-column3 divs, or only in one of them...

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...