Jump to content

Menu Builder


kongondo

Recommended Posts

When I use the menu-builder then I have to give a link to a page for each entry. In this case I give the link to the startpage in the specified language e.g. /startpage/en for english language. I found no way to stay on the active page but in a different language.

In the past I used the language switcher that you proposed. But it can not be part of the main menu. That is the problem.

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

If you've created a menu like this:

  • Parent 1
  • - Child 1.1
  • - Child 1.2
  • Parent 2
  • - Child 2.1
  • - Child 2.2

and you're on page Child 1.1, is there a way to just get the siblings of the submenu, i.e. Child 1.1, Child 1.2?

And every time you change to a page under a different parent, it shows only the child menu items?

Link to comment
Share on other sites

This is how I did it:

	$mb = $modules->get('MarkupMenuBuilder');
	$items = $mb->getMenuItems('Main', 2);

	foreach ($items as $item) :

		if ($item->isCurrent) :
			$currentID = $item->id;
			$parentID  = $item->parentID;
		endif;

	endforeach;

	$subItems = $items->find("parentID=$parentID");

	foreach ($subItems as $subItem) $output .= '<a href="'.$subItem->url.'">'.$subItem->title.'</a>';

 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Good day to everyone.

Please tell me how to implement my menu with different menu subclasses?

