Jump to content

Recommended Posts

3 hours ago, Mike Rockett said:

It does appear to work, but the root page is also assigned the current class when viewing any decsendant.

My bad! I forgot to do that check. We check by looking at $page->parents....Since home is everybody's parents, it passes the logic. I'll fix this in the next commit. 

3 hours ago, Mike Rockett said:

Is there no clean way to add an option to specific menu items that states "add current class here if an included / non-included descendant is current"?

RE 'specific menu items':

Unlike the backend per-menu-item setting Include natural children, you cannot cherry pick which items to apply current class to. That has to be done at a global level, aka $options.  For the benefit of others reading this, in this regard, 'current_class' and 'current_class_level' work globally. For 'current_class_level' = 0 we target current $page that is not part of the MB menu items (aka non-included) in order to apply 'current_class' to its NATURAL (ProcessWire) ancestors in the MB menu. For 'current_class_level' > 1, we target current $page that is either part of the MB menu or that was made part of the MB menu via 'include_children' in order to apply 'current_class' to itself as well as its Menu Builder ancestors in the MB menu if applicable. 

Back to Mike's question, as stated in some previous posts, for such fine-grained/specific control, I recommend using the getMenuItems() method with your own custom function.  Please see this post for examples as well as custom functions + gists. Please note that currently, getMenuItems() does not support 'include_children' but it will soon.

Link to post
Share on other sites
5 minutes ago, kongondo said:

My bad! I forgot to do that check. We check by looking at $page->parents....Since home is everybody's parents, it passes the logic. I'll fix this in the next commit. 

I thought that may be the case -- thanks!

And thanks for the explanation, I understand how it works now.

Link to post
Share on other sites

Update: Menu Builder Version 0.2.1.

Changelog

  1. Fixed bug in 'current_class_level' where 'current_class' was being applied to 'Home' menu item when level was set to '0'.
  2. getMenuItems() now honours both locally and globally set 'include_children'.
  3. Added 'cached_menu' option to MarkupMenuBuilder to save and fetch menus from cache to speed up menu rendering if required.
  4. Added 'cached_menu_time' to set cached menu expiration time. For compatible times, see WireCache docs.
  5. Fixed bug in ProcessMenuBuilder where 'include_children' and 'm_max_level' inputs would be displayed when the page selected to add to menu was 'Home' (These options do not apply to Home).

Note

Cached Menu

  • The benefits of this feature will likely be small for most sites as menu rendering is already fast. However, for cases where you have lots of items in your menu (or in your site map if you are using Menu Builder for such), you will notice some difference. In addition, since cached menus save the full menu items array to the database (JSON of items only; not the markup!), it means you avoid the internal multiple pages->get() for getting menu items. You only hit the database once or twice (WireCache) and you got your menu! The feature also works with multi-lingual sites, in which case each language's menu is cached separately. Anyway, the feature is there for those that need it.
  • Please note that the feature does not work with getMenuItems() since in such cases you are retrieving menu items to do what you will with them (even cache them yourself if you wish).
  • Limitations: Currently, cached menus ONLY respect 'current_class_level' 0 and 1 (the default). This is because the 'current-ness' of a menu item should not be cached! That has to be checked live [EDIT].

 

News features in dev branch only for now. Please let me know how it goes, thanks.

Edited by kongondo
Oversights and then some!
  • Like 2
Link to post
Share on other sites
37 minutes ago, Mike Rockett said:

@kongondo Thanks! Works like a charm now.

Good to know. Thanks for testing!

Please note I've just pushed a new commit (but did not change versions) to fix some oversight in the last commit. It should not affect you unless you are using the cached menu feature. I've also updated my previous post.

  • Like 2
Link to post
Share on other sites
  • 2 weeks later...

Hi! kongondo, Menu Builder is vety easy to use and powerful, But now I'm going to add some css3 effects to the menu.

Can you add a custom tpl parameter to the list item.

E.g. I want to make it

<li> <a href="">item name</a></li>

into

<li> <a href=""><span data="item name">item name</span></a></li>

The final effect is like this webpage's top menu:

