Custom Menu Wizard Widget - Version 3.2.4

Version Description

  • bugfix : improve handling of dynamically-generated items, by pre-sorting into menu_order order and coping with negative item ids
  • documentation : updated FAQs
Download this release

Release Info

Developer wizzud
Plugin Icon 128x128 Custom Menu Wizard Widget
Version 3.2.4
Comparing to
See all releases

Code changes from version 3.2.3 to 3.2.4

custom-menu-wizard.js CHANGED
@@ -56,11 +56,11 @@ jQuery(function($){
56
  if(name === 'hide_empty'){
57
  settings[name] = useAlternative || !!ocd.cmwV36plus || val;
58
  }else if(csv[name]){
59
- settings['_' + name + '_sep'] = !val || /(^\d+\+?$|,)/.test($.trim(val)) ? ',' : ' ';
60
  val = $.map(val.split(/[,\s]+/), function(x){
61
  var inherit = !legacyVersion && /\+$/.test(x);
62
  x = x ? parseInt(x, 10) : 0;
63
- return isNaN(x) || x < 1 ? null : (inherit ? x + '+' : x);
64
  });
65
  settings['_' + name] = val.join(settings['_' + name + '_sep']);
66
  }
@@ -673,7 +673,7 @@ jQuery(function($){
673
  var plus = this === item[0] || this === inheritsTickCrossFrom.get(0) ? hasTickCross : $(this).hasClass('cmw-inherit-' + tickOrCross);
674
  return $(this).data().itemid + (plus ? '+' : '');
675
  })
676
- .get().join( /(,|^\d+\+?$)/.test( $.trim(widgetField.val()) || ',' ) ? ',' : ' ' );
677
  widgetField.val(sampleSet).trigger('change');
678
  }
679
  this.blur();
56
  if(name === 'hide_empty'){
57
  settings[name] = useAlternative || !!ocd.cmwV36plus || val;
58
  }else if(csv[name]){
59
+ settings['_' + name + '_sep'] = !val || /(^-?\d+\+?$|,)/.test($.trim(val)) ? ',' : ' ';
60
  val = $.map(val.split(/[,\s]+/), function(x){
61
  var inherit = !legacyVersion && /\+$/.test(x);
62
  x = x ? parseInt(x, 10) : 0;
63
+ return isNaN(x) || !x ? null : (inherit ? x + '+' : x);
64
  });
65
  settings['_' + name] = val.join(settings['_' + name + '_sep']);
66
  }
673
  var plus = this === item[0] || this === inheritsTickCrossFrom.get(0) ? hasTickCross : $(this).hasClass('cmw-inherit-' + tickOrCross);
674
  return $(this).data().itemid + (plus ? '+' : '');
675
  })
676
+ .get().join( /(,|^-?\d+\+?$)/.test( $.trim(widgetField.val()) || ',' ) ? ',' : ' ' );
677
  widgetField.val(sampleSet).trigger('change');
678
  }
679
  this.blur();
custom-menu-wizard.min.js CHANGED
@@ -1,16 +1,16 @@
1
  /*Source: custom-menu-wizard.js
2
- *Compiled: 2015-09-10, Google Closure Compiler...
3
  *STATISTICS
4
- * - originalSize: 85715
5
- * - originalGzipSize: 19918
6
- * - compressedSize: 26591
7
  * - compressedGzipSize: 8560
8
  */