Here is the code of my old site menu. 

	+'<nav class="mainNav">'
		+'<div class="mobileMainNavBtn mainNav__btn">'
			+'<span></span>'
		+'</div>'
		+'<ul class="mainNav__list">'
			+'<li class="mainNav__item"><a href="/en/" class="mainNav__link" title="Hotel Prestige Center, St. Petersburg">Hotel</a>'
				+'<ul class="mainNavDropdownL1 mainNav__dropdown">'
					+'<li class="mainNavDropdownL1__item"> <a href="/about/contacts/" class="mainNavDropdownL1__link" title="Our contact">Our contact</a> 	</li>'
					+'<li class="mainNavDropdownL1__item"> <a href="/about/rekviziti/" class="mainNavDropdownL1__link" title="Payment details">Payment details</a> </li>'
					+'<!--<li class="mainNavDropdownL1__item"> <a href="/about/3stars/" class="mainNavDropdownL1__link" title="Hotel certificate">Hotel certificate</a> 	</li>-->'
				+'</ul>'
			+'</li>'
			+'<li class="mainNav__item"><a href="https://pre-apart.ru/" class="mainNav__link" title="kitchen">Kitchen</a></li>'
			+'<li class="mainNav__item">'
			+'<a href="/en/nomera/" class="mainNav__link" title="Hotel room">Rooms</a>'
				+'<ul class="mainNavDropdownL1 mainNav__dropdown mainNav__dropdown--row">'
					+'<li class="mainNavDropdownL1__item">'
					+'<a href="/en/nomera/cat1/" class="mainNavDropdownL1__link" title="">The rooms of the first category</a>'
						+'<ul class="mainNavDropdownL2 mainNavDropdownL1__dropdown">'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cat1/mini/" class="mainNavDropdownL2__link" title="Mini Room">«Mini»</a></li>'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cat1/econom/" class="mainNavDropdownL2__link" title="Room I category Economy">«Economy»</a></li>'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cat1/standart/" class="mainNavDropdownL2__link" title="Category I room Standard">«Standard»</a></li>'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cat1/comfort/" class="mainNavDropdownL2__link" title="The I-Comfort category">«Comfort»</a></li>'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cat1/comfort+/" class="mainNavDropdownL2__link" title="The I-Comfort category">«Comfort +»</a></li>'
						+'</ul>'
					+'</li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/nomera/cathigh/" class="mainNavDropdownL1__link" title="">Rooms of the highest category</a>'
						+'<ul class="mainNavDropdownL2 mainNavDropdownL1__dropdown">'
							
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cathigh/deluxe/" class="mainNavDropdownL2__link" title="Superior Junior Suite with Jacuzzi">«Junior Suite»</a></li>'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cathigh/luxe/" class="mainNavDropdownL2__link" title="Suite of the highest category Two-room Suite">«Lux»</a></li>'
							+'<li class="mainNavDropdownL2__item"><a href="/en/nomera/cathigh/apartment/" class="mainNavDropdownL2__link" title="Superior room Apartment with Jacuzzi">«Apartment»</a></li>'
						+'</ul>'
					+'</li>'
					+'<li class="mainNavDropdownL1__item"><a href="https://pre-apart.ru/en/rooms-suites/" class="mainNavDropdownL1__link" title="">Room with kitchen</a>'
						+'<ul class="mainNavDropdownL2 mainNavDropdownL1__dropdown">'
							+'<!--<li class="mainNavDropdownL2__item"><a href="/en/nomera/kitchen/13A/" class="mainNavDropdownL2__link" title="Room with kitchen 13A">«Room with kitchen 13A»</a></li>-->'
							+'<!--<li class="mainNavDropdownL2__item"><a href="/en/nomera/kitchen/13B/" class="mainNavDropdownL2__link" title="Room with kitchen 13B">«Apartment 13B»</a></li>-->'
							+'<!--<li class="mainNavDropdownL2__item"><a href="/en/nomera/kitchen/11/" class="mainNavDropdownL2__link" title="Marine 11">«Marine 11»</a></li>-->'
							+'<!--<li class="mainNavDropdownL2__item"><a href="/en/nomera/kitchen/12/" class="mainNavDropdownL2__link" title="Marine 12">«Marine 12»</a></li>-->'
							+'<!--<li class="mainNavDropdownL2__item"><a href="/en/nomera/cathigh/studio/" class="mainNavDropdownL2__link" title="Room of the highest category Studio">«Studio»</a></li>-->'
						+'</ul>'
					+'</li>'
					+'<li class="mainNavDropdownL1__item"><a href="/tseni/" class="mainNavDropdownL1__link" title="Prices for Rooms hotels">Hotel price</a>'
						+'<ul class="mainNavDropdownL2 mainNavDropdownL1__dropdown">'
						+'<li class="mainNavDropdownL2__item"><a href="/gallery/" class="mainNavDropdownL2__link" title="Hotel gallery">«Hotel gallery»</a></li>'
						+'</ul>'
					+'</li>'
				+'</ul>'
			+'</li>'

			+'<li class="mainNav__item"><a href="/skidki/" class="mainNav__link" title="Hotel cheaper: discounts and special offers to hotel guests">Discounts</a></li>'
			+'<li class="mainNav__item"><a href="/uslugi/" class="mainNav__link" title="Breakfast, lunch, dinner">Service</a>'
				+'<ul class="mainNavDropdownL1 mainNav__dropdown">'
					+'<!--<li class="mainNavDropdownL1__item"><a href="/uslugi/transfer/" class="mainNavDropdownL1__link" title="Трансфер">Трансфер до/из отеля</a></li>-->'
					+'<li class="mainNavDropdownL1__item"><a href="/uslugi/voucher/" class="mainNavDropdownL1__link" title="Visa support">Visa support</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/cafe/" class="mainNavDropdownL1__link" title="Russian cuisine restaurant of the hotel">Breakfast and dinner</a></li>'
				+'</ul>'
			+'</li>'
			+'<li class="mainNav__item"><a href="/raspolozenie/" class="mainNav__link" title="Location on the map">Location</a>'
				+'<ul class="mainNavDropdownL1 mainNav__dropdown">'
					+'<li class="mainNavDropdownL1__item"><a href="/raspolozenie/" class="mainNavDropdownL1__link" title="Hotel location on the map of St. Petersburg">Hotel on the map</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/raspolozenie/dobratsya/" class="mainNavDropdownL1__link" title="How to get to the hotel in St. Petersburg">How to get</a></li>'
				+'</ul>'
			+'</li>'
			+'<li class="mainNav__item"><a href="/en/bronirovanie/" class="mainNav__link" title="Quick booking of rooms">Booking</a>'
				+'<ul class="mainNavDropdownL1 mainNav__dropdown">'
					+'<li class="mainNavDropdownL1__item"><a href="/en/bronirovanie/" class="mainNavDropdownL1__link" title="Book a hotel room">Booking a room!</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/tseni/oplata/uniteller/" class="mainNavDropdownL1__link" title="Card payment online">Card payment online</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/tseni/oplata/uniteller/emoney.php" class="mainNavDropdownL1__link" title="Payment by e-money Ya. Money, WebMoney, QIWI">Payment from e-wallets</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/tseni/oplata/sberbank/" class="mainNavDropdownL1__link" title="Payment through Sberbank">Payment through Sberbank</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/tseni/oplata/platezka/" class="mainNavDropdownL1__link" title="Payment by Bank transfer">Payment by Bank transfer</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/tseni/oplata/creditcard/" class="mainNavDropdownL1__link" title="Card payment off-line">Card payment off-line</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/tseni/oplata/vozvrat/" class="mainNavDropdownL1__link" title="Chargeback">Chargeback</a></li>'
					+'<li class="mainNavDropdownL1__item"><a href="/en/about/offero/" class="mainNavDropdownL1__link" title="Public offer">Public offer</a></li>'
				+'</ul>'
			+'</li>'
			+'<li class="mainNav__item"><a href="/contacts/" class="mainNav__link" title="Contacts">Contacts</a></li>'
				+'</ul>'	
		+'</nav>'