http://mo005-3785.mo5.line1.uemo.net/list/id/37389/

Link to post
Share on other sites
4 hours ago, taoguang said:

Can you add a custom tpl parameter to the list item.

Hi @taoguang. Welcome to the forums.

For such custom markup, I recommend you make use of the getMenuItems() method as described in this post. I am happy to assist if you do get stuck.

  • Like 1
Link to post
Share on other sites
18 hours ago, kongondo said:
18 hours ago, kongondo said:

Hi @taoguang. Welcome to the forums.

For such custom markup, I recommend you make use of the getMenuItems() method as described in this post. I am happy to assist if you do get stuck.

Cool! Thank you, With this method, Now I can do almost anything!

 

  • Like 1
Link to post
Share on other sites
  • 3 weeks later...

Hi @kongondo

Thank you for so great module!

I use 0.1.7 version of module and get 

PHP Notice: Array to string conversion in ...\ProcessMenuBuilder\MarkupMenuBuilder.module:922

Here is how I use it

$menu_page = pages(1023);
if($lang_name == "ukrainian") {
    $menu_page = pages(1024);
}

$menu = $menuModule->getMenuItems($menu_page, 1, [
    "current_class_level" => 2
]);

Changing this line

$menuItems = '';

to 

$menuItems = array();

fixes it. 

Am I missing something? 

Link to post
Share on other sites

Hi @Zeka

Yeah, PHP 7 is a little more stricter. PHP 5 forgave such indiscretions :).  If you could open a bug report for me so that I don't forget to fix it, I'll appreciate it (along with other issues that have been recently reported). Thanks.

  • Like 1
Link to post
Share on other sites
On 7/20/2017 at 12:38 PM, kongondo said:

Update: Menu Builder Version 0.1.9.

Changelog

  1. Added support for multi-lingual menu items (both PW pages and custom ones)! Thanks @Michael van Laar for 'reminder'.

I'm busy with a multi-lingual site for a client, and this feature doesn't appear to work on my end - I'm getting the error "No menu items found" when switching to the only non-default language.

My menu, called footerNavLeft, is set to use French, and the language tabs are being added to the menu builder (and inheriting default values as expected). When opening the site in English (default language), all is fine. The moment I switch to French, it goves the above-mentioned error.

I'm rendering the menu to my view like this:

$menus = wire('modules')->MarkupMenuBuilder;
$view->menuFooterNavLeft = $menus->render('footerNavLeft', [
    'menu_css_class' => 'menu',
]);

infinitygroupcm_pw.lserv-2017-10-01-17-28-15.screengrab.jpeg.25b227270af4ae500a3c764e21ca2508.jpeg

 

 

---

Edit: Apologies - missed the instructions (which aren't clear in the post quoted above). Using a Page ID works. Though, I hve to ask: why isn't it possible to use a menu name/title in a multi-lingual environment?

Edited by Mike Rockett
Oops!
Link to post
Share on other sites
1 hour ago, Mike Rockett said:

Apologies - missed the instructions (which aren't clear in the post quoted above). Using a Page ID works. Though, I hve to ask: why isn't it possible to use a menu name/title in a multi-lingual environment?

Ahem...really Mike? :'(....the docs, Mike, the docs:P

Quote

The first argument is not optional and can be a Page object, a title, name or id of a menu or an array of menu items returned from a menu's menu_items field. Note that for multilingual environments, you cannot pass the method a title or a name; only the other three choices will work. The second argument is an optional array and will fall back to defaults if no user configurations are passed to the method.

Glad you got it sorted :):).

  • Like 1
Link to post
Share on other sites
15 minutes ago, kongondo said:

Ahem...really Mike? :'(....the docs, Mike, the docs:P

Glad you got it sorted :):).

Works flawlessly by the way. :-) I haven't perused the source yet, but would it be possible for you to make reference by name/title work, considering that it doesn't change on a per-language basis? 

Link to post
Share on other sites
1 minute ago, Mike Rockett said:

would it be possible for you to make reference by name/title work, considering that it doesn't change on a per-language basis? 