9
  jQuery(function(g){
10
  'use strict';
11
  var x,L=/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)/g,v=function(b,a){return(a?".":"")+"widget-custom-menu-wizard-"+b},A=function(b){var a=g(this).data().cmwDialogVersion.replace(/\./g,""),a=/^\d+$/.test(a)?"v"+a:a;x[a]?x[a].update(b?b.target:this):x.update(b?b.target:this)},C=function(b,a){var c=!1===b,d=c?{}:b.data(),e={},k=!c&&"2.1.0"===d.cmwDialogVersion,f={items:1,exclude:1},m=g.extend({branch_start:1,
12
- exclude_level:1,include_level:1},f);g.each(c?a:b.find(":input").serializeArray(),function(a,b){var h=b.name.replace(/.*\[([^\]]+)\]$/,"$1"),p=!m[h]&&/^-?\d+$/.test(b.value)?parseInt(b.value,10):b.value;e[h]=p;"hide_empty"===h?e[h]=c||!!d.cmwV36plus||p:f[h]&&(e["_"+h+"_sep"]=!p||/(^\d+\+?$|,)/.test(g.trim(p))?",":" ",p=g.map(p.split(/[,\s]+/),function(a){var b=!k&&/\+$/.test(a);a=a?parseInt(a,10):0;return isNaN(a)||1>a?null:b?a+"+":a}),e["_"+h]=p.join(e["_"+h+"_sep"]))});return e},E=function(b,a,c,
13
- d){var e=d.switch_if;return d.switch_at===b&&("current"===e&&a||"no-current"===e&&!a||"no-output"===e&&!c)},Q=function(b,a){b=g.trim(b||"");for(var c={title:"",level:1,branch:0,items:"",depth:0,depth_rel_current:0,start_at:"",start_mode:"",allow_all_root:0,ancestors:0,ancestor_siblings:0,include_root:0,include_level:"",siblings:0,exclude:"",exclude_level:"",contains_current:"",fallback:"",flat_output:0,title_from:"",title_linked:0,ol_root:0,ol_sub:0},d=L.exec(b),e={},k=0,f;d;)k++,d[1]?e[d[1]]=d[2]:
14
  d[3]?e[d[3]]=d[4]:d[5]?e[d[5]]=d[6]:k--,d=L.exec(b);if(k)for(f in e)c.hasOwnProperty(f)&&(c[f]=e[f]);f=!!c.items;d=!f&&!!c.branch;e=!f&&!d;f&&(c.filter="items");if(d){c.filter="branch";f=c.start_at.toString();c.branch_start=f;if("0"===f||"branch"===f)c.branch_start="";"root"===f&&(c.branch_start="1");"children"===f&&(c.branch_start="+1");"parent"===f&&(c.branch_start="-1");if("current"===c.branch||"current-item"===c.branch)c.branch=0;else if(!/^[+\-]?\d+$/.test(c.branch.toString()))if(c.branch=c.branch.toLowerCase(),
15
  f=a.find("a.cmw-item").filter(function(){return g(this).text().toLowerCase()===c.branch}),f.length)c.branch=f.parent().data("itemid");else return!1}e&&(c.filter="",c.level=Math.max(1,parseInt(c.level,10)));c.start_at=null;c.include_level||"1"!==c.include_root||(c.include_level="1");c.include_root=null;if(d&&!c.branch&&c.fallback&&(e=c.fallback.toLowerCase().split(/[\s,]+/),f=" "+e.join(" ")+" ",c.fallback="",0<=f.indexOf(" quit ")?c.fallback="quit":0<=f.indexOf(" parent ")?c.fallback="parent":0<=
16
  f.indexOf(" current ")&&(c.fallback="current"),""!==c.fallback&&"quit"!==c.fallback))for(0<=f.indexOf(" +siblings ")&&(c.fallback_siblings=1),k=0;k<e.length;k++)if(/^\d+$/.test(e[k])&&(f=parseInt(e[k],10),0<f)){c.fallback_depth=f;break}if(c.title_from)for(e=c.title_from.toLowerCase().split(/[\s,]+/),k=0;k<e.length;k++)if(e[k])if("branch"===e[k]||"current"===e[k])c["title_"+e[k]]="0";else if(f=e[k].match(/^(branch|current)(-root|-parent|[+\-]?\d+)$/))"-root"===f[2]?c["title_"+f[1]]=1:"-parent"===f[2]?
@@ -23,7 +23,7 @@ g.trim(r.join(" "))+'">'+e+(a.ol_root?"</ol>":"</ul>");q.html(e);q.find("li").fi
23
  b.append(d).val(a)));return a},R=function(b){b=g(this);var a=b.data(),c=!a.cmwAbsolute,d=b.closest(".ui-dialog"),e=d.find(".ui-dialog-content"),k=parseInt(d.css("top"),10)+(c?1:-1)*g(document).scrollTop();a.cmwAbsolute=c;a.cmwMaxHeight||(a.cmwMaxHeight=e.dialog("option","maxHeight"));b.button("option","icons",{primary:c?"ui-icon-circle-close":"ui-icon-circle-check"});d.toggleClass("cmw-assistance-dialog-fixed",!c);e.dialog("option",{maxHeight:c?!c:a.cmwMaxHeight});d.css("top",k);return!1},S=function(b){var a=
24
  g(this);b=["current-menu-item","current-menu-parent","current-menu-ancestor"];var c=a.closest(".ui-dialog-content"),d=c.find(".cmw-demo-themenu-ul"),a=a.find("span").not("."+b[0]).parentsUntil(d,"li"),e,k=function(){this.title=this.title+" "+e.replace(" "," & ").replace(/-/g," ")};d.find("."+b.join(",.")).removeClass(b.join(" ")).each(function(){this.title=this.title.replace(/\s.*$/,"")});for(d=0;d<a.length;d++)e=1===d?b.join(" "):b[0],a.eq(d).children(".cmw-item").find("span").addClass(e).each(k),
25
  1<b.length&&b.shift();A.call(g(c.data().cmwOnchange).get(0));return!1},T=function(){g(this).closest(".ui-dialog-content").find(".cmw-item").eq(this.href.split("#")[1]).not(":has(.current-menu-item)").trigger("click");this.blur();return!1},U=function(b){b=g(this);var a=b.hasClass("cmw-tick")?"tick":"cross",c=b.parent();b=c.closest(".cmw-demo-themenu-ul");var d=c.hasClass("cmw-inherit-"+a),e=d||c.hasClass("cmw-has-"+a),k=e?g([]):c.parentsUntil(b,".cmw-inherit-"+a),f=g(c.closest(".ui-dialog-content").data().cmwOnchange).find("tick"===
26
- a?".cmw-setitems":".cmw-exclusions"),m;!b.hasClass("cmw-using-alternative")&&f.length&&(m=b.find(".cmw-has-"+a)[d||k.length?"not":"add"](c),!e||c.children("ul").length&&!b.parent().hasClass("cmw-version-210")?e&&!d&&(m=m.not(c.find(".cmw-has-"+a))):m=m.not(c),m=m.add(k.find("li").not(c)),m=m.map(function(){var b=this===c[0]||this===k.get(0)?e:g(this).hasClass("cmw-inherit-"+a);return g(this).data().itemid+(b?"+":"")}).get().join(/(,|^\d+\+?$)/.test(g.trim(f.val())||",")?",":" "),f.val(m).trigger("change"));
27
  this.blur();return!1},V=function(b){var a={autoOpen:!1,width:Math.min(.9*g(window).width(),600),maxHeight:g(window).height()-40,modal:!1,containment:"window",create:function(){var a=g(this).closest(".ui-dialog");if(a.hasClass("cmw-assistance-dialog-fixed"))g("<button/>").addClass("cmw-dialog-fixed-absolute").button({label:b.cmwDialogFixed,icons:{primary:"ui-icon-circle-check"}}).appendTo(a.find(".ui-dialog-titlebar")).on("click",R)},dialogClass:"cmw-assistance-dialog cmw-assistance-dialog-fixed"},
28
  c=g.map(["SetCurrent","Inclusions","Exclusions","Fallback","Alternative"],function(a){return'<div class="cmw-demo-'+a.toLowerCase()+' cmw-demo-small">'+(b["cmwDialog"+a]||"")+"</div>"}),c=g("<div/>",{id:b.cmwDialogId}).addClass(v("dialog")).append(g("<div/>").addClass("cmw-demo-themenu cmw-version-"+b.cmwDialogVersion.replace(/\./g,"")).html('<em class="cmw-demo-small">'+b.cmwDialogPrompt+"</em>")).append(g("<div/>").addClass("cmw-demo-theoutput").html('<em class="cmw-demo-small">'+b.cmwDialogOutput+
29
  '</em><em class="cmw-demo-plugin-version cmw-demo-small">v'+b.cmwDialogVersion+"</em>"+c.shift()+'<div class="cmw-demo-theoutput-wrap ui-corner-all"></div>'+c.join(""))).append(g("<div/>").addClass("cmw-demo-theshortcode").html('<code class="ui-corner-all"></code><div class="cmw-find-shortcodes"><a href="#" class="button-secondary '+v("find-shortcodes")+'" data-nonce="'+(b.cmwDialogNonce||"")+'" title="'+b.cmwDialogShortcodes+'"><span class="spinner"></span><span>[&hellip;]</span></a></div><div class="cmw-demo-found-shortcodes cmw-demo-small ui-corner-all"></div>'));
1
  /*Source: custom-menu-wizard.js
2
+ *Compiled: 2016-02-22, Google Closure Compiler...
3
  *STATISTICS
4
+ * - originalSize: 85716
5
+ * - originalGzipSize: 19914
6
+ * - compressedSize: 26594
7
  * - compressedGzipSize: 8560
8
  */
9
  jQuery(function(g){
10
  'use strict';
11
  var x,L=/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)/g,v=function(b,a){return(a?".":"")+"widget-custom-menu-wizard-"+b},A=function(b){var a=g(this).data().cmwDialogVersion.replace(/\./g,""),a=/^\d+$/.test(a)?"v"+a:a;x[a]?x[a].update(b?b.target:this):x.update(b?b.target:this)},C=function(b,a){var c=!1===b,d=c?{}:b.data(),e={},k=!c&&"2.1.0"===d.cmwDialogVersion,f={items:1,exclude:1},m=g.extend({branch_start:1,
12
+ exclude_level:1,include_level:1},f);g.each(c?a:b.find(":input").serializeArray(),function(a,b){var h=b.name.replace(/.*\[([^\]]+)\]$/,"$1"),p=!m[h]&&/^-?\d+$/.test(b.value)?parseInt(b.value,10):b.value;e[h]=p;"hide_empty"===h?e[h]=c||!!d.cmwV36plus||p:f[h]&&(e["_"+h+"_sep"]=!p||/(^-?\d+\+?$|,)/.test(g.trim(p))?",":" ",p=g.map(p.split(/[,\s]+/),function(a){var b=!k&&/\+$/.test(a);a=a?parseInt(a,10):0;return isNaN(a)||!a?null:b?a+"+":a}),e["_"+h]=p.join(e["_"+h+"_sep"]))});return e},E=function(b,a,
13
+ c,d){var e=d.switch_if;return d.switch_at===b&&("current"===e&&a||"no-current"===e&&!a||"no-output"===e&&!c)},Q=function(b,a){b=g.trim(b||"");for(var c={title:"",level:1,branch:0,items:"",depth:0,depth_rel_current:0,start_at:"",start_mode:"",allow_all_root:0,ancestors:0,ancestor_siblings:0,include_root:0,include_level:"",siblings:0,exclude:"",exclude_level:"",contains_current:"",fallback:"",flat_output:0,title_from:"",title_linked:0,ol_root:0,ol_sub:0},d=L.exec(b),e={},k=0,f;d;)k++,d[1]?e[d[1]]=d[2]:
14
  d[3]?e[d[3]]=d[4]:d[5]?e[d[5]]=d[6]:k--,d=L.exec(b);if(k)for(f in e)c.hasOwnProperty(f)&&(c[f]=e[f]);f=!!c.items;d=!f&&!!c.branch;e=!f&&!d;f&&(c.filter="items");if(d){c.filter="branch";f=c.start_at.toString();c.branch_start=f;if("0"===f||"branch"===f)c.branch_start="";"root"===f&&(c.branch_start="1");"children"===f&&(c.branch_start="+1");"parent"===f&&(c.branch_start="-1");if("current"===c.branch||"current-item"===c.branch)c.branch=0;else if(!/^[+\-]?\d+$/.test(c.branch.toString()))if(c.branch=c.branch.toLowerCase(),
15
  f=a.find("a.cmw-item").filter(function(){return g(this).text().toLowerCase()===c.branch}),f.length)c.branch=f.parent().data("itemid");else return!1}e&&(c.filter="",c.level=Math.max(1,parseInt(c.level,10)));c.start_at=null;c.include_level||"1"!==c.include_root||(c.include_level="1");c.include_root=null;if(d&&!c.branch&&c.fallback&&(e=c.fallback.toLowerCase().split(/[\s,]+/),f=" "+e.join(" ")+" ",c.fallback="",0<=f.indexOf(" quit ")?c.fallback="quit":0<=f.indexOf(" parent ")?c.fallback="parent":0<=
16
  f.indexOf(" current ")&&(c.fallback="current"),""!==c.fallback&&"quit"!==c.fallback))for(0<=f.indexOf(" +siblings ")&&(c.fallback_siblings=1),k=0;k<e.length;k++)if(/^\d+$/.test(e[k])&&(f=parseInt(e[k],10),0<f)){c.fallback_depth=f;break}if(c.title_from)for(e=c.title_from.toLowerCase().split(/[\s,]+/),k=0;k<e.length;k++)if(e[k])if("branch"===e[k]||"current"===e[k])c["title_"+e[k]]="0";else if(f=e[k].match(/^(branch|current)(-root|-parent|[+\-]?\d+)$/))"-root"===f[2]?c["title_"+f[1]]=1:"-parent"===f[2]?
23
  b.append(d).val(a)));return a},R=function(b){b=g(this);var a=b.data(),c=!a.cmwAbsolute,d=b.closest(".ui-dialog"),e=d.find(".ui-dialog-content"),k=parseInt(d.css("top"),10)+(c?1:-1)*g(document).scrollTop();a.cmwAbsolute=c;a.cmwMaxHeight||(a.cmwMaxHeight=e.dialog("option","maxHeight"));b.button("option","icons",{primary:c?"ui-icon-circle-close":"ui-icon-circle-check"});d.toggleClass("cmw-assistance-dialog-fixed",!c);e.dialog("option",{maxHeight:c?!c:a.cmwMaxHeight});d.css("top",k);return!1},S=function(b){var a=
24
  g(this);b=["current-menu-item","current-menu-parent","current-menu-ancestor"];var c=a.closest(".ui-dialog-content"),d=c.find(".cmw-demo-themenu-ul"),a=a.find("span").not("."+b[0]).parentsUntil(d,"li"),e,k=function(){this.title=this.title+" "+e.replace(" "," & ").replace(/-/g," ")};d.find("."+b.join(",.")).removeClass(b.join(" ")).each(function(){this.title=this.title.replace(/\s.*$/,"")});for(d=0;d<a.length;d++)e=1===d?b.join(" "):b[0],a.eq(d).children(".cmw-item").find("span").addClass(e).each(k),
25
  1<b.length&&b.shift();A.call(g(c.data().cmwOnchange).get(0));return!1},T=function(){g(this).closest(".ui-dialog-content").find(".cmw-item").eq(this.href.split("#")[1]).not(":has(.current-menu-item)").trigger("click");this.blur();return!1},U=function(b){b=g(this);var a=b.hasClass("cmw-tick")?"tick":"cross",c=b.parent();b=c.closest(".cmw-demo-themenu-ul");var d=c.hasClass("cmw-inherit-"+a),e=d||c.hasClass("cmw-has-"+a),k=e?g([]):c.parentsUntil(b,".cmw-inherit-"+a),f=g(c.closest(".ui-dialog-content").data().cmwOnchange).find("tick"===
26
+ a?".cmw-setitems":".cmw-exclusions"),m;!b.hasClass("cmw-using-alternative")&&f.length&&(m=b.find(".cmw-has-"+a)[d||k.length?"not":"add"](c),!e||c.children("ul").length&&!b.parent().hasClass("cmw-version-210")?e&&!d&&(m=m.not(c.find(".cmw-has-"+a))):m=m.not(c),m=m.add(k.find("li").not(c)),m=m.map(function(){var b=this===c[0]||this===k.get(0)?e:g(this).hasClass("cmw-inherit-"+a);return g(this).data().itemid+(b?"+":"")}).get().join(/(,|^-?\d+\+?$)/.test(g.trim(f.val())||",")?",":" "),f.val(m).trigger("change"));
27
  this.blur();return!1},V=function(b){var a={autoOpen:!1,width:Math.min(.9*g(window).width(),600),maxHeight:g(window).height()-40,modal:!1,containment:"window",create:function(){var a=g(this).closest(".ui-dialog");if(a.hasClass("cmw-assistance-dialog-fixed"))g("<button/>").addClass("cmw-dialog-fixed-absolute").button({label:b.cmwDialogFixed,icons:{primary:"ui-icon-circle-check"}}).appendTo(a.find(".ui-dialog-titlebar")).on("click",R)},dialogClass:"cmw-assistance-dialog cmw-assistance-dialog-fixed"},
28
  c=g.map(["SetCurrent","Inclusions","Exclusions","Fallback","Alternative"],function(a){return'<div class="cmw-demo-'+a.toLowerCase()+' cmw-demo-small">'+(b["cmwDialog"+a]||"")+"</div>"}),c=g("<div/>",{id:b.cmwDialogId}).addClass(v("dialog")).append(g("<div/>").addClass("cmw-demo-themenu cmw-version-"+b.cmwDialogVersion.replace(/\./g,"")).html('<em class="cmw-demo-small">'+b.cmwDialogPrompt+"</em>")).append(g("<div/>").addClass("cmw-demo-theoutput").html('<em class="cmw-demo-small">'+b.cmwDialogOutput+
29
  '</em><em class="cmw-demo-plugin-version cmw-demo-small">v'+b.cmwDialogVersion+"</em>"+c.shift()+'<div class="cmw-demo-theoutput-wrap ui-corner-all"></div>'+c.join(""))).append(g("<div/>").addClass("cmw-demo-theshortcode").html('<code class="ui-corner-all"></code><div class="cmw-find-shortcodes"><a href="#" class="button-secondary '+v("find-shortcodes")+'" data-nonce="'+(b.cmwDialogNonce||"")+'" title="'+b.cmwDialogShortcodes+'"><span class="spinner"></span><span>[&hellip;]</span></a></div><div class="cmw-demo-found-shortcodes cmw-demo-small ui-corner-all"></div>'));
custom-menu-wizard.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Custom Menu Wizard
4
  * Plugin URI: http://wordpress.org/plugins/custom-menu-wizard/
5
  * Description: Show any part of a custom menu in a Widget, or in content using a Shortcode. Customise the output with extra classes or html; filter by current menu item or a specific item; set a depth, show the parent(s), change the list style, etc. Use the included emulator to assist with the filter settings.
6
- * Version: 3.2.3
7
  * Author: Roger Barrett
8
  * Author URI: http://www.wizzud.com/
9
  * License: GPL2+
@@ -11,6 +11,10 @@
11
  */
12
  defined( 'ABSPATH' ) or exit();
13
  /*
 
 
 
 
14
  * v3.2.3 change log
15
  * - tweaked documentation & verified WP 4.4
16
  *
@@ -166,6 +170,9 @@ if( !class_exists( 'Custom_Menu_Wizard_Plugin' ) ){
166
  //include the widget class and its walker...
167
  include( plugin_dir_path( __FILE__ ) . 'include/class.widget.php' );
168
  include( plugin_dir_path( __FILE__ ) . 'include/class.walker.php' );
 
 
 
169
 
170
  //instantiate...
171
  add_action( 'plugins_loaded', array( 'Custom_Menu_Wizard_Plugin', 'init' ) );
@@ -173,7 +180,7 @@ if( !class_exists( 'Custom_Menu_Wizard_Plugin' ) ){
173
  //declare the main plugin class...
174
  class Custom_Menu_Wizard_Plugin {
175
 
176
- public static $version = '3.2.3';
177
  public static $script_handle = 'custom-menu-wizard-plugin-script';
178
  public static $widget_class = 'Custom_Menu_Wizard_Widget';
179
  protected static $instance;
3
  * Plugin Name: Custom Menu Wizard
4
  * Plugin URI: http://wordpress.org/plugins/custom-menu-wizard/
5
  * Description: Show any part of a custom menu in a Widget, or in content using a Shortcode. Customise the output with extra classes or html; filter by current menu item or a specific item; set a depth, show the parent(s), change the list style, etc. Use the included emulator to assist with the filter settings.
6
+ * Version: 3.2.4
7
  * Author: Roger Barrett
8
  * Author URI: http://www.wizzud.com/
9
  * License: GPL2+
11
  */
12
  defined( 'ABSPATH' ) or exit();
13
  /*
14
+ * v3.2.4 change log
15
+ * - changed the walker and the Assist to cope with negative ids on menu items
16
+ * - added pre-sorting of menu items, to provide better handling of dynamically generated items by other plugins
17
+ *
18
  * v3.2.3 change log
19
  * - tweaked documentation & verified WP 4.4
20
  *
170
  //include the widget class and its walker...
171
  include( plugin_dir_path( __FILE__ ) . 'include/class.widget.php' );
172
  include( plugin_dir_path( __FILE__ ) . 'include/class.walker.php' );
173
+ //...and a small walker for sorting nav items hierarchically : it's used by the widget
174
+ // class - to make sure the branch selector has the right items in the right order
175
+ include( plugin_dir_path( __FILE__ ) . 'include/class.sorter.php' );
176
 
177
  //instantiate...
178
  add_action( 'plugins_loaded', array( 'Custom_Menu_Wizard_Plugin', 'init' ) );
180
  //declare the main plugin class...
181
  class Custom_Menu_Wizard_Plugin {
182
 
183
+ public static $version = '3.2.4';
184
  public static $script_handle = 'custom-menu-wizard-plugin-script';
185
  public static $widget_class = 'Custom_Menu_Wizard_Widget';
186
  protected static $instance;
doc/cmw-doc.html CHANGED
@@ -119,7 +119,7 @@ div > ul > li > ul, div > ol > li > ul {
119
  <p>
120
  <strong>Tested up to:</strong> 4.4</p>
121
  <p>
122
- <strong>Stable tag:</strong> 3.2.3</p>
123
  <p>
124
  <strong>License:</strong> GPLv2 or Later </p>
125
 
@@ -1078,7 +1078,7 @@ notice of is <code>title</code>, which will be output (if supplied) as an H3 in
1078
  <p>Yep, 'fraid so :</p>
1079
 
1080
  <ol>
1081
- <li>The widget will only recognise one "current" item (prior to v2.0.2 it was the last one found; as of v2.0.2, it's the first one encountered, but v3.1.5 add a switch that lets you opt for the last one found). It is perfectly possible to have more than one menu item marked as "current", but if CMW has been configured to filter on anything related to a "current menu item" it can only choose one. The simplest example of multiple "current" items is if you add the same page to a menu more than once, but any other plugin that adds and/or manipulates menu items could potentially cause problems for CMW.</li>
1082
  <li>The widget's "assist" uses jQuery UI's Dialog, which unfortunately (in versions 1.10.3/4) has a <em>really</em> annoying bug in its handling of a draggable (ie. when you drag the Dialog's title bar to reposition it on the page) when the page has been scrolled. It is due to be fixed in UI v1.11.0, but meantime I have defaulted the Dialog to fixed position, with an option to toggle back to absolute : it's not perfect but it's the best compromise I can come up with to maintain some sort of useability.</li>
1083
  </ol>
1084
 
@@ -1095,8 +1095,84 @@ infallible (and it's been proven a fair few times!), so if you still have proble
1095
  <p>Please note that simply reporting "It doesn't work" is not
1096
  the most useful of feedbacks, and is unlikely to get a response other than, possibly, a request for more details.</p>
1097
 
 
 
1098
 
1099
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-3-heading" data-toggle="collapse" href="#faq-3" aria-expanded="false" aria-controls="faq-3"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How do I use the "assist"?</h4></a><div id="faq-3" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-3-heading"><div class="panel-body">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1100
 
1101
 
1102
  <p>The widget's interactive "assist" is specific to each widget instance. It is a javascript-driven <em>emulator</em> that uses the widget instance's
@@ -1126,21 +1202,21 @@ settings but they will be slightly opaque and they will <em>not</em> be clickabl
1126
  If you are using a shortcode implementation, then copy-paste the shortcode text - at the base of either the "assist" or the widget form - straight into your post.</p>
1127
 
1128
 
1129
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-4-heading" data-toggle="collapse" href="#faq-4" aria-expanded="false" aria-controls="faq-4"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Is there an easy way to construct the shortcode?</h4></a><div id="faq-4" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-4-heading"><div class="panel-body">
1130
 
1131
 
1132
  <p>Yes, use a widget form. The shortcode for all the selected/specified options is show at the base of the widget (v3+) and the base of the
1133
  "assist". The widget does not have to be placed within a widget area, it can also be used from the Inactive Widgets area.</p>
1134
 
1135
 
1136
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-5-heading" data-toggle="collapse" href="#faq-5" aria-expanded="false" aria-controls="faq-5"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Do I have to Save the widget if I am using a shortcode?</h4></a><div id="faq-5" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-5-heading"><div class="panel-body">
1137
 
1138
 
1139
  <p>Only if (as of v3.1.5) you are using the <code>widget=N</code> attribute, which refers back to an existing widget instance
1140
  for its settings.</p>
1141
 
1142
 
1143
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-6-heading" data-toggle="collapse" href="#faq-6" aria-expanded="false" aria-controls="faq-6"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How do I get the menu item ids for the 'Items' option?</h4></a><div id="faq-6" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-6-heading"><div class="panel-body">
1144
 
1145
 
1146
  <p>Use the widget's interactive "assist" (see above). Within the representative menu structure, each menu item's id is set in its title
@@ -1148,18 +1224,18 @@ attribute, so should be seen when the cursor is moved over the item. A simpler w
1148
  then show a green tick "checkbox" to the right of each menu item and you simply [un]check the items as required. Each selection will be reflected back into the
1149
  widget's <code>Items</code> settings, and also in the shortcode texts.</p>
1150
 
1151
- <p>The more painstaking way is to go to Appearance, Menus and select the relevant menu; hover over the <em>edit</em>, <em>Remove</em>, or <em>Cancel</em> link for an item and look in
1152
  the URL (the link's href) for <code>menu-item=NNN</code> ... the NNN is the menu item id.</p>
1153
 
1154
 
1155
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-7-heading" data-toggle="collapse" href="#faq-7" aria-expanded="false" aria-controls="faq-7"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How do I get the menu item ids for the 'Exclude Ids' option?</h4></a><div id="faq-7" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-7-heading"><div class="panel-body">
1156
 
1157
 
1158
  <p>The "assist" shows a red cross "checkbox" to the left of each menu item, and [un]checking the items will reflect back into the options and
1159
  shortcode texts. Otherwise, it's the same principle as outlined above for <code>Items</code> ids.</p>
1160
 
1161
 
1162
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-8-heading" data-toggle="collapse" href="#faq-8" aria-expanded="false" aria-controls="faq-8"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>What's the difference between including Branch Siblings (or Branch Ancestors + Siblings), and switching to 'Level' instead of 'Item' in the Secondary Filter section?</h4></a><div id="faq-8" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-8-heading"><div class="panel-body">
1163
 
1164
 
1165
  <p>If you elect to include Branch [Ancestor] Siblings, you will <em>only</em> get the siblings, <strong>not</strong> their descendants (assuming they have any).
@@ -1171,21 +1247,39 @@ will become eligible for filtering. If you left "Item" enabled, and switched on
1171
  would both still be eligible, but only <em>Bravo's descendants</em> would be; not Charlie's!</p>
1172
 
1173
 
1174
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-9-heading" data-toggle="collapse" href="#faq-9" aria-expanded="false" aria-controls="faq-9"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Where is the styling of the output coming from, and how do I change it?</h4></a><div id="faq-9" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-9-heading"><div class="panel-body">
1175
 
1176
 
1177
- <p>The widget does not supply any ouput styling (at all!). This is because I have absolutely no idea where you are going to place either the
1178
- widget (sidebar, footer, header, ad-hoc, etc?) or the shortcode (page content, post content, widget content, custom field, etc?) and everyone's
1179
- requirements for styling are likely to be different ... possibly even within the same web page's output. So all styling is down to your theme,
1180
- and if you wish to modify it you will need to add to your theme's stylesheet.</p>
1181
 
1182
- <p>The safest way to do this is via a child theme, so that any changes you make will not be lost if/when the main theme gets updated. The best
1183
- way to test your changes is by utilising the developer capabilities that are available in most modern browsers (personally, I could not
1184
- do without Firefox and the Firebug extension!) and dynamically applying/modifying styles, possibly utilising the custom classes that the
1185
- widget applies to its output, or the Container options for a user-defined id or class.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1186
 
1187
 
1188
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-10-heading" data-toggle="collapse" href="#faq-10" aria-expanded="false" aria-controls="faq-10"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How can I find all my posts/pages that have a CMW shortcode so that I can upgrade them?</h4></a><div id="faq-10" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-10-heading"><div class="panel-body">
1189
 
1190
 
1191
  <p>There is a button on the widget's "assist" - <code>[...]</code> - that will provide a list of posts/pages whose content, or meta data (custom fields),
@@ -1198,7 +1292,7 @@ the "assist" (for some unknown reason). You may optionally provide a title attri
1198
  Note that output from this shortcode extension is restricted to users with edit_pages capability.</p>
1199
 
1200
 
1201
- </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-11-heading" data-toggle="collapse" href="#faq-11" aria-expanded="false" aria-controls="faq-11"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Is Version 2 of the widget, including the old [custom_menu_wizard/] shortcode, still supported?</h4></a><div id="faq-11" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-11-heading"><div class="panel-body">
1202
 
1203
 
1204
  <p>In Version 3, Yes. However, I highly recommend that you upgrade your widgets &amp; shortcodes to the latest versions,
@@ -1206,7 +1300,14 @@ because Version 2 will <strong>not</strong> be supported beyond Version 3.</p>
1206
  </div></div></div></div> </div>
1207
  <div role="tabpanel" class="tab-pane fade" id="Changelog">
1208
  <h2>Changelog</h2>
1209
- <h4>3.2.3</h4>
 
 
 
 
 
 
 
1210
 
1211
  <ul>
1212
  <li>tweak : minor updates to documentation, and verified for WordPress v4.4</li>
119
  <p>
120
  <strong>Tested up to:</strong> 4.4</p>
121
  <p>
122
+ <strong>Stable tag:</strong> 3.2.4</p>
123
  <p>
124
  <strong>License:</strong> GPLv2 or Later </p>
125
 
1078
  <p>Yep, 'fraid so :</p>
1079
 
1080
  <ol>
1081
+ <li>The widget will only recognise one "current" item (prior to v2.0.2 it was the last one found; as of v2.0.2, it's the first one encountered, but v3.1.5 adds a switch that lets you opt for the last one found). It is perfectly possible to have more than one menu item marked as "current", but if CMW has been configured to filter on anything related to a "current menu item" it can only choose one. The simplest example of multiple "current" items is if you add the same page to a menu more than once, but any other plugin that adds and/or manipulates menu items could potentially cause problems for CMW.</li>
1082
  <li>The widget's "assist" uses jQuery UI's Dialog, which unfortunately (in versions 1.10.3/4) has a <em>really</em> annoying bug in its handling of a draggable (ie. when you drag the Dialog's title bar to reposition it on the page) when the page has been scrolled. It is due to be fixed in UI v1.11.0, but meantime I have defaulted the Dialog to fixed position, with an option to toggle back to absolute : it's not perfect but it's the best compromise I can come up with to maintain some sort of useability.</li>
1083
  </ol>
1084
 
1095
  <p>Please note that simply reporting "It doesn't work" is not
1096
  the most useful of feedbacks, and is unlikely to get a response other than, possibly, a request for more details.</p>
1097
 
1098
+ <p>I should also point out that any other plugin can change any menu, at any time, either before or after this widget does it stuff (even
1099
+ prevent it running at all!), so it's possible that the problem lies somewhere other than CMW.</p>
1100
 
1101
+
1102
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-3-heading" data-toggle="collapse" href="#faq-3" aria-expanded="false" aria-controls="faq-3"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Where is the styling of the output coming from, and how do I change it?</h4></a><div id="faq-3" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-3-heading"><div class="panel-body">
1103
+
1104
+
1105
+ <p>The widget does not supply any output styling (at all!). This is because I have absolutely no idea where you are going to place either the
1106
+ widget (sidebar, footer, header, ad-hoc, etc?) or the shortcode (page content, post content, widget content, custom field, etc?) and everyone's
1107
+ requirements for styling are likely to be different ... possibly even within the same web page's output. So, all styling is down to your theme,
1108
+ and if you wish to modify it you will need to add to (or modify) your theme's stylesheet.</p>
1109
+
1110
+ <p>The safest way to do this is via a <a href="https://codex.wordpress.org/Child_Themes" target='_blank'>child theme<small class="glyphicon glyphicon-new-window offsite-link" aria-hidden="true"></small></a>, so that any
1111
+ changes you make will not be lost if/when the main theme gets updated.
1112
+ The best way to test your changes is by utilising the developer capabilities that are available in most
1113
+ modern browsers (personally, I could not do without Firefox and the Firebug extension!) and dynamically
1114
+ applying/modifying styles, possibly utilising the custom classes that the
1115
+ widget applies to its output, or the Container options for a user-defined id or class.</p>
1116
+
1117
+
1118
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-4-heading" data-toggle="collapse" href="#faq-4" aria-expanded="false" aria-controls="faq-4"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Why is there no (or, How do I get...) indentation on my hierarchical menu?</h4></a><div id="faq-4" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-4-heading"><div class="panel-body">
1119
+
1120
+
1121
+ <p>Firstly, see the answer above, re: styling of the output.</p>
1122
+
1123
+ <p>Any output styling comes from your theme (or possibly some other plugin, but definitely <em>not</em> CMW).</p>
1124
+
1125
+ <p>If other nested lists are displayed with indentation then it is likely (but not guaranteed) that there is a
1126
+ class that can be applied to the CMW output that may result in the desired effect. It is always worth
1127
+ checking out WordPress's own Nav Menu widget, on a menu that has sub-menus : if that has indentation then
1128
+ check the classes <em>it</em> has and try them on CMW (assuming that they're not already there!). If it doesn't
1129
+ have indentation then you're probably going to have to add your own styled class(es) to your theme, and
1130
+ then apply them to CMW.</p>
1131
+
1132
+ <p>Note that quite a few themes "reset/standardise the CSS", by removing all
1133
+ padding and margins from lists : trouble is, some of them don't then provide any means for indenting
1134
+ nested lists.
1135
+ Also, please be aware that any CSS rules that <em>are</em> provided <em>may</em> be location-specific.
1136
+ So, for example, a class may indent nested lists when they are in a sidebar widget area, but not when
1137
+ they're in a footer widget area or inserted within content (using a shortcode).</p>
1138
+
1139
+ <p>Purely as an example, [re-]applying indentation to nested unorder lists (ULs) could be as fundamental as ...</p>
1140
+
1141
+ <pre><code>ul ul { margin-left: 1em; }</code></pre>
1142
+
1143
+ <p>...however, I have found that things a generally never that straightforward, particularly when menus with
1144
+ links in them are involved, so I'm afraid you might to have to experiment a bit.</p>
1145
+
1146
+
1147
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-5-heading" data-toggle="collapse" href="#faq-5" aria-expanded="false" aria-controls="faq-5"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How can I create a horizontal menu?</h4></a><div id="faq-5" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-5-heading"><div class="panel-body">
1148
+
1149
+
1150
+ <p>Firstly, see the answer above, re: styling of the output.</p>
1151
+
1152
+ <p>Any output styling comes from your theme (or possibly some other plugin, but definitely <em>not</em> CMW).</p>
1153
+
1154
+ <p>If you simply want all the menu items to flow horizontally across the page then you could start with
1155
+ something along the lines of...</p>
1156
+
1157
+ <pre><code>.menu-widget {
1158
+ list-style-type: none;
1159
+ margin: 0;
1160
+ padding: 0;
1161
+ }
1162
+ .menu-widget li {
1163
+ display: inline-block;
1164
+ margin: 0 2em 0 0;
1165
+ }</code></pre>
1166
+
1167
+ <p>This is purely an <em>example</em>.</p>
1168
+
1169
+ <p>I've used a class : you may want to change/add to the class, or swap it for an id.
1170
+ There are a number of other ways to do it - especially if you have multiple levels, or you want vertical
1171
+ sub-menus, and/or any sort of interaction. You may want to bring in a jQuery script, or another WordPress
1172
+ plugin, to handle it for you, assuming that your theme doesn't already provide the functionality you need.</p>
1173
+
1174
+
1175
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-6-heading" data-toggle="collapse" href="#faq-6" aria-expanded="false" aria-controls="faq-6"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How do I use the "assist"?</h4></a><div id="faq-6" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-6-heading"><div class="panel-body">
1176
 
1177
 
1178
  <p>The widget's interactive "assist" is specific to each widget instance. It is a javascript-driven <em>emulator</em> that uses the widget instance's
1202
  If you are using a shortcode implementation, then copy-paste the shortcode text - at the base of either the "assist" or the widget form - straight into your post.</p>
1203
 
1204
 
1205
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-7-heading" data-toggle="collapse" href="#faq-7" aria-expanded="false" aria-controls="faq-7"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Is there an easy way to construct the shortcode?</h4></a><div id="faq-7" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-7-heading"><div class="panel-body">
1206
 
1207
 
1208
  <p>Yes, use a widget form. The shortcode for all the selected/specified options is show at the base of the widget (v3+) and the base of the
1209
  "assist". The widget does not have to be placed within a widget area, it can also be used from the Inactive Widgets area.</p>
1210
 
1211
 
1212
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-8-heading" data-toggle="collapse" href="#faq-8" aria-expanded="false" aria-controls="faq-8"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Do I have to Save the widget if I am using a shortcode?</h4></a><div id="faq-8" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-8-heading"><div class="panel-body">
1213
 
1214
 
1215
  <p>Only if (as of v3.1.5) you are using the <code>widget=N</code> attribute, which refers back to an existing widget instance
1216
  for its settings.</p>
1217
 
1218
 
1219
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-9-heading" data-toggle="collapse" href="#faq-9" aria-expanded="false" aria-controls="faq-9"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How do I get the menu item ids for the 'Items' option?</h4></a><div id="faq-9" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-9-heading"><div class="panel-body">
1220
 
1221
 
1222
  <p>Use the widget's interactive "assist" (see above). Within the representative menu structure, each menu item's id is set in its title
1224
  then show a green tick "checkbox" to the right of each menu item and you simply [un]check the items as required. Each selection will be reflected back into the
1225
  widget's <code>Items</code> settings, and also in the shortcode texts.</p>
1226
 
1227
+ <p>The more painstaking way is to go to Appearance, Menus and select the relevant menu; hover over one of the <em>edit</em>, <em>Remove</em>, or <em>Cancel</em> links for an item and look in
1228
  the URL (the link's href) for <code>menu-item=NNN</code> ... the NNN is the menu item id.</p>
1229
 
1230
 
1231
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-10-heading" data-toggle="collapse" href="#faq-10" aria-expanded="false" aria-controls="faq-10"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How do I get the menu item ids for the 'Exclude Ids' option?</h4></a><div id="faq-10" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-10-heading"><div class="panel-body">
1232
 
1233
 
1234
  <p>The "assist" shows a red cross "checkbox" to the left of each menu item, and [un]checking the items will reflect back into the options and
1235
  shortcode texts. Otherwise, it's the same principle as outlined above for <code>Items</code> ids.</p>
1236
 
1237
 
1238
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-11-heading" data-toggle="collapse" href="#faq-11" aria-expanded="false" aria-controls="faq-11"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>What's the difference between including Branch Siblings (or Branch Ancestors + Siblings), and switching to 'Level' instead of 'Item' in the Secondary Filter section?</h4></a><div id="faq-11" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-11-heading"><div class="panel-body">
1239
 
1240
 
1241
  <p>If you elect to include Branch [Ancestor] Siblings, you will <em>only</em> get the siblings, <strong>not</strong> their descendants (assuming they have any).
1247
  would both still be eligible, but only <em>Bravo's descendants</em> would be; not Charlie's!</p>
1248
 
1249
 
1250
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-12-heading" data-toggle="collapse" href="#faq-12" aria-expanded="false" aria-controls="faq-12"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Can CMW handle menus that have items dynamically added by other plugins?</h4></a><div id="faq-12" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-12-heading"><div class="panel-body">
1251
 
1252
 
1253
+ <p>Ummm ... Maybe.</p>
 
 
 
1254
 
1255
+ <p>Unfortunately, I can't answer this with a definitive Yes or No. By definition, if something is "dynamic" then
1256
+ it is likely to change. If the plugin that creates those dynamic items does its job correctly then the items
1257
+ added should have unique ids, <em>at least within the context of the menu being manipulated</em>. Also, those items
1258
+ will probably have been set up with a menu_order property that places them appropriately within the menu
1259
+ structure, and the existing menu items will have been modified accordingly. If that is the case then CMW will
1260
+ be able to process them in the right order &amp; structure.</p>
1261
+
1262
+ <p><strong>However</strong>, there is a big caveat here : CMW stores item ids wherever a specific item is targeted - such
1263
+ as <code>Branch=Page One</code>, or <code>Items=1,3,5</code>, or <code>Exclusions=2,4,6+</code>, etc. If any one of those ids relates
1264
+ to a dynamically-generated item at the time the widget (or shortcode) is configured, then it is possible that
1265
+ the id may get assigned to a different item, or may not even exist, when it comes to displaying the
1266
+ menu.</p>
1267
+
1268
+ <p>As a contrived example, let's say that posts Alpha, Charlie and Echo are dynamically added to a menu, and you
1269
+ can see them when you configure the CMW widget. You decide to Exclude post Charlie, so you configure and save the widget accordingly.
1270
+ Then someone adds or changes post Beta such that <em>it</em> now qualifies for dynamic inclusion into the menu - so, the
1271
+ menu should now contain posts Alpha, Beta, Charlie and Echo. Unfortunately, the ids get re-assigned by the
1272
+ plugin doing the dynamic insertion, and Beta now has the id that Charlie was given when you configured CMW, so
1273
+ Beta gets filtered out and Alpha, Charlie and Echo get shown!</p>
1274
+
1275
+ <p>So, my advice would be : If you use CMW with a menu that you <em>know</em> contains dynamically-degenerated items,
1276
+ try to avoid specifically targeting any of those items in the configuration. For example,
1277
+ setting <code>Branch=Current Item</code> is fine, but don't set <code>Branch=A Dynamic Item</code>; and avoid including or excluding
1278
+ specific dynamic items, use a parent item that exists in the menu instead. If you can do that then there
1279
+ should be no problem.</p>
1280
 
1281
 
1282
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-13-heading" data-toggle="collapse" href="#faq-13" aria-expanded="false" aria-controls="faq-13"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>How can I find all my posts/pages that have a CMW shortcode so that I can upgrade them?</h4></a><div id="faq-13" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-13-heading"><div class="panel-body">
1283
 
1284
 
1285
  <p>There is a button on the widget's "assist" - <code>[...]</code> - that will provide a list of posts/pages whose content, or meta data (custom fields),
1292
  Note that output from this shortcode extension is restricted to users with edit_pages capability.</p>
1293
 
1294
 
1295
+ </div></div></div><div class="panel panel-info"><a class="panel-heading show" role="tab" id="faq-14-heading" data-toggle="collapse" href="#faq-14" aria-expanded="false" aria-controls="faq-14"><h4 class="panel-title"><span class="glyphicon glyphicon-triangle-bottom pull-right"></span><span class="glyphicon glyphicon-triangle-top pull-right"></span>Is Version 2 of the widget, including the old [custom_menu_wizard/] shortcode, still supported?</h4></a><div id="faq-14" class="panel-collapse collapse" role="tabpanel" aria-labelledby="faq-14-heading"><div class="panel-body">
1296
 
1297
 
1298
  <p>In Version 3, Yes. However, I highly recommend that you upgrade your widgets &amp; shortcodes to the latest versions,
1300
  </div></div></div></div> </div>
1301
  <div role="tabpanel" class="tab-pane fade" id="Changelog">
1302
  <h2>Changelog</h2>
1303
+ <h4>3.2.4</h4>
1304
+
1305
+ <ul>
1306
+ <li>bugfix : improve handling of dynamically-generated items, by pre-sorting into menu_order order and coping with negative item ids</li>
1307
+ <li>documentation : updated FAQs</li>
1308
+ </ul>
1309
+
1310
+ <h4>3.2.3</h4>
1311
 
1312
  <ul>
1313
  <li>tweak : minor updates to documentation, and verified for WordPress v4.4</li>
include/class.sorter.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Custom Menu Wizard plugin
4
+ *
5
+ * Custom Menu Wizard Sorter class
6
+ * NB: Walker_Nav_Menu class is in wp-includes/nav-menu-template.php, and is itself an
7
+ * extension of the Walker class (wp-includes/class-wp-walker.php).
8
+ *
9
+ * This is for ensuring that nav items are in a proper hierarchical structure, ie. children
10
+ * immediately follow their parent (plugins like Gecka Submenu tack nav items onto the
11
+ * end of the items list, regardless of where the parent item lies in the list), the theory
12
+ * being that however WordPress sorts out the hierarchy should be good enough for me!
13
+ */
14
+ class Custom_Menu_Wizard_Sorter extends Walker_Nav_Menu {
15
+
16
+ /**
17
+ * Traverse elements to create list from elements.
18
+ * This cut down version merely grabs the original element into a new array
19
+ *
20
+ * @param object $element Data object.
21
+ * @param array $children_elements List of elements to continue traversing.
22
+ * @param int $max_depth Max depth to traverse.
23
+ * @param int $depth Depth of current element.
24
+ * @param array $args An array of arguments.
25
+ * @param string $output Passed by reference. Used to append additional content.
26
+ */
27
+ public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
28
+
29
+ if ( ! $element ) {
30
+ return;
31
+ }
32
+
33
+ $id_field = $this->db_fields['id'];
34
+ $id = $element->$id_field;
35
+
36
+ if( !is_array( $output ) ){
37
+ $output = array();
38
+ }
39
+ $output[] = $element;
40
+
41
+ // descend only when the depth is right and there are childrens for this element
42
+ if ( ( $max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[ $id ] ) ) {
43
+
44
+ foreach ( $children_elements[ $id ] as $child ){
45
+
46
+ $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
47
+ }
48
+ unset( $children_elements[ $id ] );
49
+ }
50
+
51
+ } //end display()
52
+
53
+ /**
54
+ * Sort array of elements hierarchically.
55
+ *
56
+ * @param array $elements An array of elements.
57
+ * @param int $max_depth The maximum hierarchical depth (default, unlimited).
58
+ * @return array The elements in proper hierarchical order.
59
+ */
60
+ public function walk( $elements, $max_depth = 0 ) {
61
+
62
+ //NB : any orphan elements (and that includes children of orphans) get appended to the
63
+ // output array in the order that they are placed in the original array (ie. regardless
64
+ // of menu_order) BUT *only* if $max_depth is zero! If $max_depth is anything other than
65
+ // zero then all orphans (and their children) are ignored (ie. discarded).
66
+ $output = parent::walk( $elements, $max_depth );
67
+
68
+ //always return an array...
69
+ return is_array( $output ) ? $output : array();
70
+
71
+ } //end walk()
72
+
73
+ } //end Custom_Menu_Wizard_Sorter class
include/class.walker.php CHANGED
@@ -52,16 +52,23 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
52
  * @param integer $max_depth
