Jump to content

want to create a custom menu


mrkhan
 Share

Recommended Posts

Hello,

i want to create two custom menus on my website and want to have option to add some pages in one menu and some in second page.

i have created one template called top-menu this template is using repeater name "menu_pages" for page, so that i can add as many pages i want.

filed name in repeater is "menu_page"

after that i am calling that page in my template like that 

<ul class="sf-menu  ">
<li class="current active"><a href="<?=$config->urls->root;?>">Home</a></li>
<?php
$top_menu=$pages->get("/top-menu/");
foreach($top_menu->menu_pages as $menu_page) {
?>
<li class=""><a href="<?php echo $menu_page->url ;?>"><?php echo $menu_page->page-tile ;?></a></li>
<?php } ?>
</ul>

but i am getting output Home | 0 | 0 | 0

also i want to check if page have child pages then again sub menu will be created every time page have child page.

i can't figure out how to do that.

i saw few plugins but i want to write it myself.

Thanks

Link to comment
Share on other sites

Hi @mrkhan and welcome to the forums.

Not sure if it is the only issue, but the most obvious problem I see with your code is:

$menu_page->page-tile

You can't have dashes in field names, and I am also assuming it is the title of the page you are looking for. Have you tried:

$menu_page->title
Link to comment
Share on other sites

hi adrian,

thanks for reply but 

$menu_page->title

did solve my problem let me explain again.

i want to create custom menu page my self which i can control from admin so

1. i created a new template name top-menu

2. i created a repeater name menu_pages

3. in menu_pages repeater i add a field name menu_page which is page type

after 

1. i create a new page with top-menu template

2. and add 4 menu_pages repeater & select 4 pages.

after

1. i put following code in head.inc file

<?php include('top-menu.php') ?>

after i write this code in top-menu.php

<?php
$top_menu=$pages->get("/top-menu/");
foreach($top_menu->menu_pages as $menu_page) {
?>
<li class=""><a href="#"><?php echo $menu_page->tile ;?></a></li>
<?php } ?>

This is not showing page name.

as i write before i want to have option in admin panel to create my own custom menu and display on website.

Thanks

Link to comment
Share on other sites

Mrkhan...welcome to the forums and PW...

I am wondering why do you need repeaters for this? You only have for pages in them and you are not exactly 'repeating' anything...You can simply have a multiple page field added directly to your page (the one using the top-menu template) and select your menu pages directly rather than going through repeaters...OK, back to your question...

Whereas you are looping through your repeater (it returns an array), you still have one more array to loop through - your page field is a multiple page field. So you need to foreach it inside your repeater foreach...Also, you still have $menu_page->tile that Adrian pointed to...

Link to comment
Share on other sites

Hello kongondo,

thanks for kind reply.

i actually need repeater as don't know how many pages i will add in menu.

i also modify my code as bellow as you said i need one more loop 

<?php
$top_menu=$pages->get("/top-menu/");
foreach($top_menu->menu_pages as $menu_page) {
foreach($menu_page as $menu_item){
?>
<li class=""><a href="#"><?php echo $menu_item->tile ;?></a></li>
<?php }} ?>

but its also not working. its showing lot of | signs but no text.

thanks

Link to comment
Share on other sites

i actually need repeater as don't know how many pages i will add in menu.

I don't  understand this. It doesn't stop you from using a page field directly in your page rather than via a repeater...anyway...

I am not very good with the alternative PHP syntax you are using so not sure if your <li> is in the right foreach. Is this a development/local server you are testing this on? Turn on debug mode to true if you haven't already. OK, let's determine that $menu_page is actually an array. What do you get when you do the following?

foreach($top_menu->menu_pages as $menu_page) {
   echo gettype($menu_page);
   exit;
}
Link to comment
Share on other sites

Can you confirm if your page fields are for single or multiple pages? If multiple and if you have set up as shown in the screenshot below, then you need to nest yet another foreach! If you really want to continue using repeaters for this then you probably want to write a recursive function to output your menu. Is this your setup?

post-894-0-20530000-1418503511_thumb.png

If yes, you would need to loop through $menu_item as well...

  • Like 1
Link to comment
Share on other sites

my menu page is as bellow

http://postimg.org/image/md4wrrzv5/

can you plz write code for me how to loop  $menu_item as i did as this but it did't work

<?php
$top_menu=$pages->get("/top-menu/");
foreach($top_menu->menu_pages as $menu_page) {
foreach($menu_page as $menu_item){
?>
<li class=""><a href="#"><?php echo $menu_item->tile ;?></a></li>
<?php }} ?>

or simply if you can help me how to make a page in admin panel where i can add as many pages i want and these pages should display in menu.

Thanks

Link to comment
Share on other sites