I suppose so. I struggle with the ML API to be honest and could do with some help. Do I tell PW to get the page (menu) with the title of the default language? Thanks for any pointers/code, ta.

Link to post
Share on other sites
26 minutes ago, kongondo said:

I suppose so. I struggle with the ML API to be honest and could do with some help. Do I tell PW to get the page (menu) with the title of the default language? Thanks for any pointers/code, ta.

I'm no expert either, but I feel the calls made to search for menu pages in MarkupMenuBuilder.module:142-144 are a bit much... On my side, changing it to the following fixes the issue, but I honestly don't know if it breaks anything else...

$menuName = $this->wire('sanitizer')->pageName($menu);
$menu = $this->wire('pages')->get("name=$menuName, template=menus, parent.name=menu-builder, check_access=0");

 

Edited by Mike Rockett
Refer to specific commit for when code changes...
Link to post
Share on other sites

Wrapping inner <ul> into div?

thanks for your great module!

With the uikit nav + dropdown i need to wrap an inner <ul> into a <div>. Thats fairly easy with MarkupSimpleNavigation "inner_tpl" but how to do it in this case?

Uikit example:

<a href"#">Menuitem</a>
<div uk-dropdown>
  <ul class="uk-nav uk-dropdown-nav">...</ul>
</div>

thanks!

Link to post
Share on other sites
1 hour ago, kater said:

Wrapping inner <ul> into div?

thanks for your great module!

With the uikit nav + dropdown i need to wrap an inner <ul> into a <div>. Thats fairly easy with MarkupSimpleNavigation "inner_tpl" but how to do it in this case?

Menu Builder doesn't support that out of the box, and so you'll need to use getMenuItems(), which allows you to build your menu the way you want it. Here are some gists that could guide you for your menu.

  • Like 1
Link to post
Share on other sites

Hi @kongondo

I have this setup: 

  • MenuItem1
    • Submenuitem_01( allowed children)
    • SubmenuItem_02 ( allowed children)
  • MenuItem2
    • Submenuitem_03 ( allowed children)
    • SubmenuItem_02 ( allowed children)

I'm using getMenuItems for building my menu, but the issue is that I get children of Submenuitem_02 as children only of the last Submenuitem_02 ( parent_id  =  id of the last Submenuitem_02 ), but I expected that I will get duplications of children pages with right parent_id for every Submenuitem_02

Of course, I can get children in my custom function but I think that in this case, getMenuItems doesn't work as expected and could be improved.

What do you think about it? 

Thanks, Eugene. 

Link to post
Share on other sites
  • 1 month later...

I am currently getting a fatal error on a multilanguage site. On the german version, there is no problem, the menu is rendering just as expected, but when I try to open the english or dutch version I am getting the following message:

Error: Exception: No menu items found! Confirm that such a menu exists and that it has menu items. (in /Applications/MAMP/htdocs/cleaninstall/site/modules/ProcessMenuBuilder/MarkupMenuBuilder.module line 959)

#0 /Applications/MAMP/htdocs/cleaninstall/site/modules/ProcessMenuBuilder/MarkupMenuBuilder.module(87): MarkupMenuBuilder->throwError()
#1 /Applications/MAMP/htdocs/cleaninstall/site/templates/partials/header.inc(110): MarkupMenuBuilder->render('main', Object(MenuOptions))
#2 /Applications/MAMP/htdocs/cleaninstall/wire/core/TemplateFile.php(259): require('/Applications/M...')
#3 /Applications/MAMP/htdocs/cleaninstall/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render()
#4 /Applications/MAMP/htdocs/cleaninstall/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___render', Array)
#5 /Applications/MAMP/htdocs/cleaninstall/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array)
#6 

 

The mentioned line 110 of header.inc looks like this: 

<?php
$options = array(
  'menu_css_class' => 'menu-lvl-1',
  'submenu_css_class' => 'menu-lvl-2',
  'current_class' => 'active',
  'has_children_class' => 'has_children',
  'current_class_level' => 3,
  'include_children' => 1
);
?>
<?php echo $menu->render('main', $options); ?>

The Processwire version is 3.0.62 and yes, I already checked if there were menu items in there and I also created another menu to confirm that the error persists.