That's what I've already done.

<nav class="mainNav">
<?php
			// load the module
			$menu = $modules->get('MarkupMenuBuilder');// $menu is an example

			

			$options = array(
			'wrapper_list_type' => 'ul',// ul, ol, nav, div, etc.
			'' => 'li',// li, a, span, etc.
			'' => 'main',// a CSS ID for the menu
			'menu_css_class' => 'mainNav__list',// a CSS Class for the menu
			'submenu_css_class' => 'mainNavDropdownL1 mainNav__dropdown',// CSS Class for sub-menus
			'has_children_class' => 'mainNav__item',// CSS Class for any menu item that has children
			);
			
			echo $menu->render ('main', $options);// render the menu by title		

		?>
</nav>

If this is not possible, please also write, then I will redo the CSS of the old menu.

Thanks.

Link to comment
Share on other sites

  On 5/20/2022 at 6:11 AM, siaweb said:

Good day to everyone.

Expand  

Welcome to the forums @siaweb.

  On 5/20/2022 at 6:11 AM, siaweb said:

Please tell me how to implement my menu with different menu subclasses?

Expand  

Do you mean each submenu to have a unique subclass? That is not possible using $menu->render(). Instead, I'd suggest getMenuItems(). Please see its documentation and examples here.

  On 5/20/2022 at 7:19 AM, Clarity said:

Hello, @kongondo!

Expand  

Hello @Clarity,

  On 5/20/2022 at 7:19 AM, Clarity said:

Can you please tell me where can I see the name of menu? It seems to me that the name and the title of menu are the same.

Expand  