53
  * @return string
54
  */
55
- public function walk($elements, $max_depth){
56
 
57
- $args = array_slice(func_get_args(), 2);
58
  $args = $args[0];
59
 
60
- if( $max_depth >= -1 && !empty( $elements ) && isset($args->_custom_menu_wizard) ){
 
 
 
 
 
61
 
62
  if( empty( $args->_custom_menu_wizard['cmwv'] ) ){
63
  $elements = $this->_cmw_walk_legacy( $args, $elements );
64
  }else{
 
 
65
  $elements = $this->_cmw_walk( $args, $elements );
66
  }
67
 
@@ -74,12 +81,24 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
74
  $max_depth = -1;
75
  }
76
 
77
- } //ends the check for bad max depth, empty elements, or empty cmw args
78
 
79
  return empty( $elements ) ? '' : parent::walk( apply_filters( 'custom_menu_wizard_walker_items', $elements, $args ), $max_depth, $args );
80
 
81
  } //end walk()
82
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  /**
84
  * current & legacy : finds and returns ID of current menu item while creating the tree and levels arrays
85
  *
@@ -91,6 +110,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
91
  //$elements is an array of objects, indexed by position within the menu (menu_order),
92
  //starting at 1 and incrementing sequentially regardless of parentage (ie. first item is [1],
93
  //second item is [2] whether it's at root or subordinate to first item)
 
94
 
95
  $id_field = $this->db_fields['id']; //eg. = 'db_id'
96
  $parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
@@ -425,7 +445,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
425
  $rtn = $this->_cmw_tree[0]['keepCount'] > 0;
426
  if( $rtn && !empty( $cmw['__exclude'] )){
427
  foreach( $cmw['__exclude'] as $itemID ){
428
- if( $itemID > 0 && isset( $this->_cmw_tree[ $itemID ] ) && $this->_cmw_tree[ $itemID ]['keep'] ){
429
  $this->_cmw_tree[ $itemID ]['keep'] = false;
430
  $this->_cmw_tree[0]['keepCount']--;
431
  }
@@ -565,6 +585,10 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
565
  */