Link to post
Share on other sites
48 minutes ago, thmsnhl said:

I am currently getting a fatal error on a multilanguage site. On the german version, there is no problem, the menu is rendering just as expected, but when I try to open the english or dutch version I am getting the following message:

 

48 minutes ago, thmsnhl said:

<?php echo $menu->render('main', $options); ?>

https://github.com/kongondo/MenuBuilder#api

render()

This method renders a menu/navigation list of a specified menu. The method accepts two arguments/parameters:

render($menu, $options);

The first argument is not optional and can be a Page object, a title, name or id of a menu or an array of menu items returned from a menu's menu_items field. Note that for multilingual environments, you cannot pass the method a title or a name; only the other three choices will work. The second argument is an optional array and will fall back to defaults if no user configurations are passed to the method.

@thmsnhl

That should resolve your issue :).

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

@kongondo First: thank you for your response and sorry for my delayed reply. I had some other projects crashing my work on that one.

With your help I was able to render the menu also on localized sites. The code now looks like this:

<?php
$options = array(
'menu_css_class' => 'menu-lvl-1',
'submenu_css_class' => 'menu-lvl-2',
'current_class' => 'active',
'has_children_class' => 'has_children',
'current_class_level' => 3,
'include_children' => 1
);
?>
<?php echo $menu->render($pages->get("id=1930"), $options); ?>

But: The menu does not show the localized page titles, those are still German. Am I missing anything else?

 

Edit: I solved it, I just realised that I was missing the following option to translate the titles.

