Jump to content

Recommended Posts

Posted (edited)

This bug has been already reported by one of my colleagues in 2021, but nothing has been corrected so far. If your profile is set in a language other than the default language, and you are building a menu with the MenuBuilder module, your menu won't appear correctly in the other language.

1639174403_CleanShot2022-11-08at15_34_29.png.ce07791ca729c0794681ba173637af93.png

If you switch back to the original language, you can edit it.

668728021_CleanShot2022-11-08at15_44_43.png.49293712e8586db9538c55635bf534dd.png

Also, the menu is pretty useless because it doesn't show correctly in pages.

935616135_CleanShot2022-11-08at15_53_52.png.c2bf052ec0adc3e151be1023c683c8b9.png

Which is a real problem in one of our actual project

1173005745_CleanShot2022-11-08at15_57_50.png.8769b0b687c4f45245d759d0b0b954c9.png

Is there a solution for that?

 

Edited by Spiria
Typo
Posted

Hey @Spiria — just a heads-up that I have merged your post to the Menu Builder support thread. Official support thread is the best way to reach module author. Looking back to the report in 2021, it looks like that earlier report might've just gone unnoticed.

  • Like 1
Posted
19 hours ago, Spiria said:

This bug has been already reported by one of my colleagues in 2021, but nothing has been corrected so far. If your profile is set in a language other than the default language, and you are building a menu with the MenuBuilder module, your menu won't appear correctly in the other language.

What @teppo said. Apologies this slipped under the radar. I'll have a look this weekend.

Posted
19 hours ago, Spiria said:

Also, the menu is pretty useless because it doesn't show correctly in pages.

Not sure I understand this bit. Is it related to the 'switching user language profile' issue you've mentioned?

Posted

Hello,

if you build the menu with language in your profile other than the default language, the menu will not translate correctly to the language chosen by a visitor, as my examples show.

Posted
On 11/17/2022 at 7:34 PM, Spiria said:

@kongondo Where you able to figure out what the problem is?

Hi @Spiria,

Sorry, didn't get a chance to look at it. There are two 'issues' you have reported:

#1 If your profile is set in a language other than the default language, and you are building a menu with the MenuBuilder module, your menu won't appear correctly in the other language.

I am working on a fix now. I hope to fix over the weekend. No promises though.

#2 if you build the menu with language in your profile other than the default language, the menu will not translate correctly to the language chosen by a visitor, as my examples show.

By default Menu Builder will display the title of the page as it was when it was added to the menu. If you want it to be dynamic depending on the current title and current language, you need to use the default_title option as documented here. For example:

<?php

namespace ProcessWire;

$menu = $modules->get('MarkupMenuBuilder');
// render the menu by title and show the current title of the page in the user's language
$content =  $menu->render('My Menu', ['default_title' => 1]);

 

 

 

Posted
On 11/17/2022 at 7:34 PM, Spiria said:

@kongondo Where you able to figure out what the problem is?

Hi @Spiria

Could you please test version 0.2.8 currently on the dev branch? You will have to install it manually. It fixes the issue:

Quote

If your profile is set in a language other than the default language, and you are building a menu with the MenuBuilder module, your menu won't appear correctly in the other language.

Please let me know if it works. 

Thanks.

Posted

Sorry for the delay. My colleague said the problem is solved in part:

When I add a page to a menu in another language than default, the url is now OK, but the title is displayed in the wrong language as before

A page with the site's page selector, not a custom addition.

 

  • 2 weeks later...
Posted
On 11/23/2022 at 7:57 PM, Spiria said:

but the title is displayed in the wrong language as before

I don't understand this. 

  1. What title are you referring to? The titles of menus that are displayed in the dashboard that shows all Menu Builder menus in the backend?
  2. What is the wrong language in this case?
  3. A screenshot with English explanations would help.
Posted

Hi kogondo, I am a colleague of Spiria. In this exemple, the default language is French. if the profile of the user who modify the menu is english, the url of the item that will be displayed is correct, but not the title. 

 

Screenshot 2022-12-04 at 2.34.55 PM.png

Posted
11 minutes ago, GEN- said:

Hi kogondo, I am a colleague of Spiria. In this exemple, the default language is French. if the profile of the user who modify the menu is english, the url of the item that will be displayed is correct, but not the title. 

 

Screenshot 2022-12-04 at 2.34.55 PM.png

Hi @GEN-,

Thanks for clarifying. Did you see my response above about this with respect to the option default_title?

 

 

Posted

Thanks Kogondo, I didn't see this comment. I just saw the one from November 20th talking about the version 0.2.8 on the dev branch. I just tried getMenuItems(1705, 1,['default_title' => 1]) and it works.