566
  private function _cmw_walk( &$args, $elements ){
567
 
 
 
 
 
568
  $id_field = $this->db_fields['id']; //eg. = 'db_id'
569
  $parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
570
  $unlimited = 65532;
@@ -576,7 +600,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
576
  while( $runCount > 0 ){
577
 
578
  $runCount--;
579
- $topOfBranch = -1;
580
  $continue = true;
581
 
582
  //find the current menu item (ID of the menu item) while creating the tree and levels arrays...
@@ -645,12 +669,12 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
645
  }
646
  //branch...
647
  if( $find_branch ){
648
- //topOfBranch gets set to -1 if it can't be determined...
649
  $topOfBranch = $find_current
650
- ? ( $currentItem === false ? -1 : $currentItem )
651
- : ( isset( $this->_cmw_tree[ $cmw['branch'] ] ) ? $cmw['branch'] : -1 );
652
  $theBranchItem = $topOfBranch;
653
- $continue = $topOfBranch > 0;
654
  }
655
  } //end PRIMARIES
656
 
52
  * @param integer $max_depth
53
  * @return string
54
  */
55
+ public function walk( $elements, $max_depth ){
56
 
57
+ $args = array_slice( func_get_args(), 2 );
58
  $args = $args[0];
59
 
60
+ //v3.2.4 : there's no guarantee the items in $elements will actually be in menu_order order, even
61
+ // though they will probably be indexed as such, which means that reading through using
62
+ // foreach() may process menu_order 14 before menu_order 3 (for example).
63
+ // I'm therefore introducing a pre-sorter, to ensure that the array *is* in the right order!
64
+
65
+ if( $max_depth >= -1 && !empty( $elements ) && isset( $args->_custom_menu_wizard ) ){
66
 
67
  if( empty( $args->_custom_menu_wizard['cmwv'] ) ){
68
  $elements = $this->_cmw_walk_legacy( $args, $elements );
69
  }else{
70
+ //pre-sort $elements...
71
+ usort( $elements, array( &$this, 'cmw_sort_menu_order') );
72
  $elements = $this->_cmw_walk( $args, $elements );
73
  }
74
 
81
  $max_depth = -1;
82
  }
83
 
84
+ }
85
 