'default_title' => 1

 

  • Like 1
Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By monollonom
      (once again I was surprised to see a work of mine pop up in the newsletter, this time without even listing the module on PW modules website 😅. Thx @teppo !)
      Github: https://github.com/romaincazier/FieldtypeQRCode
      Modules directory: https://processwire.com/modules/fieldtype-qrcode/
      This is a simple module I made so a client could quickly grab a QR Code of the page's url in the admin.
      There's not much to it for now, but if need be you can output anything using a hook:
      $wire->addHookAfter("FieldtypeQRCode::getQRText", function($event) { $event->return = "Your custom text"; }) You can also output the QR code on your front-end by calling the field:
      echo $page->qr_code_field; The module uses the PHP library QR Code Generator by Kazuhiko Arase. When looking for a way to generate a QR Code in PW I came across @ryan's integration in his TFA module. I'm not very familiar with fieldtype/inputfield module development so I blindly followed @bernhard (great) tutorial and his BaseFieldtypeRuntime. At some point I'll take a deeper look to make a module on my own.
      Some ideas for improvements :
      add the ability to choose what to ouput : page's url / editUrl / file(s) / image(s) / ... allow to output multiple QR codes ?
    • By Chris Bennett
      https://github.com/chrisbennett-Bene/AdminThemeTweaker
      Inspired by @bernhard's excellent work on the new customisable LESS CSS getting rolled into the core soon, I thought I would offer up the module for beta testing, if it is of interest to anyone.

      It takes a different approach to admin styling, basically using the Cascade part of CSS to over-ride default UiKit values.
      Values are stored in ModuleConfig Module creates a separate AdminThemeTweaker Folder at root, so it can link to AdminThemeTweaker.php as CSS AdminThemeTweaker.php reads the module values, constructs the CSS variables then includes the CSS framework Can be switched on and off with a click. Uninstall removes everything, thanks to bernhard's wonderful remove dir & contents function.
      It won't touch your core. It won't care if stuff is upgraded. You won't need to compile anything and you don't need to touch CSS unless you want to.

      It won't do much at all apart from read some values from your module config, work out the right CSS variables to use (auto contrast based on selected backgrounds) and throw it on your screen.
      You can configure a lot of stuff, leave it as it comes (dark and curvy), change two main colors (background and content background) or delve deep to configure custom margins, height of mastheads, and all manner of silly stuff I never use.

      Have been developing it for somewhere around 2 years now. It has been (and will continue to be) constantly tweaked over that time, as I click on something and find something else to do.
      That said, it is pretty solid and has been in constant use as my sole Admin styling option for all of those 2 years.

      If nothing else, it would be great if it can provide any assistance to @bernhard or other contributor's who may be looking to solve some of the quirkier UiKit behavior.
      Has (in my opinion) more robust and predictable handling of hidden Inputfields, data-colwidths and showIf wrappers.
      I am very keen to help out with that stuff in any way I can, though LESS (and any css frameworks/tools basically) are not my go.
      I love CSS variables and banging-rocks-together, no-dependency CSS you can write with notepad.



       

    • By opalepatrick
      I see old posts saying that repeaters are not the way to go in Custom Process Modules. If that is the case, when using forms (as I am trying to do) how would one tackle things like repeat contact fields where there can be multiple requirements for contact details with different parameters? (Like point of contact, director, etc) or even telephone numbers that have different uses?
      Just for background I am creating a process module that allows me to create types of financial applications in the admin area (no need to publish any of this, pure admin) that require a lot of personal or company information.
      Maybe I am thinking about this incorrectly?
    • By HMCB
      I ran across a reference to IftRunner module. The post was 6 years ago. I cant find it in available modules. Has it been pulled?
    • By tcnet
      PageViewStatistic for ProcessWire is a module to log page visits of the CMS. The records including some basic information like IP-address, browser, operating system, requested page and originate page. Please note that this module doesn't claim to be the best or most accurate.
      Advantages
      One of the biggest advantage is that this module doesn't require any external service like Google Analytics or similar. You don't have to modify your templates either. There is also no Javascript or image required.
      Disadvantages
      There is only one disadvantage. This module doesn't record visits if the browser loads the page from its browser cache. To prevent the browser from loading the page from its cache, add the following meta tags to the header of your page:
      <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /> How to use
      The records can be accessed via the Setup-menu of the CMS backend. The first dropdown control changes the view mode.

      Detailed records
      View mode "Detailed records" shows all visits of the selected day individually with IP-address, browser, operating system, requested page and originate page. Click the update button to see new added records.

      Cached visitor records
      View modes other than "Detailed records" are cached visitor counts which will be collected on a daily basis from the detailed records. This procedure ensures a faster display even with a large number of data records. Another advantage is that the detailed records can be deleted while the cache remains. The cache can be updated manually or automatically in a specified time period. Multiple visits from the same IP address on the same day are counted as a single visitor.

      Upgrade from older versions
      Cached visitor counts is new in version 1.0.8. If you just upgraded from an older version you might expire a delay or even an error 500 if you display cached visitor counts. The reason for this is that the cache has to be created from the records. This can take longer if your database contains many records. Sometimes it might hit the maximally execution time. Don't worry about that and keep reloading the page until the cache is completely created.
      Special Feature
      PageViewStatistic for ProcessWire can record the time a visitor viewed the page. This feature is deactivated by default. To activate open the module configuration page and activate "Record view time". If activated you will find a new column "S." in the records which means the time of view in seconds. With every page request, a Javascript code is inserted directly after the <body> tag. Every time the visitor switches to another tab or closes the tab, this script reports the number of seconds the tab was visible. The initial page request is recorded only as a hyphen (-).

      Settings
      You can access the module settings by clicking the Configuration button at the bottom of the records page. The settings page is also available in the menu: Modules->Configure->ProcessPageViewStat.
      IP2Location
      This module uses the IP2Location database from: http://www.ip2location.com. This database is required to obtain the country from the IP address. IP2Location updates this database at the begin of every month. The settings of ProcessPageViewStat offers the ability to automatically download the database monthly. Please note, that automatically download will not work if your webspace doesn't allow allow_url_fopen.
      Dragscroll
      This module uses DragScroll. A JavaScript available from: http://github.com/asvd/dragscroll. Dragscroll adds the ability in view mode "Day" to drag the records horizontally with the mouse pointer.
      parseUserAgentStringClass
      This module uses the PHP class parseUserAgentStringClass available from: http://www.toms-world.org/blog/parseuseragentstring/. This class is required to filter out the browser type and operating system from the server request.
×
×
  • Create New...