The menu name is automatically created from the menu title. It is not separately editable via Menu Builder (it's a page though). Could you please explain why you need access to the name?

Link to comment
Share on other sites

  On 5/20/2022 at 7:38 PM, kongondo said:

Welcome to the forums @siaweb.

Do you mean each submenu to have a unique subclass? That is not possible using $menu->render(). Instead, I'd suggest getMenuItems(). Please see its documentation and examples here.

Hello @Clarity,

The menu name is automatically created from the menu title. It is not separately editable via Menu Builder (it's a page though). Could you please explain why you need access to the name?

Expand  

Good day. I'm not selenium in PHP to be honest. But from what you sent me for review, I have read.

I can do this. 

Rules: If the menu goes deeper than 1 level, then apply such a style. (But as far as I understood, the style will only apply to il and not to ul)

Thanks for the reference, I will try to understand, but I realized for myself that it's easier for me to redo the CSS menu. Since it's easier for me than with PHP. 

Thanks. But for the overall development, everything is exactly on the test server, then I will try to do it more correctly.

Link to comment
Share on other sites

  On 5/20/2022 at 7:38 PM, kongondo said:

Hello @Clarity,

The menu name is automatically created from the menu title. It is not separately editable via Menu Builder (it's a page though). Could you please explain why you need access to the name?

Expand  

The problem is that I need to use the title, say, 'footer-menu' in code: $menuBuilder->getMenuItems('footer-menu'). Then I think it is not a good practice to give a title to menu like 'Footer Menu'. Also, if the title can be multi-language, it might, I think, cause other issues.

Link to comment
Share on other sites

  On 5/24/2022 at 6:37 AM, Clarity said:

Then I think it is not a good practice to give a title to menu like 'Footer Menu'.

Expand  

Why is it not good practice? ? 

  On 5/24/2022 at 6:37 AM, Clarity said:

Also, if the title can be multi-language, it might, I think, cause other issues.

Expand  

This is already supported (version 0.2.7):

 

  • Thanks 1
Link to comment
Share on other sites

  • 4 weeks later...
  On 5/20/2022 at 7:38 PM, kongondo said:

Welcome to the forums @siaweb.

Expand  

hi @kongondoI dealt with my first question differently. Completely redesigned the menu for module requests. But I had a new question. I just can't redo the menu in my second project otherwise. The bottom line is that I use two classes for links example below.

  Reveal hidden contents

My problem is in two classes that I won't be able to transfer. class="ajax-loader" class="page-link

Link to comment
Share on other sites

  • 1 month later...

Hi @kongondo,

after setting some of our PHP environments to 8.0, we registered an error on deleting menu items (ProcessWire 3.0.200, MenuBuilder 0.2.7, Multi-language):

method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given in line 2602 in ProcessMenuBuilder.module. To prevent this, a check for item related page existence was successful:

if (!$itemID || !$pages->get($itemID)->id) continue;

Could you publish a bug fix release für this issue, please?

Thanks in advance,

Thomas from xport.

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Hello,

I've been having problems with implementing my menu in my template.

Not sure how to continue here, it's not working as it should. First parent looks ok, but all submenus are not. Is this even possible with this approach?

My HTML code looks like this:

  Reveal hidden contents

What I managed to do:
 

  Reveal hidden contents

Any help appreciated.

R

Link to comment
Share on other sites

  • 1 month later...

Any ideas on this? Only custom urls are being output, even with built in methods. I have an older PW site I'm busy reskinning. That works but the new one's menu doesn't and I can't see what the difference is. 

Here is my menu json:

 

{"2":{"title":"Home","pages_id":1},"17":{"title":"Portfolio \/ Services","pages_id":1170},"7":{"title":"Weddings","parent_id":17,"pages_id":1118},"14":{"title":"Portraits and Headshots","parent_id":17,"pages_id":1134},"19":{"title":"Portraits","parent_id":17,"pages_id":1186},"12":{"title":"Family","parent_id":17,"pages_id":1132},"18":{"title":"Maternity","parent_id":17,"pages_id":1182},"11":{"title":"Architecture","parent_id":17,"pages_id":1136},"8":{"title":"Real Estate","parent_id":17,"pages_id":1138},"15":{"title":"Events","parent_id":17,"pages_id":1140},"20":{"title":"FAQ -----","url":"#"},"21":{"title":"Wedding FAQ","parent_id":20,"pages_id":1174},"5":{"title":"Contact","pages_id":1047},"1":{"title":"Posts","pages_id":1020},"16":{"title":"About","pages_id":1149},"22":{"title":"aaaa","url":"#"}}

This is the test code I'm using:  (it's a built in method of MenuBuilder)

 

$menu = $modules->get('MarkupMenuBuilder');
echo $menu->render('Main');// render the menu by title

And here is the output:

 

<ul>
	<li>
		<a href="/pwvanilla/">Home</a>
	</li>
	<li>
		<a href="#">FAQ -----</a>
	</li>
	<li>
		<a href="#">aaaa</a>
	</li>
</ul>

As you can see it is "ignoring" anything that isn't a custom url 

I'm running PHP 7.3 and I've tried on other versions using wamp, the result is the same. 

MenuBuilder is amazing but with this error I might have to abandon it, please help if you can.

 

Thank you. 

Link to comment
Share on other sites

@mel47 I got it right. For use: I include the php file in the header. It's for a Bootstrap 4 site but I'd imagine Bootstrap 5 would be very similar. 

Note:  I did have an issue with a nav padding on "sm devices" which I couldn't resolve in the php output. In the end I added an additional rule to my css to fix it. A bit of a hack but it's working. 

@media (max-width: 992px) {
    li.nav-item {
        padding-left: 30px;
    }
}

And here is the php

<?php namespace ProcessWire;

function buildMenuFromObject($parent = 0, $menu, $first = 0) {
	if(!is_object($menu)) return;

	$out = '';
	$has_child = false;

	foreach ($menu as $m) {
		$newtab = $m->newtab ? " target='_blank'" : '';
		// if this menu item is a parent; create the sub-items/child-menu-items
		if ($m->parentID == $parent) {// if this menu item is a parent; create the inner-items/child-menu-items
				// if this is the first child
				if ($has_child === false) {
						$has_child = true;// This is a parent
						if ($first == 0){
							$out .= "\n<ul class='navbar-nav plain mx-auto text-center'>";
							$first = 1;
						}
						else {
							$out .=
								"\n\t" .
									"<ul class='dropdown-menu'>";
						}
				}
				// active/current menu item
				$class = $m->isParent ?  ' class="nav-item dropdown"' : ' class="nav-item"';
				$aClass = $m->isParent ?  'class="dropdown-item dropdown-toggle"' : 'class="dropdown-item"';

				// a menu item
				$out .= "\n\t<li$class><a {$aClass} href='{$m->url}' '{$newtab}'>{$m->title}</a>";

				// call function again to generate nested list for sub-menu items belonging to this menu item.
				$out .= buildMenuFromObject($m->id, $menu, $first);
				if ($m->isParent) $out .= "\n";// close li
				$out .= "</li>";

		}// end if parent

	}// end foreach

	if ($has_child === true) $out .= "\n\t</ul>";

	return $out;

}

$menu = $modules->get('MarkupMenuBuilder');
$menuItemsAsObject = $menu->getMenuItems('Main', 2);//Where "Main" is the name of the menu to output
$menu = buildMenuFromObject(0, $menuItemsAsObject);

   
?>

<div id="gregnav">
<nav class="navbar wide transparent transparent-light navbar-expand-lg">
      <div class="container-fluid flex-row justify-content-center">
        <div class="navbar-header">
          <div class="navbar-brand"><a href="index.html"><img src="#" srcset="<?php echo $config->urls->templates?>style/greg-images/GL-black-square60.png 1x, <?php echo $config->urls->templates?>style/greg-images/GL-black-square75.png 2x" alt="" /></a></div>
          <div class="navbar-hamburger ml-auto d-lg-none d-xl-none"><button class="hamburger animate" data-toggle="collapse" data-target=".navbar-collapse"><span></span></button></div>
        </div>
        <!-- /.navbar-header -->
        <div class="navbar-collapse collapse justify-content-between align-items-center">


		  <?=$menu?>
        </div>

        <!--/.social-wrapper -->
      </div>
    </nav>
</div>

I hope that helps you. ?



 

  • Like 1
Link to comment
Share on other sites

Hi all,

Sorry, I have been away from this parts of the forums for a while. 

  On 9/28/2022 at 12:37 PM, Clarity said:

Can you please tell me how to create a dynamic menu using your module? Where URLs of pages are relative not to a whole site, but to every page where we use this menu.

Expand  

@Clarity

I am not sure I follow. Please clarify, e.g. with an illustration.

Does this post perhaps offer a solution?

 

Edited by kongondo
Link to comment
Share on other sites

  On 4/12/2022 at 11:33 AM, Tyssen said:

This is how I did it:

	$mb = $modules->get('MarkupMenuBuilder');
	$items = $mb->getMenuItems('Main', 2);

	foreach ($items as $item) :

		if ($item->isCurrent) :
			$currentID = $item->id;
			$parentID  = $item->parentID;
		endif;

	endforeach;

	$subItems = $items->find("parentID=$parentID");

	foreach ($subItems as $subItem) $output .= '<a href="'.$subItem->url.'">'.$subItem->title.'</a>';

 

Expand  

Thanks for this example @Tyssen. Out of curiosity, how do you use $currentID subsequently?

Link to comment
Share on other sites

  On 7/18/2022 at 1:16 PM, xportde said:

after setting some of our PHP environments to 8.0, we registered an error on deleting menu items (ProcessWire 3.0.200, MenuBuilder 0.2.7, Multi-language):

method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given in line 2602 in ProcessMenuBuilder.module. To prevent this, a check for item related page existence was successful:

if (!$itemID || !$pages->get($itemID)->id) continue;

Could you publish a bug fix release für this issue, please?

Expand  

@xportde. Thanks for catching this. I'll work on it, hopefully soon. I am (very) slowly moving all my modules to require at least PHP 8.x. Thanks!

Link to comment
Share on other sites

  On 9/22/2022 at 8:08 AM, Greg Lumley said:

As you can see it is "ignoring" anything that isn't a custom url 

Expand  

@Greg Lumley,

Just to be clear, did menuRender() used to work in an older site but isn't working in a newer site? If yes, what is the difference between those sites in relation to:

  1. ProcessWire versions? <-- I suspect the issue is here perhpaps.
  2. PHP versions?

Thanks.

Link to comment
Share on other sites

  • 2 weeks later...

Hi,
Unfortunately I can find what is the problem. I don't think it's related to my templates, since it didn't work even in Tracy. In my previous project, the same code render correctly a menu.
Same PHP version 7.2 (localhost) but different versions PW (3.0.206 vs 3.0.188).
Mel
 

204.thumb.png.53d57efba2d77a23966d8d5ea981a9b6.png

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
×
×
  • Create New...