Sure, I can and I have tested this and it works but let me show you how to do it without repeaters (it's just an unnecessary step in this case IMO)...assuming you want a single level menu.

This is for a single level menu

  1. Edit and change your page field (menu_page) to be a Multiple pages (PageArray)
  2. While still editing it, on the Input Tab, scroll down to Input field type * and select an appropriate input, maybe *AsmSelect. Save
  3. Add menu_page to your top-menu template
  4. Edit the page 'top-menu' and select your menu pages
  5. Output your menu using code similar to below (add code to top-menu.php)..or adjust it if adding to your head.inc (i.e use $pages->get to get the Top Menu page first)
foreach($page->menu_page as $item) echo '<li class=""><a href="#">'. $item->title . '</a></li>';

Screenshot

post-894-0-18473400-1418505285_thumb.png

  • Like 2
Link to comment
Share on other sites

Hello

thanks for quick response and so effort but still here user can add 4 menus, but i don't want to put limit to menu items for user thats why use repeater so that use can add as much he want without modifying the template.

how can i do that?

Link to comment
Share on other sites

You can add as many pages as you want. Try it. There is no limit. I was just using 4 as an example... :-). You can order them the way you want. Depending on how you setup the menu_page field under Input Tab -> Selectable Pages, you can limit the pages that are selectable as menu items.  By limit here I mean you could limit them to child pages of a particular parent, or pages using a particular template, etc (I don't mean a limit on numbers!)

Edited by kongondo
  • Like 1
Link to comment
Share on other sites

@mrkahn -

I've yet to see a way to represent nested pages in a multi-page select; it would be interesting if it were possible, but i think it would take some custom module.

I guess you could create dummy pages that trigger a new dropdown and then the first item after that is the dropdown parent and then the subsequent items are the children of the first item; then you would need another dummy page to end the subnav;

i think that would work, but it seems like a lot of work;

I build menus using pages, so this makes it easy to build menus, publish and unpublish menu items, and have as many levels as needed with no extra work. It also allows you to have a custom title for every menu item, set an icon if you want, or classes, or use javascript as the menu item...

here's an example site with 3 menus:

post-136-0-76962500-1418568845_thumb.png

  • Like 3
Link to comment
Share on other sites

@mrkhan,

If by child pages you are referring to the children of the pages you have selected in your menu_page page field, then the following (slightly verbose) code should do it. This will create a 2-level menu. For anything deeper use a recursive function - there's plenty right here in the forums. 

$out = '';
$out .= '<ul>';

foreach($page->menu_page as $item) {

    $out .= '<li class="top"><a href="#">'. $item->title . '</a>';

    if ($item->numChildren) {

          $out .='<ul>';
      
         foreach ($item->children as $child) {
           
                  $out .= '<li class="child"><a href="#">'. $child->title . '</a></li>';
         }

         $out .='</ul>';
    
    }//end if child items

    $out .='</li>';
}

$out .='</ul>';

echo $out;
  • Like 2
Link to comment
Share on other sites

yes i know about module MarkupSimpleNavigation?  but the only problem with that we can't choose which pages we want to display on menu.

also we can't have multiple menus in page like top menu , side menu, footer menu.

what i am trying to do is to create pages for top menu, side menu , footer menu and assign them to pages as i want.

i am new to PW and really loving it, its really simple.

i just want to get your help again, if you can please

now menu work perfect but i want to assign current page class "active current"

i mean any page i click on menu or submenu, main menu should be assigned class "active current"

Thanks

Link to comment
Share on other sites

The current page is always $page (you can assign something else to $page, but it's not a good idea). This means you can check if the page you are currently adding to the menu is the same as $page. Then you can modify the output accordingly. For example:

foreach($page->menu_page as $item) {
    $activeclass = ($item == $page) ? 'active current' : ''; //If this is the page we are viewing, add the classes. Otherwise use ''.
    $out .= "<li class='top {$activeclass}'><a href='#'>{$item->title}</a>";
}

If you want the parent pages to be highlighted in your multi-level menu as well, you can check if they're in $page->parents.

$parents = $page->parents;
foreach($page->menu_page as $item) {
    $parentclass = ($parents->has($item)) ? 'active' : ''; //If this is a parent of the page we are viewing, add the class.
    $activeclass = ($item == $page) ? 'current' : ''; //If this is the page we are viewing, add the classes. Otherwise use ''.
    $out .= "<li class='top {$activeclass} {$parentclass}'><a href='#'>{$item->title}</a>";
}

Or something like that...

  • Like 3
Link to comment
Share on other sites

@mrkhan,

Just want to clarify that you can pass a PageArray to MarkupSimpleNavigation as explained here: https://github.com/somatonic/MarkupSimpleNavigation#build-a-menu-using-a-pagearray-instead-of-a-single-root-page

Build a menu using a PageArray instead of a single root page

 
Since 1.3.3 you can also define a PageArray as the root page argument. Instead of a root it will take the PageArray as the first level entries. This can be used to build a menu from a page select field for example. Assuming you have a page field "navigation_entries" on your home root page

You are also not limited to a single menu per page.

But feel free to use what works for you and you are comfortable with :D

If you haven't already, also have a look at the PW docs here:

Selectors: http://processwire.com/api/selectors/

Page: http://processwire.com/api/variables/page/

Pages: http://processwire.com/api/variables/pages/

Edited by kongondo
  • Like 3
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

×
×
  • Create New...