86
  return empty( $elements ) ? '' : parent::walk( apply_filters( 'custom_menu_wizard_walker_items', $elements, $args ), $max_depth, $args );
87
 
88
  } //end walk()
89
 
90
+ /**
91
+ * sort by ascending menu_order
92
+ * @param object $a Item
93
+ * @param object $a Item
94
+ * @return integer +/-1
95
+ */
96
+ public static function cmw_sort_menu_order( $a, $b ){
97
+
98
+ return (int) $a->menu_order < (int) $b->menu_order ? -1 : 1;
99
+
100
+ }
101
+
102
  /**
103
  * current & legacy : finds and returns ID of current menu item while creating the tree and levels arrays
104
  *
110
  //$elements is an array of objects, indexed by position within the menu (menu_order),
111
  //starting at 1 and incrementing sequentially regardless of parentage (ie. first item is [1],
112
  //second item is [2] whether it's at root or subordinate to first item)
113
+ //NB : as of v3.2.4, $elements will be zero-based due to pre-sorting to get into menu_order order.
114
 
115
  $id_field = $this->db_fields['id']; //eg. = 'db_id'
116
  $parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
445
  $rtn = $this->_cmw_tree[0]['keepCount'] > 0;
446
  if( $rtn && !empty( $cmw['__exclude'] )){
447
  foreach( $cmw['__exclude'] as $itemID ){
448
+ if( !empty( $itemID ) && isset( $this->_cmw_tree[ $itemID ] ) && $this->_cmw_tree[ $itemID ]['keep'] ){
449
  $this->_cmw_tree[ $itemID ]['keep'] = false;
450
  $this->_cmw_tree[0]['keepCount']--;
451
  }
585
  */