Thanks again

  • Like 1
Posted
3 minutes ago, GEN- said:

Thanks Kogondo, I didn't see this comment. I just saw the one from November 20th talking about the version 0.2.8 on the dev branch. I just tried getMenuItems(1705, 1,['default_title' => 1]) and it works.

Thanks again

Glad you got it sorted! ?.

By the way, I know there are some CSS issues that need fixing. Something changed in ProcessWire that is messing up the page selections. I have accepted a PR for this in the Project  in GitHUb and will be merging with dev 0.28 this week now that you have confirmed 0.28 works. Thanks.

  • 2 weeks later...
Posted

Hello,

I'm strugling to create the menu, and somehow can't make it to look the same as original.
It somehow works, but no quite right. Not sure what is wrong here. Any help appreciated.

I need:

<ul class="navbar-nav ms-auto">
	<li class="nav-item dropdown"> <span class="nav-link active" data-bs-toggle="dropdown" aria-expanded="false"> Home <i class="ti-angle-down"></i></span>
		<ul class="dropdown-menu last">
			<li class="dropdown-item"><a href="index.html">Home Layout 01</a></li>
			<li class="dropdown-item"><a href="index2.html">Home Layout 02</a></li>
			<li class="dropdown-item"><a href="index3.html">Home Layout 03</a></li>
			<li class="dropdown-item active"><a href="index4.html">Home Layout 04</a></li>
			<li class="dropdown-item"><a href="index5.html">Home Layout 05</a></li>
			<li class="dropdown-item"><a href="index6.html">Home Layout 06</a></li>
			<li class="dropdown-item"><a href="index7.html">Home Layout 07</a></li>
		</ul>
	</li>
</ul>

My code:

<?php

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 .= "<ul class='navbar-nav ms-auto'>\n";                            
			  $first = 1;
			}                        
			else $out .= "\n<ul class='dropdown-menu last'>\n";
		}
		$class = $m->isCurrent ? 'active' : '';
		// a menu item
		$out .= '<li class="nav-item dropdown"><span class="nav-link  ' . $class . '"  data-bs-toggle="dropdown" aria-expanded="false"><a href="' . $m->url . '">'. $m->title .'</a>';                    
		// if menu item has children
		if ($m->isParent) {
		  $out .= '<i class="ti-angle-down"></i></span>';
		}
		
		else $out .= '<li class="nav-item dropdown">' .
		'</a>';         
		// call function again to generate nested list for sub-menu items belonging to this menu item. 
		$out .= buildMenuFromObject($m->id, $menu, $first);
		$out .= "</li>\n";
	}// end if parent
  
  }// end foreach
  if ($has_child === true) $out .= "</ul>\n";    
  return $out;
}


##################################

$mb = $modules->get('MarkupMenuBuilder');// get Menu Builder

$menu = 1031;// pass an ID

$options = array('default_title'=> 1, 'default_class'=> 'dropdown-item', 'current_class_level' => 6);
/* grab menu items as a WireArray with Menu objects */
$menuItems = $mb->getMenuItems($menu, 2, $options);// called with options and 2nd argument = 2 {return Menu (WireArray object)}
?>
		   
<?php
  // build menu from array (example 1b only)
  echo buildMenuFromObject(0, $menuItems);
?>

Thank you very much

R

  • 1 month later...
Posted

Hello everyone,

I have following markup for my menu build with module "MenuBuilder" and I want to update it to PHP 8. I am not very expirienced with PHP so I cant find a solution. Here is the code:

<?php namespace ProcessWire;
/*
 *
 * Main Menu.
 *
 */
?>
    <?php
/**
 * Builds a nested list (menu items) of a single menu.
 *
 * A recursive function to display nested list of menu items.
 *
 * @access private
 * @param Int $parent ID of menu item.
 * @param Array $menu Object of menu items to display.
 * @param Int $first Helper variable to designate first menu item.
 * @return string $out.
 *
 */
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='uk-navbar-nav'>";
                    $first = 1;
                }
                else {
                    $out .=
                        "\n\t<div class='uk-navbar-dropdown'>" .
                        "\n\t\t<ul class='uk-nav uk-navbar-dropdown-nav'>";
                }
            }
            // active/current menu item
            $class = $m->isCurrent ? ' class="uk-active"' : '';

            // a menu item
            $out .= "\n\t<li$class><a 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\t</div>\n";// close div.uk-navbar-dropdown
            $out .= "</li>";

        }// end if parent

    }// end foreach

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

    return $out;

}

// example usage

