From 53d18ed3455e3a47a2b3f9699c88e068dd60a428 Mon Sep 17 00:00:00 2001
From: chimmel <>
Date: Wed, 9 Oct 2024 09:52:42 -0400
Subject: [PATCH 1/5] fix typos; automatically disable newly added menu items
if disable_items setting is enabled; add target text input to any menu items,
& override new tab in markup
---
MarkupMenuBuilder.module | 25 +++++++++++++-------
ProcessMenuBuilder.module | 49 +++++++++++++++++++++++++++++++++++----
README.md | 4 ++++
3 files changed, 66 insertions(+), 12 deletions(-)
diff --git a/MarkupMenuBuilder.module b/MarkupMenuBuilder.module
index 53ceb41..ccc9153 100644
--- a/MarkupMenuBuilder.module
+++ b/MarkupMenuBuilder.module
@@ -33,7 +33,7 @@ class MarkupMenuBuilder extends WireData implements Module {
'title' => 'Menu Builder: Markup',
'summary' => 'Render menus created by Process Menu Builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.7',
+ 'version' => '0.2.8',
'href' => 'http://processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
@@ -275,6 +275,8 @@ class MarkupMenuBuilder extends WireData implements Module {
// NEW TAB
$m->newtab = isset($item['newtab']) ? 1 : '';
+ // TARGET
+ $m->target = isset($item['target']) ? $item['target'] : '';
// CSS
$m->cssID = isset($item['css_itemid']) ? $item['css_itemid'] : '';
@@ -614,7 +616,9 @@ class MarkupMenuBuilder extends WireData implements Module {
foreach ($menu as $m) {
// set properties
- $newtab = $m->newtab ? " target='_blank'" : '';
+ $newtab = $m->newtab && empty($m->target) ? " target='_blank'" : '';
+ $target = $m->target ? " target='".$m->target."'" : '';
+ // if (!empty($target)) $newtab = ''; // Override newtab target attribute
// if this menu item is a parent; create the sub-items/child-menu-items
if ($m->parentID == $parent) {
@@ -663,8 +667,8 @@ class MarkupMenuBuilder extends WireData implements Module {
$class = strlen($classes) ? ' class="' . $classes . '"' : '';
// if $iTag is empty, apply css id and classes to instead
- if (!$iTag) $out .= "\n\t{$m->title}";
- else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t{$m->title}";
+ if (!$iTag) $out .= "\n\t{$m->title}";
+ else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t{$m->title}";
// build nested/sub-elements
$out .= str_replace("\n", "\n\t\t", $this->buildMenu($m->id));
@@ -717,6 +721,7 @@ class MarkupMenuBuilder extends WireData implements Module {
// set properties
$newtab = $m->newtab ? " target='_blank'" : '';
+ $target = $m->target ? " target='".$m->target."'" : '';
// if this menu item is a parent; create the sub-items/child-menu-items
if ($m->parent_id == $parent) { // @note: here and throughout, property names == original array index!
@@ -758,8 +763,8 @@ class MarkupMenuBuilder extends WireData implements Module {
$class = strlen($classes) ? ' class="' . $classes . '"' : '';
// if $iTag is empty, apply css id and classes to instead
- if (!$iTag) $out .= "\n\t{$m->title}";
- else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t{$m->title}";
+ if (!$iTag) $out .= "\n\t{$m->title}";
+ else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t{$m->title}";
// build nested/sub-elements
$out .= str_replace("\n", "\n\t\t", $this->buildMenuFromCache($id));
@@ -940,6 +945,7 @@ class MarkupMenuBuilder extends WireData implements Module {
$url = $item->url;
$newtab = '';
+ $target = '';
} else {
// grab the menu item in the WireArray with the id=$item
@@ -947,14 +953,15 @@ class MarkupMenuBuilder extends WireData implements Module {
$title = $m->title;
$url = $m->url;
$newtab = $m->newtab ? "target='_blank'" : '';
+ $target = $m->target ? "target='".$m->target."'" : '';
}
// ancestor items
if ($total - $i != 1) {
$divider = " {$o->divider} "; // note the spaces before and after!
// if $iTag is empty, default to instead
- if (!$iTag) $out .= "{$title}{$divider}";
- else $out .= "<$iTag>{$title}{$divider}$iTag>";
+ if (!$iTag) $out .= "{$title}{$divider}";
+ else $out .= "<$iTag>{$title}{$divider}$iTag>";
}
// the last breadcrumb item, i.e., the current page
@@ -1413,6 +1420,7 @@ class MarkupMenuBuilder extends WireData implements Module {
'title' => $m->title, // default_title: 0=show saved mb titles;1=show actual/current pw titles
'url' => $m->url, // menu items URL
'newtab' => $m->newtab, // open link in new tab?
+ 'target' => $m->target, // open link in new tab?
'css_itemid' => $m->cssID, // the items own CSS ID
'css_itemclass' => $m->cssClass, // the items own CSS class(es)
'include_children' => $m->includeChildren, // include this menu items natural children
@@ -2201,6 +2209,7 @@ class Menu extends WireData {
$this->set('title', '');
$this->set('url', '');
$this->set('newtab', '');
+ $this->set('target', '');
$this->set('parentID', ''); // mb menu item parent [not pw!]
$this->set('pagesID', ''); // for pw pages
$this->set('cssID', '');
diff --git a/ProcessMenuBuilder.module b/ProcessMenuBuilder.module
index 59493a8..1de8d12 100644
--- a/ProcessMenuBuilder.module
+++ b/ProcessMenuBuilder.module
@@ -37,7 +37,7 @@ class ProcessMenuBuilder extends Process implements Module {
'title' => 'Menu Builder: Process',
'summary' => 'Easy, drag and drop menu builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.7',
+ 'version' => '0.2.8',
'href' => 'http:// processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
@@ -430,6 +430,7 @@ class ProcessMenuBuilder extends Process implements Module {
$this->_('CSS ID'),
$this->_('CSS Class'),
$this->_('New Tab'),
+ $this->_('Target'),
));
$n = $modules->get('InputfieldName');
@@ -452,12 +453,17 @@ class ProcessMenuBuilder extends Process implements Module {
$itemCustomNewTab = "";
$itemCustomNewTabHidden = "";// force send a value for new tabs
+ $nt = $modules->get('InputfieldName');
+ $nt->attr('name', 'new_item_custom_target[]');
+ $nt->attr('class', 'new_custom');
+
$t->row(array(
$n->render(),
$u->render(),
$n2->render(),
$n3->render(),
$itemCustomNewTab . $itemCustomNewTabHidden,
+ $nt->render(),
'',
));
@@ -552,6 +558,7 @@ class ProcessMenuBuilder extends Process implements Module {
$this->_('CSS ID'),
$this->_('CSS Class'),
$this->_('New Tab'),
+ $this->_('Target'),
$this->_('Type'),// custom or PW page
));
@@ -580,6 +587,8 @@ class ProcessMenuBuilder extends Process implements Module {
// does this menu item link open in a new window or not (i.e. target='_blank') - for custom menu items only
$itemNewTab = isset($menuItem['newtab']) ? $this->_('Yes') : $this->_('No');
+ $itemTarget = isset($menuItem['target']) ? $menuItem['target'] : '';
+
$itemCSSID = isset($menuItem['css_itemid']) ? $menuItem['css_itemid'] :'';
$itemCSSClass = isset($menuItem['css_itemclass']) ? $menuItem['css_itemclass'] : '';
@@ -590,6 +599,7 @@ class ProcessMenuBuilder extends Process implements Module {
$itemCSSID,
$itemCSSClass,
$itemNewTab,
+ $itemTarget,
$itemType)
);
@@ -773,7 +783,7 @@ class ProcessMenuBuilder extends Process implements Module {
$r = new InputfieldRadios();
$r->attr('id+name', 'menu_item_disable_items');
$r->label = $this->_('Use enable/disable menu items feature');
- $r->notes = $this->_('Allows you to set some menu items as disabled. If an item is disabled, the item together will all of its descendants will be set as disabled after you save the menu settings. Disabled items will not be output when the menu is viewed in the frontend.');
+ $r->notes = $this->_('Allows you to set some menu items as disabled. If an item is disabled, the item together with all of its descendants will be set as disabled after you save the menu settings. Disabled items will not be output when the menu is viewed in the frontend.');
$radioOptions = array (
1 => $this->_('Yes'),
@@ -927,7 +937,7 @@ class ProcessMenuBuilder extends Process implements Module {
- css_itemclass: this menu items's CSS Class (optional)
- pages_id: for PW pages items = $page->id; for custom menu items = 0 (note: this is different from id!)
- optional include children feature
- - opitional disable menu items feature
+ - optional disable menu items feature
*/
@@ -959,6 +969,7 @@ class ProcessMenuBuilder extends Process implements Module {
$this->cssItemClass = isset($item['css_itemclass']) ? $item['css_itemclass'] : '';
$this->itemPagesID = isset($item['pages_id']) ? $item['pages_id'] : 0;// only PW pages will have a pages_id > 0 (equal to their PW page->id)
$this->newTab = isset($item['newtab']) ? $item['newtab'] : 0;
+ $this->target = isset($item['target']) ? $item['target'] : '';// bd($this->target); // 210x bd() for 14 menu items
$this->itemIncludeChildren = isset($item['include_children']) ? $item['include_children'] : '';
$this->itemMenuMaxLevel = isset($item['m_max_level']) ? $item['m_max_level'] : '';
$this->disabledItem = isset($item['disabled_item']) ? $item['disabled_item'] : '';
@@ -1332,6 +1343,8 @@ class ProcessMenuBuilder extends Process implements Module {
if($this->disableItems == 1) $out .= $this->buildMenuItemDisabledMarkup();
######################### custom menu item new tab markup #########################
if(0 == $this->itemPagesID) $out .= $this->buildMenuItemNewTabMarkup();
+ ######################### custom menu item target markup #########################
+ $out .= $this->buildMenuItemTargetMarkup();
######################### item hidden inputs markup #########################
$out .= $this->buildMenuItemHiddenInputs();
@@ -1534,7 +1547,24 @@ class ProcessMenuBuilder extends Process implements Module {
}
/**
- * Builds hiden inputs for tracking menu items settings.
+ * Builds input for specifying menu item target attribute.
+ *
+ * Used in a menu item's settings.
+ *
+ * @access private
+ * @return string $out Markup of input.
+ *
+ */
+ private function buildMenuItemTargetMarkup() {
+ $id = $this->itemID;
+ $value = isset($this->menuItems[$this->itemID]['target']) ? $this->menuItems[$this->itemID]['target'] : '';
+ $out = '
+ ';
+ return $out;
+ }
+
+ /**
+ * Builds hidden inputs for tracking menu items settings.
*
* @access private
* @return string $out Markup of hidden inputs.
@@ -2425,6 +2455,8 @@ class ProcessMenuBuilder extends Process implements Module {
$itemCSSClass = $sanitizer->text($post->css_itemclass[$itemID]);// sanitizer->text to accept multiple classes
$itemNewTab = isset($post->newtab[$itemID]) ? 1 : '';// only save for custom menu items with target='_blank'
+ $itemTarget = isset($post->target[$itemID]) ? $sanitizer->name($post->target[$itemID]) : '';// save for any custom/page(s)
+
// if current user can edit include children values + change include children setting
$itemIncludeChildren = '';
if( $this->includeChildren && isset($post->include_children[$itemID]) ) {
@@ -2451,6 +2483,7 @@ class ProcessMenuBuilder extends Process implements Module {
'include_children' => $itemIncludeChildren,
'm_max_level' => $itemMMaxLevel,
'disabled_item' => $itemDisabled,
+ 'target' => $itemTarget,
);
// add disabled item to array to check if to apply same status to descendants
@@ -2553,6 +2586,7 @@ class ProcessMenuBuilder extends Process implements Module {
$itemCSSClass = $sanitizer->name($post->new_css_itemclass[$i]);
//$itemNewTab = (!isset($post->new_newtab[$i])) ? '' : 1;// using checkbox unreliable; use hidden input instead (below)
$itemNewTab = (int) $post->new_newtab_hidden[$i] ? 1 : '';// hidden input to resolve above
+ $itemTarget = isset($post->new_item_custom_target[$i]) ? $post->new_item_custom_target[$i] : '';
// add custom (external) menu items to our menu
$menuItems[$menuItemID] = array(
@@ -2563,7 +2597,10 @@ class ProcessMenuBuilder extends Process implements Module {
'css_itemclass' => $itemCSSClass,
'pages_id' => '',
'newtab' => $itemNewTab,
+ 'target' => $itemTarget,
);
+ // Auto-disable new items:
+ if ($this->disableItems) $menuItems[$menuItemID]['disabled_item'] = 1;
$menuItemID++;
@@ -2637,6 +2674,8 @@ class ProcessMenuBuilder extends Process implements Module {
'm_max_level' => $itemMMaxLevel,
// 'b_max_level' => $itemBMaxLevel,// @todo - not setting individually for now
);
+ // Auto-disable new items:
+ if ($this->disableItems) $menuItems[$menuItemID]['disabled_item'] = 1;
$menuItemID++;
@@ -2688,6 +2727,8 @@ class ProcessMenuBuilder extends Process implements Module {
'pages_id' => $item->id,// the PW page ID
// 'newtab' => ''// NOT necessary for PW pages
);
+ // Auto-disable new items:
+ if ($this->disableItems) $menuItems[$menuItemID]['disabled_item'] = 1;
$menuItemID++;
diff --git a/README.md b/README.md
index a259740..15344a4 100644
--- a/README.md
+++ b/README.md
@@ -1026,6 +1026,10 @@ GPL2
## Changelog
+### Version 0.2.8
+1. If disable_items menu setting is enabled: automatically disable newly added menu items until positioned in the menu, so as to allow for positioning post-save/addition in a published menu in use, prior to the item being added to its output, e.g., if menu is already in use on the frontend. Once saved/added/disabled, and then positioned, 'Disable' can be unchecked, save, and proper placement attained with no disruption.
+2. Add text input for target attribute that overrides 'New Tab', and is applicable on any menu item (custom/page).
+
### Version 0.2.7
1. In multi-lingual environments, menus and breadcrumbs can retrieved using their titles or names in any language irrespective of the current user's language.
2. For getMenuItems() usage only, added option extra_fields to return values of some specific fields on the menu item pages. See documentation for compatible Fieldtypes.
From f4cf96023ca0ccb6064e6b2e23b1d7e97e64dde1 Mon Sep 17 00:00:00 2001
From: chimmel <>
Date: Wed, 9 Oct 2024 21:39:12 -0400
Subject: [PATCH 2/5] v0.2.81: add options a_toplevel_class, a_children_class,
a_parent_class, for item inner a tag
---
MarkupMenuBuilder.module | 18 ++++++++++++++++--
ProcessMenuBuilder.module | 2 +-
README.md | 3 +++
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/MarkupMenuBuilder.module b/MarkupMenuBuilder.module
index ccc9153..bcd0197 100644
--- a/MarkupMenuBuilder.module
+++ b/MarkupMenuBuilder.module
@@ -33,7 +33,7 @@ class MarkupMenuBuilder extends WireData implements Module {
'title' => 'Menu Builder: Markup',
'summary' => 'Render menus created by Process Menu Builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.8',
+ 'version' => '0.2.81',
'href' => 'http://processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
@@ -662,13 +662,21 @@ class MarkupMenuBuilder extends WireData implements Module {
// apply current item class to current page + ancestors if specified for both native and included menu items
$itemCurrent = $m->isCurrent == 1 ? $o->currentClass . ' ' : '';
+ // a tag:
+ $aTopLevelClass = $o['aTopLevelClass'] ? $o['aTopLevelClass'].' ' : '';
+ $aChildrenClass = $o['aChildrenClass'] ? $o['aChildrenClass'].' ' : '';
+ $aParentClass = $o['aParentClass'] ? $o['aParentClass'].' ' : '';
+ $aTagClass = $parent == 0 ? $aTopLevelClass : $aChildrenClass;
+ if ($m->isParent) $aTagClass .= $aParentClass;
+ $aTagClass = trim($aTagClass);
+
$classes = $itemCSSClass . $itemHasChildren . $itemLast . $itemCurrent . $itemFirst;
$classes = trim(preg_replace('/\s+/', ' ', $classes));
$class = strlen($classes) ? ' class="' . $classes . '"' : '';
// if $iTag is empty, apply css id and classes to instead
if (!$iTag) $out .= "\n\t{$m->title}";
- else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t{$m->title}";
+ else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\turl}\">{$m->title}";
// build nested/sub-elements
$out .= str_replace("\n", "\n\t\t", $this->buildMenu($m->id));
@@ -2139,6 +2147,9 @@ class MenuOptions extends WireData {
current_class_level// NOT for breadcrumbs - 0=unlimited (+ include ancestors of current page that are not menu items);1=current item only;2=current+parent;3=current+parent+grandparent
current_css_id// only for breadcrumbs
default_class// a default css class to be applied to all menu items
+ $this->set('aTopLevelClass', isset($options['a_toplevel_class']) ? $options['a_toplevel_class'] : ''); // a tags
+ $this->set('aChildrenClass', isset($options['a_children_class']) ? $options['a_children_class'] : ''); // a tags
+ $this->set('aParentClass', isset($options['a_parent_class']) ? $options['a_parent_class'] : ''); // a tags
divider// only for breadcrumbs
prepend home page at the as topmost item even if it isn't part of the breadcrumb
prepend_home// only for breadcrumbs => 0=no;1=yes
@@ -2173,6 +2184,9 @@ class MenuOptions extends WireData {
$this->set('currentClassLevel', isset($options['current_class_level']) ? $options['current_class_level'] : 1);
$this->set('currentCSSID', isset($options['current_css_id']) ? $options['current_css_id'] : '');
$this->set('defaultClass', isset($options['default_class']) ? $options['default_class'] : '');
+ $this->set('aTopLevelClass', isset($options['a_toplevel_class']) ? $options['a_toplevel_class'] : '');
+ $this->set('aChildrenClass', isset($options['a_children_class']) ? $options['a_children_class'] : '');
+ $this->set('aParentClass', isset($options['a_parent_class']) ? $options['a_parent_class'] : '');
$this->set('divider', isset($options['divider']) ? $options['divider'] : '»');
$this->set('prependHome', isset($options['prepend_home']) ? $options['prepend_home'] : 0);
$this->set('defaultTitle', isset($options['default_title']) ? $options['default_title'] : 0);
diff --git a/ProcessMenuBuilder.module b/ProcessMenuBuilder.module
index 1de8d12..f457ac4 100644
--- a/ProcessMenuBuilder.module
+++ b/ProcessMenuBuilder.module
@@ -37,7 +37,7 @@ class ProcessMenuBuilder extends Process implements Module {
'title' => 'Menu Builder: Process',
'summary' => 'Easy, drag and drop menu builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.8',
+ 'version' => '0.2.81',
'href' => 'http:// processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
diff --git a/README.md b/README.md
index 15344a4..63aadcf 100644
--- a/README.md
+++ b/README.md
@@ -1026,6 +1026,9 @@ GPL2
## Changelog
+### Version 0.2.81
+1. Add options a_toplevel_class, a_children_class, a_parent_class.
+
### Version 0.2.8
1. If disable_items menu setting is enabled: automatically disable newly added menu items until positioned in the menu, so as to allow for positioning post-save/addition in a published menu in use, prior to the item being added to its output, e.g., if menu is already in use on the frontend. Once saved/added/disabled, and then positioned, 'Disable' can be unchecked, save, and proper placement attained with no disruption.
2. Add text input for target attribute that overrides 'New Tab', and is applicable on any menu item (custom/page).
From 7657bd6f4a0c9e4e9759ad76f8c6bf5983c6e8ff Mon Sep 17 00:00:00 2001
From: chimmel <>
Date: Wed, 9 Oct 2024 21:39:12 -0400
Subject: [PATCH 3/5] v0.2.81: add options a_toplevel_class, a_children_class,
a_parent_class, for item inner a tag
---
MarkupMenuBuilder.module | 18 ++++++++++++++++--
ProcessMenuBuilder.module | 2 +-
README.md | 7 +++++++
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/MarkupMenuBuilder.module b/MarkupMenuBuilder.module
index ccc9153..bcd0197 100644
--- a/MarkupMenuBuilder.module
+++ b/MarkupMenuBuilder.module
@@ -33,7 +33,7 @@ class MarkupMenuBuilder extends WireData implements Module {
'title' => 'Menu Builder: Markup',
'summary' => 'Render menus created by Process Menu Builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.8',
+ 'version' => '0.2.81',
'href' => 'http://processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
@@ -662,13 +662,21 @@ class MarkupMenuBuilder extends WireData implements Module {
// apply current item class to current page + ancestors if specified for both native and included menu items
$itemCurrent = $m->isCurrent == 1 ? $o->currentClass . ' ' : '';
+ // a tag:
+ $aTopLevelClass = $o['aTopLevelClass'] ? $o['aTopLevelClass'].' ' : '';
+ $aChildrenClass = $o['aChildrenClass'] ? $o['aChildrenClass'].' ' : '';
+ $aParentClass = $o['aParentClass'] ? $o['aParentClass'].' ' : '';
+ $aTagClass = $parent == 0 ? $aTopLevelClass : $aChildrenClass;
+ if ($m->isParent) $aTagClass .= $aParentClass;
+ $aTagClass = trim($aTagClass);
+
$classes = $itemCSSClass . $itemHasChildren . $itemLast . $itemCurrent . $itemFirst;
$classes = trim(preg_replace('/\s+/', ' ', $classes));
$class = strlen($classes) ? ' class="' . $classes . '"' : '';
// if $iTag is empty, apply css id and classes to instead
if (!$iTag) $out .= "\n\t{$m->title}";
- else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t{$m->title}";
+ else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\turl}\">{$m->title}";
// build nested/sub-elements
$out .= str_replace("\n", "\n\t\t", $this->buildMenu($m->id));
@@ -2139,6 +2147,9 @@ class MenuOptions extends WireData {
current_class_level// NOT for breadcrumbs - 0=unlimited (+ include ancestors of current page that are not menu items);1=current item only;2=current+parent;3=current+parent+grandparent
current_css_id// only for breadcrumbs
default_class// a default css class to be applied to all menu items
+ $this->set('aTopLevelClass', isset($options['a_toplevel_class']) ? $options['a_toplevel_class'] : ''); // a tags
+ $this->set('aChildrenClass', isset($options['a_children_class']) ? $options['a_children_class'] : ''); // a tags
+ $this->set('aParentClass', isset($options['a_parent_class']) ? $options['a_parent_class'] : ''); // a tags
divider// only for breadcrumbs
prepend home page at the as topmost item even if it isn't part of the breadcrumb
prepend_home// only for breadcrumbs => 0=no;1=yes
@@ -2173,6 +2184,9 @@ class MenuOptions extends WireData {
$this->set('currentClassLevel', isset($options['current_class_level']) ? $options['current_class_level'] : 1);
$this->set('currentCSSID', isset($options['current_css_id']) ? $options['current_css_id'] : '');
$this->set('defaultClass', isset($options['default_class']) ? $options['default_class'] : '');
+ $this->set('aTopLevelClass', isset($options['a_toplevel_class']) ? $options['a_toplevel_class'] : '');
+ $this->set('aChildrenClass', isset($options['a_children_class']) ? $options['a_children_class'] : '');
+ $this->set('aParentClass', isset($options['a_parent_class']) ? $options['a_parent_class'] : '');
$this->set('divider', isset($options['divider']) ? $options['divider'] : '»');
$this->set('prependHome', isset($options['prepend_home']) ? $options['prepend_home'] : 0);
$this->set('defaultTitle', isset($options['default_title']) ? $options['default_title'] : 0);
diff --git a/ProcessMenuBuilder.module b/ProcessMenuBuilder.module
index 1de8d12..f457ac4 100644
--- a/ProcessMenuBuilder.module
+++ b/ProcessMenuBuilder.module
@@ -37,7 +37,7 @@ class ProcessMenuBuilder extends Process implements Module {
'title' => 'Menu Builder: Process',
'summary' => 'Easy, drag and drop menu builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.8',
+ 'version' => '0.2.81',
'href' => 'http:// processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
diff --git a/README.md b/README.md
index 15344a4..3f323d7 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,10 @@ $defaultOptions = array(
'm_max_level' => 1,// how deep to fetch 'include_children'
'current_class_level' => 1,// how high up the ancestral tree to apply 'current_class'
'default_class' => '',// a CSS class to apply to all menu items
+ // inner a tags:
+ 'a_toplevel_class' => '',
+ 'a_children_class' => '',
+ 'a_parent_class' => '',
);
````
@@ -1026,6 +1030,9 @@ GPL2
## Changelog
+### Version 0.2.81
+1. Add options a_toplevel_class, a_children_class, a_parent_class.
+
### Version 0.2.8
1. If disable_items menu setting is enabled: automatically disable newly added menu items until positioned in the menu, so as to allow for positioning post-save/addition in a published menu in use, prior to the item being added to its output, e.g., if menu is already in use on the frontend. Once saved/added/disabled, and then positioned, 'Disable' can be unchecked, save, and proper placement attained with no disruption.
2. Add text input for target attribute that overrides 'New Tab', and is applicable on any menu item (custom/page).
From eb7e90619defdf3e34b520346fc1531544594576 Mon Sep 17 00:00:00 2001
From: chimmel <>
Date: Thu, 24 Oct 2024 14:52:51 -0400
Subject: [PATCH 4/5] add nestedArray method
---
MarkupMenuBuilder.module | 28 +++++++++++++++++++++++++++-
ProcessMenuBuilder.module | 2 +-
README.md | 3 +++
3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/MarkupMenuBuilder.module b/MarkupMenuBuilder.module
index bcd0197..b07c147 100644
--- a/MarkupMenuBuilder.module
+++ b/MarkupMenuBuilder.module
@@ -33,7 +33,7 @@ class MarkupMenuBuilder extends WireData implements Module {
'title' => 'Menu Builder: Markup',
'summary' => 'Render menus created by Process Menu Builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.81',
+ 'version' => '0.2.82',
'href' => 'http://processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
@@ -77,6 +77,32 @@ class MarkupMenuBuilder extends WireData implements Module {
// required
}
+ /**
+ * Get nested array of given menu identity's menu_items
+ *
+ * @param int|string $menuID
+ * @return array $nested
+ *
+ */
+ public function nestedArray(int|string $menuID) {
+ $m = wire('pages')->get('template=menus, name|id|title='.$menuID);
+ if (!$m->id) return false;
+
+ // Get flat items array:
+ $json = $m->menu_items;
+ $array = json_decode($json, true);
+ // Init nested array:
+ $nested = [];
+
+ // Populate nested array:
+ foreach ($array as $k => $v) {
+ if (array_key_exists('parent_id', $v)) $nested[$v['parent_id']][$k] = $v;
+ else $nested[$k] = $v;
+ }
+
+ return $nested;
+ }
+
/**
* Pass on menu items for processing and rendering.
*
diff --git a/ProcessMenuBuilder.module b/ProcessMenuBuilder.module
index f457ac4..1622151 100644
--- a/ProcessMenuBuilder.module
+++ b/ProcessMenuBuilder.module
@@ -37,7 +37,7 @@ class ProcessMenuBuilder extends Process implements Module {
'title' => 'Menu Builder: Process',
'summary' => 'Easy, drag and drop menu builder',
'author' => 'Francis Otieno (Kongondo)',
- 'version' => '0.2.81',
+ 'version' => '0.2.82',
'href' => 'http:// processwire.com/talk/topic/4451-module-menu-builder/',
'singular' => true,
'autoload' => false,
diff --git a/README.md b/README.md
index 3f323d7..9b08523 100644
--- a/README.md
+++ b/README.md
@@ -1030,6 +1030,9 @@ GPL2
## Changelog
+### Version 0.2.82
+1. Add nestedArray method to MarkupMenuBuilder.
+
### Version 0.2.81
1. Add options a_toplevel_class, a_children_class, a_parent_class.
From 6a4a2b34b5b10ab44bc319e55818aa4e873928c0 Mon Sep 17 00:00:00 2001
From: chimmel <>
Date: Thu, 24 Oct 2024 14:58:43 -0400
Subject: [PATCH 5/5] add alterations author note
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 9b08523..2a4039d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
# Menu Builder
This Module allows you to easily create custom menus/navigation lists in the ProcessWire Admin Panel using drag and drop. In the backend, it uses the [nestedSortable](https://github.com/mjsarfatti/nestedSortable) jQueryUI plugin by Manuele J Sarfatti.
+_(Alterations v0.2.8 - 0.2.82 by chimmel)_
+
## Features
* Visual menu builder