586
  private function _cmw_walk( &$args, $elements ){
587
 
588
+ if( empty( $elements ) ){
589
+ return $elements;
590
+ }
591
+
592
  $id_field = $this->db_fields['id']; //eg. = 'db_id'
593
  $parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
594
  $unlimited = 65532;
600
  while( $runCount > 0 ){
601
 
602
  $runCount--;
603
+ $topOfBranch = false;
604
  $continue = true;
605
 
606
  //find the current menu item (ID of the menu item) while creating the tree and levels arrays...
669
  }
670
  //branch...
671
  if( $find_branch ){
672
+ //topOfBranch gets set to false if it can't be determined...
673
  $topOfBranch = $find_current
674
+ ? $currentItem
675
+ : ( isset( $this->_cmw_tree[ $cmw['branch'] ] ) ? $cmw['branch'] : false );
676
  $theBranchItem = $topOfBranch;
677
+ $continue = $topOfBranch !== false;
678
  }
679
  } //end PRIMARIES
680
 
include/class.widget.php CHANGED
@@ -26,6 +26,8 @@ class Custom_Menu_Wizard_Widget extends WP_Widget {
26
  $this->_cmw_accessibility = isset( $_GET['editwidget'] ) && $_GET['editwidget'];
27
  $this->_cmw_hash_ct = 0;
28
 
 
 
29
  } //end __construct()
30
 