$mb = $modules->get('MarkupMenuBuilder');
$menuItemsAsObject = $mb->getMenuItems(1073, 2);
$menu = buildMenuFromObject(0, $menuItemsAsObject);

echo $menu;
?>

As far as I found out, the problem is the function with the $menu variable. But I can't find a way to update this.

May someone can help me out!

thanks in advance

  • 4 weeks later...
Posted

Hey @kongondo, figured out an error

PHP 8.1 - PW 3.0.210

697744425_2023-03-1023_28_45-TypeError_method_exists()_Argument1(object_or_class)mustbeoftypeobjec.thumb.png.b9d543207c337aaadd8aaebc59b42b0a.png

I'm trying to move an existing page and get the error above. Do you need any further info?

EDIT: This fix is working for me - would be nice if you could fix it ?

Cheers

  • 1 month later...
Posted

In a multilingual environment I get the following error, wehen sorting menu-items

TypeError

method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given
File: .../modules/MarkupMenuBuilder/ProcessMenuBuilder.module:2602

2602: if($language != null && method_exists($pages->get($itemID)->title, 'getLanguageValue')) $itemTitle = $pages->get($itemID)->title->getLanguageValue($language);// title of each PW page in this array

This works for me:

 

// multilingual environments
if($language != null && $itemID && method_exists($pages->get($itemID)->title, 'getLanguageValue')) $itemTitle = $pages->get($itemID)->title->getLanguageValue($language);// title of each PW page in this array


 

  • Like 1
  • 3 weeks later...
Posted

Hello

I'm having some problems with my menu. I want to show only first level of my menu without any children but can't make it work, no matter what I do. It always shows children. Any idea?
It is a multilanguage site!

I'm tried:

<?php
$menu = $modules->get('MarkupMenuBuilder');
$options = array(
    'max_levels' => 1,
    'include_children' => 0
);
echo $menu->render(1030, $options);
?>	

But it's not working. Am I missing something or is there some bug maybe. Tried all sorts of codes but childrens are always there.

Thank you

R

Posted

Hi @Roych,

4 hours ago, Roych said:

I want to show only first level of my menu without any children

There is no setting for this currently. 'include_children' applies to only to the 'real/natural ProcessWire children pages. For instance, if my ProcessWire page tree is as follows:

Home
	About
    	History
        Mission
        Team
	Services
    Plans

And your Menu Builder Menu is as follows (in the backend):

Home
About
	Services

If you use 'include_children', your rendered menu will display as follows:

Home
About
	Services
    History
    Mission
    Team

As you can see, 'include_children' will grab the 'real' children (ProcessWire pages) of 'About'  and display them in the menu. However, without 'include_children', your menu will be rendered as follows:

Home
About
	Services

You cannot programmatically disables 'Services' from not showing. I.e,, there is no option for you to get:

Home
About

However, you can achieve what you want by using getMenuItems()

You can have getMenuItems() return an object (WireArray). You can then use WireArray methods to remove children items from the WireArray. Finally, given that this is a single level menu, you can just loop through the filtered WireArray and display them in your markup. Example code (untested):

<?php

namespace ProcessWire;

$menu = $modules -> get('MarkupMenuBuilder');
// get the menu items for menu with ID 1030
/** @var WireArray $menuItems */
$menuItems = $menu->getMenuItems(1030);
// OR, if passing options
// $menuItems = $menu->getMenuItems(1030, 2, $options);
// ------
// grab top level menu items only
// they do not have a parent, i.e. parent_id == 0
/** @var WireArray $topLevelMenuItems */
$topLevelMenuItems = $menuItems->find("parentID=0");// you could also use (destructive) filter

$out = "<ul>";
foreach($topLevelMenuItems as $topLevelMenuItem){
  $out .= "<li><a href='{$topLevelMenuItem->url}'>{$topLevelMenuItem->title}</a></li>";
}
$out .= "</ul>";

Hope this helps.

Posted

not realy working. The children are not native children of a page, they are made with MenuBuilder drag&drop option. I want those in my header main menu, but in my footer I only want to show the first row.

 

Posted (edited)

Ohhh, with a lot of thinking, this is somehow working But not as expected ?
 

<?php
$homepage = $pages->get(1); // get the homepage
$topLevelPages = $homepage->children("parent_id=1"); // get the top-level pages

$out = "";
foreach ($topLevelPages as $page) {
  $out .= "<li><a href='{$page->url}'>{$page->title}</a></li>";
}
if ($out != "") {
  $out = "<ul>" . $out . "</ul>";
  echo $out;
} else {
  echo "No menu items found.";
}

?>

 

Edited by Roych
Forget this, it's not working!

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