31
  /**
@@ -1159,20 +1161,17 @@ class Custom_Menu_Wizard_Widget extends WP_Widget {
1159
  if( !empty( $menus ) ){
1160
  foreach( $menus as $i => $menu ){
1161
  //find the menu's items, then remove any menus that have no items...
1162
- $menus[ $i ]->_items = wp_get_nav_menu_items( $menu->term_id );
 
 
 
 
 
 
1163
  if( empty( $menus[ $i ]->_items ) ){
1164
  unset( $menus[ $i ] );
1165
- }else{
1166
- //if the items are all orphans, then remove the menu...
1167
- $rootItem = false;
1168
- foreach( $menus[ $i ]->_items as $item ){
1169
- $rootItem = $rootItem || $item->menu_item_parent == 0;
1170
- }
1171
- if( !$rootItem ){
1172
- unset( $menus[ $i ] );
1173
- }elseif( $findSM && $selectedMenu == $menu->term_id ){
1174
- $findSM = false;
1175
- }
1176
  }
1177
  }
1178
  }
@@ -1228,7 +1227,7 @@ class Custom_Menu_Wizard_Widget extends WP_Widget {
1228
  //don't need to check for existence of items because if there were none then the menu wouldn't be here!
1229
  foreach( $menu->_items as $item ){
1230
  //exclude orphans!
1231
- if( isset($itemindents[ $item->menu_item_parent ])){
1232
  $title = $item->title;
1233
  $level = $itemindents[ $item->menu_item_parent ] + 1;
1234
 
@@ -1405,7 +1404,7 @@ class Custom_Menu_Wizard_Widget extends WP_Widget {
1405
  'ancestors' => -9999, //v3.0.0 replaces include_ancestors, but with levels (relative & absolute)
1406
  'ancestor_siblings' => -9999, //v3.0.0 also has levels (relative & absolute)
1407
  'depth' => 0,
1408
- 'branch' => 0, //v3.0.0 replaces filter_item, but without current parent|root item
1409
  'menu' => 0,
1410
  'level' => 1, //v3.0.0 replace start_level (for a level filter)
1411
  'fallback_depth' => 0 //v3.0.0 added
@@ -1472,10 +1471,10 @@ class Custom_Menu_Wizard_Widget extends WP_Widget {
1472
  $instance[ "_$k" ] = array();
1473
  $instance[ $k ] = isset( $from_instance[ $k ] ) ? trim( (string)$from_instance[ $k ] ) : $v;
1474
  foreach( preg_split('/[,\s]+/', $instance[ $k ], -1, PREG_SPLIT_NO_EMPTY ) as $i ){
1475
- //values can be just digits, or digits followed by a '+' (for inheritance)...
1476
- if( preg_match( '/^(\d+)(\+?)$/', $i, $m ) > 0 ){
1477
  $i = intval( $m[1] );
1478
- if( $i > 0 ){
1479
  if( !empty( $m[2] ) ){
1480
  $inherits[] = $i;
1481
  $i = $i . '+';
@@ -1560,7 +1559,7 @@ class Custom_Menu_Wizard_Widget extends WP_Widget {
1560
  //specifying branch sets byBranch, overriding byLevel...
1561
  if( $byBranch ){
1562
  //use the alternative for 0 ("current") because it's more self-explanatory...
1563
- $args['branch'] = $instance['branch'] > 0 ? $instance['branch'] : 'current';
1564
  //start_at only *has* to be specified if not empty...
1565
  if( !empty( $instance['branch_start'] ) ){
1566
  $args['start_at'] = array( $instance['branch_start'] );
26
  $this->_cmw_accessibility = isset( $_GET['editwidget'] ) && $_GET['editwidget'];
27
  $this->_cmw_hash_ct = 0;
28
 
29
+ $this->_cmw_hierarchy = new Custom_Menu_Wizard_Sorter();
30
+
31
  } //end __construct()
32
 
33
  /**
1161
  if( !empty( $menus ) ){
1162
  foreach( $menus as $i => $menu ){
1163
  //find the menu's items, then remove any menus that have no items...
1164
+ //note : sending a huge number through to the sorter should prevent orphans being
1165
+ // appended to the returned array.
1166
+ // but also note that if the entire menu is orphans, the sorter will appoint
1167
+ // the first item in $elements as "root"!
1168
+ //no longer need to check for all orphans (no root) because the hierarchy sort
1169
+ //will create one if there weren't any before!
1170
+ $menus[ $i ]->_items = $this->_cmw_hierarchy->walk( wp_get_nav_menu_items( $menu->term_id ), 65532 );
1171
  if( empty( $menus[ $i ]->_items ) ){
1172
  unset( $menus[ $i ] );
1173
+ }elseif( $findSM && $selectedMenu == $menu->term_id ){
1174
+ $findSM = false;
 
 
 
 
 
 
 
 
 
1175
  }
1176
  }
1177
  }
1227
  //don't need to check for existence of items because if there were none then the menu wouldn't be here!
1228
  foreach( $menu->_items as $item ){
1229
  //exclude orphans!
1230
+ if( isset( $itemindents[ $item->menu_item_parent ] ) ){
1231
  $title = $item->title;
1232
  $level = $itemindents[ $item->menu_item_parent ] + 1;
1233
 
1404
  'ancestors' => -9999, //v3.0.0 replaces include_ancestors, but with levels (relative & absolute)
1405
  'ancestor_siblings' => -9999, //v3.0.0 also has levels (relative & absolute)
1406
  'depth' => 0,
1407
+ 'branch' => -999999, //v3.0.0 replaces filter_item, but without current parent|root item, v3.2.4 allows negative
1408
  'menu' => 0,
1409
  'level' => 1, //v3.0.0 replace start_level (for a level filter)
1410
  'fallback_depth' => 0 //v3.0.0 added
1471
  $instance[ "_$k" ] = array();
1472
  $instance[ $k ] = isset( $from_instance[ $k ] ) ? trim( (string)$from_instance[ $k ] ) : $v;
1473
  foreach( preg_split('/[,\s]+/', $instance[ $k ], -1, PREG_SPLIT_NO_EMPTY ) as $i ){
1474
+ //values can be just digits (maybe with leading '-'), or digits followed by a '+' (for inheritance)...
1475
+ if( preg_match( '/^(-?\d+)(\+?)$/', $i, $m ) > 0 ){
1476
  $i = intval( $m[1] );
1477
+ if( $i != 0 ){
1478
  if( !empty( $m[2] ) ){
1479
  $inherits[] = $i;
1480
  $i = $i . '+';
1559
  //specifying branch sets byBranch, overriding byLevel...
1560
  if( $byBranch ){
1561
  //use the alternative for 0 ("current") because it's more self-explanatory...
1562
+ $args['branch'] = $instance['branch'] == 0 ? 'current' : $instance['branch'];
1563
  //start_at only *has* to be specified if not empty...
1564
  if( !empty( $instance['branch_start'] ) ){
1565
  $args['start_at'] = array( $instance['branch_start'] );
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: menu,widget,navigation,custom menu,partial menu,current item,current page,menu level,menu branch,menu shortcode,menu widget,advanced,enhanced
5
  Requires at least: 3.6
6
  Tested up to: 4.4
7
- Stable tag: 3.2.3
8
  License: GPLv2 or Later
9
 
10
  Show branches or levels of your menu in a widget, or in content using a shortcode, with full customisation.
@@ -769,7 +769,7 @@ If you have a question or problem that is not covered here, please use the [Supp
769
  = Are there any known problems/restrictions? =
770
  Yep, 'fraid so :
771
 
772
- 1. The widget will only recognise one "current" item (prior to v2.0.2 it was the last one found; as of v2.0.2, it's the first one encountered, but v3.1.5 add a switch that lets you opt for the last one found). It is perfectly possible to have more than one menu item marked as "current", but if CMW has been configured to filter on anything related to a "current menu item" it can only choose one. The simplest example of multiple "current" items is if you add the same page to a menu more than once, but any other plugin that adds and/or manipulates menu items could potentially cause problems for CMW.
773
  2. The widget's "assist" uses jQuery UI's Dialog, which unfortunately (in versions 1.10.3/4) has a *really* annoying bug in its handling of a draggable (ie. when you drag the Dialog's title bar to reposition it on the page) when the page has been scrolled. It is due to be fixed in UI v1.11.0, but meantime I have defaulted the Dialog to fixed position, with an option to toggle back to absolute : it's not perfect but it's the best compromise I can come up with to maintain some sort of useability.
774
 
775
  = Why isn't it working? Why is there no output? =
@@ -782,6 +782,73 @@ infallible (and it's been proven a fair few times!), so if you still have proble
782
  Please note that simply reporting "It doesn't work" is not
783
  the most useful of feedbacks, and is unlikely to get a response other than, possibly, a request for more details.
784
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
785
  = How do I use the "assist"? =
786
  The widget's interactive "assist" is specific to each widget instance. It is a javascript-driven *emulator* that uses the widget instance's
787
  option settings - including the menu selected - to build a pictorial representation of the menu and show you, in blue, which menu items will
@@ -821,7 +888,7 @@ attribute, so should be seen when the cursor is moved over the item. A simpler w
821
  then show a green tick "checkbox" to the right of each menu item and you simply [un]check the items as required. Each selection will be reflected back into the
822
  widget's `Items` settings, and also in the shortcode texts.
823
 
824
- The more painstaking way is to go to Appearance, Menus and select the relevant menu; hover over the *edit*, *Remove*, or *Cancel* link for an item and look in
825
  the URL (the link's href) for `menu-item=NNN` ... the NNN is the menu item id.
826
 
827
  = How do I get the menu item ids for the 'Exclude Ids' option? =
@@ -837,16 +904,34 @@ with `Starting at` set to "the Branch" (ie. Bravo). If you switch from "Item" to
837
  will become eligible for filtering. If you left "Item" enabled, and switched on the inclusion of Branch Siblings, then Bravo and Charlie
838
  would both still be eligible, but only *Bravo's descendants* would be; not Charlie's!
839
 
840
- = Where is the styling of the output coming from, and how do I change it? =
841
- The widget does not supply any ouput styling (at all!). This is because I have absolutely no idea where you are going to place either the
842
- widget (sidebar, footer, header, ad-hoc, etc?) or the shortcode (page content, post content, widget content, custom field, etc?) and everyone's
843
- requirements for styling are likely to be different ... possibly even within the same web page's output. So all styling is down to your theme,
844
- and if you wish to modify it you will need to add to your theme's stylesheet.
845
-
846
- The safest way to do this is via a child theme, so that any changes you make will not be lost if/when the main theme gets updated. The best
847
- way to test your changes is by utilising the developer capabilities that are available in most modern browsers (personally, I could not
848
- do without Firefox and the Firebug extension!) and dynamically applying/modifying styles, possibly utilising the custom classes that the
849
- widget applies to its output, or the Container options for a user-defined id or class.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
850
 
851
  = How can I find all my posts/pages that have a CMW shortcode so that I can upgrade them? =
852
  There is a button on the widget's "assist" - `[...]` - that will provide a list of posts/pages whose content, or meta data (custom fields),
@@ -876,6 +961,10 @@ because Version 2 will **not** be supported beyond Version 3.
876
 
877
  == Changelog ==
878
 
 
 
 
 
879
  = 3.2.3 =
880
  * tweak : minor updates to documentation, and verified for WordPress v4.4
881
 
@@ -1035,6 +1124,10 @@ because Version 2 will **not** be supported beyond Version 3.
1035
 
1036
  == Upgrade Notice ==
1037
 
 
 
 
 
1038
  = 3.2.3 =
1039
  Tweaked documentation and verified for WordPress v4.4
1040
 
4
  Tags: menu,widget,navigation,custom menu,partial menu,current item,current page,menu level,menu branch,menu shortcode,menu widget,advanced,enhanced
5
  Requires at least: 3.6
6
  Tested up to: 4.4
7
+ Stable tag: 3.2.4
8
  License: GPLv2 or Later
9
 
10
  Show branches or levels of your menu in a widget, or in content using a shortcode, with full customisation.
769
  = Are there any known problems/restrictions? =
770
  Yep, 'fraid so :
771
 
772
+ 1. The widget will only recognise one "current" item (prior to v2.0.2 it was the last one found; as of v2.0.2, it's the first one encountered, but v3.1.5 adds a switch that lets you opt for the last one found). It is perfectly possible to have more than one menu item marked as "current", but if CMW has been configured to filter on anything related to a "current menu item" it can only choose one. The simplest example of multiple "current" items is if you add the same page to a menu more than once, but any other plugin that adds and/or manipulates menu items could potentially cause problems for CMW.
773
  2. The widget's "assist" uses jQuery UI's Dialog, which unfortunately (in versions 1.10.3/4) has a *really* annoying bug in its handling of a draggable (ie. when you drag the Dialog's title bar to reposition it on the page) when the page has been scrolled. It is due to be fixed in UI v1.11.0, but meantime I have defaulted the Dialog to fixed position, with an option to toggle back to absolute : it's not perfect but it's the best compromise I can come up with to maintain some sort of useability.
774
 
775
  = Why isn't it working? Why is there no output? =
782
  Please note that simply reporting "It doesn't work" is not
783
  the most useful of feedbacks, and is unlikely to get a response other than, possibly, a request for more details.
784
 
785
+ I should also point out that any other plugin can change any menu, at any time, either before or after this widget does it stuff (even
786
+ prevent it running at all!), so it's possible that the problem lies somewhere other than CMW.
787
+
788
+ = Where is the styling of the output coming from, and how do I change it? =
789
+ The widget does not supply any output styling (at all!). This is because I have absolutely no idea where you are going to place either the
790
+ widget (sidebar, footer, header, ad-hoc, etc?) or the shortcode (page content, post content, widget content, custom field, etc?) and everyone's
791
+ requirements for styling are likely to be different ... possibly even within the same web page's output. So, all styling is down to your theme,
792
+ and if you wish to modify it you will need to add to (or modify) your theme's stylesheet.
793
+
794
+ The safest way to do this is via a [child theme](https://codex.wordpress.org/Child_Themes), so that any
795
+ changes you make will not be lost if/when the main theme gets updated.
796
+ The best way to test your changes is by utilising the developer capabilities that are available in most
797
+ modern browsers (personally, I could not do without Firefox and the Firebug extension!) and dynamically
798
+ applying/modifying styles, possibly utilising the custom classes that the
799
+ widget applies to its output, or the Container options for a user-defined id or class.
800
+
801
+ = Why is there no (or, How do I get...) indentation on my hierarchical menu? =
802
+ Firstly, see the answer above, re: styling of the output.
803
+
804
+ Any output styling comes from your theme (or possibly some other plugin, but definitely *not* CMW).
805
+
806
+ If other nested lists are displayed with indentation then it is likely (but not guaranteed) that there is a
807
+ class that can be applied to the CMW output that may result in the desired effect. It is always worth
808
+ checking out WordPress's own Nav Menu widget, on a menu that has sub-menus : if that has indentation then
809
+ check the classes *it* has and try them on CMW (assuming that they're not already there!). If it doesn't
810
+ have indentation then you're probably going to have to add your own styled class(es) to your theme, and
811
+ then apply them to CMW.
812
+
813
+ Note that quite a few themes "reset/standardise the CSS", by removing all
814
+ padding and margins from lists : trouble is, some of them don't then provide any means for indenting
815
+ nested lists.
816
+ Also, please be aware that any CSS rules that *are* provided *may* be location-specific.
817
+ So, for example, a class may indent nested lists when they are in a sidebar widget area, but not when
818
+ they're in a footer widget area or inserted within content (using a shortcode).
819
+
820
+ Purely as an example, [re-]applying indentation to nested unorder lists (ULs) could be as fundamental as ...
821
+
822
+ `ul ul { margin-left: 1em; }`
823
+
824
+ ...however, I have found that things a generally never that straightforward, particularly when menus with
825
+ links in them are involved, so I'm afraid you might to have to experiment a bit.
826
+
827
+ = How can I create a horizontal menu? =
828
+ Firstly, see the answer above, re: styling of the output.
829
+
830
+ Any output styling comes from your theme (or possibly some other plugin, but definitely *not* CMW).
831
+
832
+ If you simply want all the menu items to flow horizontally across the page then you could start with
833
+ something along the lines of...
834
+
835
+ `.menu-widget {
836
+ list-style-type: none;
837
+ margin: 0;
838
+ padding: 0;
839
+ }
840
+ .menu-widget li {
841
+ display: inline-block;
842
+ margin: 0 2em 0 0;
843
+ }`
844
+
845
+ This is purely an *example*.
846
+
847
+ I've used a class : you may want to change/add to the class, or swap it for an id.
848
+ There are a number of other ways to do it - especially if you have multiple levels, or you want vertical
849
+ sub-menus, and/or any sort of interaction. You may want to bring in a jQuery script, or another WordPress
850
+ plugin, to handle it for you, assuming that your theme doesn't already provide the functionality you need.
851
+
852
  = How do I use the "assist"? =
853
  The widget's interactive "assist" is specific to each widget instance. It is a javascript-driven *emulator* that uses the widget instance's
854
  option settings - including the menu selected - to build a pictorial representation of the menu and show you, in blue, which menu items will
888
  then show a green tick "checkbox" to the right of each menu item and you simply [un]check the items as required. Each selection will be reflected back into the
889
  widget's `Items` settings, and also in the shortcode texts.
890
 
891
+ The more painstaking way is to go to Appearance, Menus and select the relevant menu; hover over one of the *edit*, *Remove*, or *Cancel* links for an item and look in
892
  the URL (the link's href) for `menu-item=NNN` ... the NNN is the menu item id.
893
 
894
  = How do I get the menu item ids for the 'Exclude Ids' option? =
904
  will become eligible for filtering. If you left "Item" enabled, and switched on the inclusion of Branch Siblings, then Bravo and Charlie
905
  would both still be eligible, but only *Bravo's descendants* would be; not Charlie's!
906
 
907
+ = Can CMW handle menus that have items dynamically added by other plugins? =
908
+ Ummm ... Maybe.
909
+
910
+ Unfortunately, I can't answer this with a definitive Yes or No. By definition, if something is "dynamic" then
911
+ it is likely to change. If the plugin that creates those dynamic items does its job correctly then the items
912
+ added should have unique ids, *at least within the context of the menu being manipulated*. Also, those items
913
+ will probably have been set up with a menu_order property that places them appropriately within the menu
914
+ structure, and the existing menu items will have been modified accordingly. If that is the case then CMW will
915
+ be able to process them in the right order & structure.
916
+
917
+ **However**, there is a big caveat here : CMW stores item ids wherever a specific item is targeted - such
918
+ as `Branch=Page One`, or `Items=1,3,5`, or `Exclusions=2,4,6+`, etc. If any one of those ids relates
919
+ to a dynamically-generated item at the time the widget (or shortcode) is configured, then it is possible that
920
+ the id may get assigned to a different item, or may not even exist, when it comes to displaying the
921
+ menu.
922
+
923
+ As a contrived example, let's say that posts Alpha, Charlie and Echo are dynamically added to a menu, and you
924
+ can see them when you configure the CMW widget. You decide to Exclude post Charlie, so you configure and save the widget accordingly.
925
+ Then someone adds or changes post Beta such that *it* now qualifies for dynamic inclusion into the menu - so, the
926
+ menu should now contain posts Alpha, Beta, Charlie and Echo. Unfortunately, the ids get re-assigned by the
927
+ plugin doing the dynamic insertion, and Beta now has the id that Charlie was given when you configured CMW, so
928
+ Beta gets filtered out and Alpha, Charlie and Echo get shown!
929
+
930
+ So, my advice would be : If you use CMW with a menu that you *know* contains dynamically-degenerated items,
931
+ try to avoid specifically targeting any of those items in the configuration. For example,
932
+ setting `Branch=Current Item` is fine, but don't set `Branch=A Dynamic Item`; and avoid including or excluding
933
+ specific dynamic items, use a parent item that exists in the menu instead. If you can do that then there
934
+ should be no problem.
935
 
936
  = How can I find all my posts/pages that have a CMW shortcode so that I can upgrade them? =
937
  There is a button on the widget's "assist" - `[...]` - that will provide a list of posts/pages whose content, or meta data (custom fields),
961
 
962
  == Changelog ==
963
 
964
+ = 3.2.4 =
965
+ * bugfix : improve handling of dynamically-generated items, by pre-sorting into menu_order order and coping with negative item ids
966
+ * documentation : updated FAQs
967
+
968
  = 3.2.3 =
969
  * tweak : minor updates to documentation, and verified for WordPress v4.4
970
 
1124
 
1125
  == Upgrade Notice ==
1126
 
1127
+ = 3.2.4 =
1128
+ Fix to improve handling of dynamically-generated items that have negative item ids, and that get appended to the list of items.
1129
+ Updated FAQs documentation.
1130
+
1131
  = 3.2.3 =
1132
  Tweaked documentation and verified for WordPress v4.4
1133