Version Description
! Possible Breaker ! The calculation of
Start Level
has been made consistent across theShow all
andChildren of
filters : if you previously had a setup where you were filtering for the children of an item at level 2, with start level set to 4, there would have been no output because the immediate children (at level 3) were outside the start level. Now, there will be output, starting with the grand-children (at level 4).! Possible Breaker ! There is now deemed to be an artificial "root" item above the level 1 items, which mean that a
Children of
filter set to "Current Parent Item" or "Current Root Item" will no longer fail for a top-level "current menu item". If you have the "no ancestor" fallback set then this change will have no impact (but you may now want to consider turning the fallback off?); if you don't currently use the "no ancestor" fallback, then where there was previously no output there will now be some!added new option : Items, a comma- or space-delimited list of menu item ids, as an alternative Filter
added new option : Depth Relative to Current Item to the Filter section (depth_rel_current=1 in the shortcode)
added new option : Must Contain Current Item to the Output section (contains_current=1 in the shortcode)
changed the widget's "demo" facility to "assist" and brought it into WordPress admin, with full interactivity with the widget
refactored code
Release Info
Developer | wizzud |
Plugin | Custom Menu Wizard Widget |
Version | 2.0.0 |
Comparing to | |
See all releases |
Code changes from version 1.2.2 to 2.0.0
- custom-menu-wizard.css +56 -0
- custom-menu-wizard.js +558 -27
- custom-menu-wizard.min.js +28 -0
- custom-menu-wizard.php +522 -258
- demo.html +0 -592
- readme.txt +142 -26
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* custom-menu-wizard.css
|
3 |
+
* Version: 2.0.0
|
4 |
+
*/
|
5 |
+
/*widget admin style...*/
|
6 |
+
/*NB .widget-content class is not present in accessibility mode*/
|
7 |
+
.js .widget-content .widget-custom-menu-wizard-onchange .cmw-start-fieldset-collapsed {display:none;}
|
8 |
+
.widget-custom-menu-wizard-onchange .cmw-colour-grey {color:#999999;}
|
9 |
+
.widget-custom-menu-wizard-onchange .cmw-pad-left-1 {padding-left:1em;}
|
10 |
+
.widget-custom-menu-wizard-onchange .cmw-off-the-page {display:none; position:absolute; left:-5000px; top:-5000px;}
|
11 |
+
.widget-custom-menu-wizard-onchange .cmw-toggle-assist {float:right; line-height:1; margin-left:1em;}
|
12 |
+
.widget-custom-menu-wizard-collapsible-fieldset {margin:0 0 0.5em; cursor:pointer;}
|
13 |
+
.widget-custom-menu-wizard-collapsible-fieldset h3 {font-size:1em; margin:0; padding:2px 0.5em;}
|
14 |
+
.widget-custom-menu-wizard-collapsible-fieldset div {background-color:#transparent; background-repeat:no-repeat; background-position:0 -36px; height:16px; width:16px; float:right; outline:0 none;}
|
15 |
+
.js .widget-content .widget-custom-menu-wizard-collapsible-fieldset div.cmw-collapsed-fieldset {background-position:0 0;}
|
16 |
+
.widget-custom-menu-wizard-disableifnot-rp, .widget-custom-menu-wizard-disableifnot-ci {line-height:1.3333;}
|
17 |
+
.widget-custom-menu-wizard-childrenof optgroup option {padding-left:0.75em;}
|
18 |
+
select.widget-custom-menu-wizard-listen {max-width:100%;}
|
19 |
+
/*dialog style...*/
|
20 |
+
/*...menu...*/
|
21 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu {margin:0; font-size:0.8333em;}
|
22 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu ul {font-size:10px; list-style-type:none; margin:0.5em 0; padding:0;}
|
23 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu ul ul {margin:0 0 0 5em;}
|
24 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu li {display:block; margin:0; padding:0;}
|
25 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu a {display:inline-block; text-align:center; padding:3px 4px; margin:2px; color:#333333; text-decoration:none;}
|
26 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu a:focus {outline:0 none;}
|
27 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu input {vertical-align:top; visibility:hidden}
|
28 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu ul span {display:block; width:10em; padding:0 2px; height:1.75em; line-height:1.75; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; border:1px solid #999999; box-shadow:2px 2px 2px 0px #666666;}
|
29 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu .current-menu-ancestor {border-color:#cccc00 !important; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 153, 1)), to(rgba(255, 255, 153, 0.1))); background-image:-webkit-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:-moz-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:-ms-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:-o-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:linear-gradient(to bottom, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff99, endColorstr=#1affff99); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff99, endColorstr=#1affff99)";}
|
30 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu .current-menu-item {border-color:#cc0000 !important; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 204, 204, 1)), to(rgba(255, 204, 204, 0.1))); background-image:-webkit-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:-moz-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:-ms-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:-o-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:linear-gradient(to bottom, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcccc, endColorstr=#1affcccc); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcccc, endColorstr=#1affcccc)";}
|
31 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu .current-menu-parent {border-color:#ff9900 !important; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 204, 153, 1)), to(rgba(255, 204, 153, 0.1))); background-image:-webkit-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:-moz-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:-ms-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:-o-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:linear-gradient(to bottom, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcc99, endColorstr=#1affcc99); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcc99, endColorstr=#1affcc99)";}
|
32 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-themenu .picked > a {background-color:#333366; color:#ffffff; font-weight:bold;}
|
33 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-filteritems input {visibility:visible}
|
34 |
+
/*...shortcode...*/
|
35 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theshortcode {clear:both; width:100%; margin:1em 0 0.5em;}
|
36 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theshortcode code {border:1px solid #CCCCCC; display:inline-block; line-height:1.5; padding:0.25em 0.5em;}
|
37 |
+
/*...output...*/
|
38 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput {float:right; margin:0 0 1em 2em; font-size:0.8333em;}
|
39 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput h3 {border-bottom:1px solid #CCCCCC; margin:0 0 0.25em; padding: 0.5em 0 0.25em;}
|
40 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap {margin:0.5em 0; padding:0 1em; border:1px solid #cccccc; min-height:2em; min-width:9em;}
|
41 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ul, .widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ol {margin:0.5em 0 0.5em 1.5em; padding:0;}
|
42 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap li {margin:0;}
|
43 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap li ul {margin:0 0 0 1em;}
|
44 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap li ol {margin:0 0 0 1.5em;}
|
45 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ul {list-style-type:disc;}
|
46 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ul ul {list-style-type:circle;}
|
47 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ul ul ul {list-style-type:square;}
|
48 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ul ul ul ul {list-style-type:disc;}
|
49 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ul ul ul ul ul {list-style-type:circle;}
|
50 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ol {list-style-type:decimal;}
|
51 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ol ol {list-style-type:upper-alpha;}
|
52 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ol ol ol {list-style-type:lower-alpha;}
|
53 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ol ol ol ol {list-style-type:lower-roman;}
|
54 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-theoutput-wrap ol ol ol ol ol {list-style-type:decimal;}
|
55 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-fallback {display:none; text-align:right; color:#006600;}
|
56 |
+
.widget-custom-menu-wizard-dialog .cmw-demo-fallback.cmw-demo-fellback {display:block;}
|
@@ -1,34 +1,528 @@
|
|
1 |
/* Plugin Name: Custom Menu Wizard
|
2 |
-
* Version:
|
3 |
* Author: Roger Barrett
|
4 |
*
|
5 |
* Script for controlling this widget's options (in Admin -> Widgets)
|
6 |
*/
|
|
|
|
|
7 |
jQuery(function($){
|
8 |
-
var dotPrefix = '.widget-custom-menu-wizard'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
$(document)
|
10 |
//fieldsets...
|
11 |
.on('click', dotPrefix + '-collapsible-fieldset', function(){
|
12 |
-
var
|
|
|
13 |
collapse = !chkbox.prop('checked');
|
14 |
if(chkbox.length){
|
15 |
chkbox.prop('checked', collapse);
|
16 |
-
|
17 |
-
|
18 |
}
|
19 |
this.blur();
|
20 |
return false;
|
21 |
})
|
22 |
//change of menu, and enableif / disableif...
|
23 |
.on('change', dotPrefix + '-listen', function(){
|
24 |
-
var
|
25 |
-
selectMenu =
|
26 |
-
|
27 |
-
|
28 |
-
filterItem =
|
29 |
fiVal = parseInt(filterItem.val(), 10),
|
30 |
groupClone;
|
31 |
if(selectMenu.is(this)){
|
|
|
32 |
selectMenu = this.selectedIndex;
|
33 |
if(!filterItem.find('optgroup').filter(function(){
|
34 |
var keep = $(this).data('cmwOptgroupIndex') === selectMenu;
|
@@ -49,28 +543,65 @@ jQuery(function($){
|
|
49 |
}
|
50 |
}
|
51 |
$.each(
|
52 |
-
{ '' : showAll,
|
53 |
-
'
|
54 |
-
'not-
|
|
|
55 |
},
|
56 |
function(k, v){
|
57 |
-
$(dotPrefix + '-disableif' + k, this.form).
|
58 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
});
|
60 |
|
61 |
-
//when a widget is opened or saved, trigger change on the filter_item select
|
62 |
-
//
|
63 |
-
//
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}else{
|
75 |
//one-off fallback...
|
76 |
$(dotPrefix + '-selectmenu').trigger('change');
|
1 |
/* Plugin Name: Custom Menu Wizard
|
2 |
+
* Version: 2.0.0
|
3 |
* Author: Roger Barrett
|
4 |
*
|
5 |
* Script for controlling this widget's options (in Admin -> Widgets)
|
6 |
*/
|
7 |
+
/*global jQuery, window, document */
|
8 |
+
/*jslint forin: true, nomen: true, plusplus: true, regexp: true, unparam: true, sloppy: true, white: true */
|
9 |
jQuery(function($){
|
10 |
+
var dotPrefix = '.widget-custom-menu-wizard',
|
11 |
+
assist = {
|
12 |
+
/**
|
13 |
+
* gets a widget form's dialog element as a jQuery object
|
14 |
+
* @param {Object} fm jQuery of the widget form
|
15 |
+
* @return (Object) jQuery of the dialog element
|
16 |
+
*/
|
17 |
+
getDialog : function(fm){
|
18 |
+
return $( '#' + fm.find(dotPrefix + '-onchange').data().cmwDialogId );
|
19 |
+
},
|
20 |
+
/**
|
21 |
+
* gets the widget form's values
|
22 |
+
* @param {Object} fm jQuery of the widget form
|
23 |
+
* @return {Object} key=>value pairs of the form element values
|
24 |
+
*/
|
25 |
+
getSettings : function(fm){
|
26 |
+
var settings = {};
|
27 |
+
$.each(fm.serializeArray(), function(i, v){
|
28 |
+
var name = v.name.replace(/.*\[([^\]]+)\]$/, '$1'),
|
29 |
+
val = name !== 'items' && /^-?\d+$/.test(v.value) ? parseInt(v.value, 10) : v.value;
|
30 |
+
settings[name] = val;
|
31 |
+
if(name === 'items'){
|
32 |
+
settings._items_sep = !val || /(^\d+$|,)/.test($.trim(val)) ? ',' : ' ';
|
33 |
+
val = $.map(val.split(/[,\s]+/), function(x){
|
34 |
+
x = x ? parseInt(x, 10) : 0;
|
35 |
+
return isNaN(x) || x < 1 ? null : x;
|
36 |
+
});
|
37 |
+
settings._items = val.join(settings._items_sep);
|
38 |
+
}
|
39 |
+
});
|
40 |
+
return settings;
|
41 |
+
},
|
42 |
+
/**
|
43 |
+
* recursively build LI items for the menu structure (kicked off by createMenu())
|
44 |
+
* @param {Object} items Set of menu items with same parent
|
45 |
+
* @param {integer} level Level of parent within the structure (1-based)
|
46 |
+
* @return {string} HTML
|
47 |
+
*/
|
48 |
+
buildRecurse : function(items, level, trace){
|
49 |
+
var rtn = '', n, i;
|
50 |
+
level = (level || 0) + 1;
|
51 |
+
trace = trace || '';
|
52 |
+
for(n in items){
|
53 |
+
i = n.split('|')[0];
|
54 |
+
rtn += '<li class="level-' + level + '" data-itemid="' + i + '" data-level="' + level + '" data-trace="' + trace + '">';
|
55 |
+
rtn += '<a class="ui-corner-all" href="#"><span class="ui-corner-all" title="#' + i + '">' + n.replace(/^\d+\|/, '');
|
56 |
+
rtn += '</span></a><input type="checkbox" value="' + i + '" />';
|
57 |
+
if(items[n]){
|
58 |
+
rtn += '<ul>' + assist.buildRecurse(items[n], level, i + (trace ? ',' : '') + trace) + '</ul>';
|
59 |
+
}
|
60 |
+
rtn += '</li>';
|
61 |
+
}
|
62 |
+
return rtn;
|
63 |
+
},
|
64 |
+
/**
|
65 |
+
* change handler for an item's checkbox in the menu structure
|
66 |
+
* @this {Element} Input checkbox element
|
67 |
+
* @param {Object} e Event object
|
68 |
+
*/
|
69 |
+
changeMenu : function(e){
|
70 |
+
var self = $(this),
|
71 |
+
itemsField = $(self.closest('.ui-dialog-content').data().cmwTriggerChange).closest('form').find(dotPrefix + '-setitems'),
|
72 |
+
currVal = $.trim(itemsField.val()),
|
73 |
+
sep = !currVal || /(^\d+$|,)/.test(currVal) ? ',' : ' ';
|
74 |
+
itemsField.val(
|
75 |
+
self.closest('.cmw-demo-themenu').find('input').map(function(){
|
76 |
+
return this.checked ? this.value : null;
|
77 |
+
}).get().join(sep)
|
78 |
+
).trigger('change');
|
79 |
+
},
|
80 |
+
/**
|
81 |
+
* click handler for an item in the menu structure : sets or clears current menu item and its ancestors
|
82 |
+
* @this {Element} Anchor element clicked on
|
83 |
+
* @param {Object} e Event object
|
84 |
+
* @return {boolean} false
|
85 |
+
*/
|
86 |
+
clickMenu : function(e){
|
87 |
+
var self = $(this),
|
88 |
+
cls = ['current-menu-item', 'current-menu-parent', 'current-menu-ancestor'],
|
89 |
+
dialog = self.closest('.ui-dialog-content'),
|
90 |
+
themenu = dialog.find('.cmw-demo-themenu'),
|
91 |
+
inPath = self.find('span').not('.' + cls[0]).parentsUntil(themenu, 'li'),
|
92 |
+
i, n,
|
93 |
+
appendCls = function(){
|
94 |
+
this.title = this.title + ' ' + n.replace(' ', ' & ').replace(/-/g, ' ');
|
95 |
+
};
|
96 |
+
themenu.find('.' + cls.join(',.')).removeClass(cls.join(' ')).each(function(){
|
97 |
+
this.title = this.title.replace(/\s.*$/, '');
|
98 |
+
});
|
99 |
+
for(i = 0; i < inPath.length; i++){
|
100 |
+
n = i === 1 ? cls.join(' ') : cls[0];
|
101 |
+
inPath.eq(i).children('a').find('span').addClass(n).each(appendCls);
|
102 |
+
if(cls.length > 1){
|
103 |
+
cls.shift();
|
104 |
+
}
|
105 |
+
}
|
106 |
+
//trigger a change in the widget form, causing update() to be run...
|
107 |
+
$( dialog.data().cmwTriggerChange ).trigger('change');
|
108 |
+
return false;
|
109 |
+
},
|
110 |
+
/**
|
111 |
+
* click handler for an item in the Basic Output list : triggers a click on the respective menu structure item
|
112 |
+
* @this {Element} Anchor element clicked on
|
113 |
+
* @param {Object} e Event object
|
114 |
+
* @return {boolean} false
|
115 |
+
*/
|
116 |
+
clickOutput : function(e){
|
117 |
+
var indx = this.href.split('#')[1];
|
118 |
+
$(this).closest('.ui-dialog-content').find('.cmw-demo-themenu a').eq(indx).not(':has(.current-menu-item)').trigger('click');
|
119 |
+
this.blur();
|
120 |
+
return false;
|
121 |
+
},
|
122 |
+
/**
|
123 |
+
* creates a new list of menu items and inserts it into the dialog content in place of any previous one
|
124 |
+
* @param {Object} dialog jQuery object of the dialog
|
125 |
+
* @param {Object} fm jQuery object of the widget form
|
126 |
+
*/
|
127 |
+
createMenu : function(dialog, fm){
|
128 |
+
var data = dialog.data(),
|
129 |
+
themenu = dialog.find('.cmw-demo-themenu'),
|
130 |
+
selectmenu = fm.find(dotPrefix + '-selectmenu'),
|
131 |
+
menuid = parseInt(selectmenu.val(), 10),
|
132 |
+
currentmenu = themenu.find('ul').eq(0),
|
133 |
+
mdata = themenu.data(),
|
134 |
+
menu;
|
135 |
+
if(!currentmenu.length || currentmenu.data('menuid') !== menuid){
|
136 |
+
menu = $('<ul>' + assist.buildRecurse( fm.find(dotPrefix + '-childrenof optgroup').data().cmwItems || {} ) + '</ul>');
|
137 |
+
currentmenu.remove();
|
138 |
+
dialog.dialog('option', 'title', data.cmwTitlePrefix + selectmenu.find('option:selected').text() );
|
139 |
+
mdata.maxLevel = 0;
|
140 |
+
themenu.append( menu.data('menuid', menuid) )
|
141 |
+
.find('a').each(function(i){
|
142 |
+
var level = $(this).parent('li').data().level;
|
143 |
+
$(this).data('indx', i);
|
144 |
+
if(level && level > mdata.maxLevel){
|
145 |
+
mdata.maxLevel = level;
|
146 |
+
}
|
147 |
+
});
|
148 |
+
}
|
149 |
+
},
|
150 |
+
/**
|
151 |
+
* toggles the assist dialog open/closed, creating it if necessary
|
152 |
+
* @this {Element} A -toggle-assist anchor
|
153 |
+
* @param {Object} e Event object
|
154 |
+
* @return {boolean} false
|
155 |
+
*/
|
156 |
+
init : function(e){
|
157 |
+
var self = $(this),
|
158 |
+
data = self.closest(dotPrefix + '-onchange').data(),
|
159 |
+
dialog = $( '#' + data.cmwDialogId ),
|
160 |
+
fm = self.closest('form');
|
161 |
+
if(!dialog.length){
|
162 |
+
//create it...
|
163 |
+
dialog = $('<div/>', {id:data.cmwDialogId}).addClass(dotPrefix.substr(1) + '-dialog')
|
164 |
+
.data({cmwTriggerChange:data.cmwDialogTrigger, cmwTitlePrefix:data.cmwDialogTitle})
|
165 |
+
.append( $('<div/>').addClass('cmw-demo-theoutput').html('<strong>' + data.cmwDialogOutput + '</strong> …<div class="cmw-demo-theoutput-wrap ui-corner-all"></div><div class="cmw-demo-fallback"><small>' + data.cmwDialogFallback + '</small></div>') )
|
166 |
+
.append( $('<div/>').addClass('cmw-demo-themenu').html('<small><em>' + data.cmwDialogPrompt + '</em></small>') )
|
167 |
+
.append( $('<div/>').addClass('cmw-demo-theshortcode').html('<code class="ui-corner-all">[custom_menu_wizard]</code>') );
|
168 |
+
dialog.find('.cmw-demo-themenu').on('click', 'a', assist.clickMenu);
|
169 |
+
dialog.find('.cmw-demo-themenu').on('change', 'input', assist.changeMenu);
|
170 |
+
dialog.find('.cmw-demo-theoutput').on('click', 'a', assist.clickOutput);
|
171 |
+
dialog.dialog({autoOpen:false, width:Math.min($(window).width() * 0.8, 600), modal:false});
|
172 |
+
}
|
173 |
+
if(dialog.dialog('isOpen')){
|
174 |
+
dialog.dialog('close');
|
175 |
+
}else{
|
176 |
+
assist.createMenu(dialog, fm);
|
177 |
+
dialog.dialog('open');
|
178 |
+
$(data.cmwDialogTrigger).trigger('change');
|
179 |
+
}
|
180 |
+
this.blur();
|
181 |
+
return false;
|
182 |
+
},
|
183 |
+
/**
|
184 |
+
* create and show the shortcode equivalent
|
185 |
+
* @param {Object} fm jQuery object of the widget form
|
186 |
+
* @param {Object} settings Form element values
|
187 |
+
*/
|
188 |
+
shortcode : function(fm, settings){
|
189 |
+
var args = {
|
190 |
+
'menu' : [settings.menu]
|
191 |
+
},
|
192 |
+
v, m, n;
|
193 |
+
if(settings.title){
|
194 |
+
args.title = settings.title;
|
195 |
+
}
|
196 |
+
if(settings.filter > 0){
|
197 |
+
switch(settings.filter_item){
|
198 |
+
case 0: args.children_of = 'current'; break;
|
199 |
+
case -1: args.children_of = 'parent'; break;
|
200 |
+
case -2: args.children_of = 'root'; break;
|
201 |
+
default:
|
202 |
+
args.children_of = [settings.filter_item];
|
203 |
+
}
|
204 |
+
}
|
205 |
+
if(settings.filter < 0){
|
206 |
+
args.items = settings._items;
|
207 |
+
}
|
208 |
+
if(settings.filter > 0 && settings.filter_item < 0 && settings.fallback_no_ancestor){
|
209 |
+
if(settings.fallback_include_parent_siblings){
|
210 |
+
args.fallback_parent = 'siblings';
|
211 |
+
}else if(settings.fallback_include_parent){
|
212 |
+
args.fallback_parent = 'parent';
|
213 |
+
}else{
|
214 |
+
args.fallback_parent = [1];
|
215 |
+
}
|
216 |
+
}
|
217 |
+
if(settings.filter > 0 && !settings.filter_item && settings.fallback_no_children){
|
218 |
+
if(settings.fallback_nc_include_parent_siblings){
|
219 |
+
args.fallback_current = 'siblings';
|
220 |
+
}else if(settings.fallback_nc_include_parent){
|
221 |
+
args.fallback_current = 'parent';
|
222 |
+
}else{
|
223 |
+
args.fallback_current = [1];
|
224 |
+
}
|
225 |
+
}
|
226 |
+
if(settings.start_level > 1){
|
227 |
+
args.start_level = [settings.start_level];
|
228 |
+
}
|
229 |
+
if(settings.depth > 0){
|
230 |
+
args.depth = [settings.depth];
|
231 |
+
}
|
232 |
+
if(settings.depth_rel_current && settings.depth > 0){
|
233 |
+
args.depth_rel_current = [1];
|
234 |
+
}
|
235 |
+
n = [];
|
236 |
+
if(settings.filter > 0){
|
237 |
+
if(settings.include_parent_siblings){
|
238 |
+
n.push('siblings');
|
239 |
+
}else if(settings.include_parent){
|
240 |
+
n.push('parent');
|
241 |
+
}
|
242 |
+
if(settings.include_ancestors){
|
243 |
+
n.push('ancestors');
|
244 |
+
}
|
245 |
+
if(n.length){
|
246 |
+
args.include = n.join(' ');
|
247 |
+
}
|
248 |
+
}
|
249 |
+
n = [];
|
250 |
+
if(settings.filter > 0 && settings.title_from_parent){
|
251 |
+
n.push('parent');
|
252 |
+
}
|
253 |
+
if(settings.title_from_current){
|
254 |
+
n.push('current');
|
255 |
+
}
|
256 |
+
if(n.length){
|
257 |
+
args.title_from = n.join(' ');
|
258 |
+
}
|
259 |
+
for(n in {flat_output:1, contains_current:1, ol_root:1, ol_sub:1}){
|
260 |
+
if(settings[n]){
|
261 |
+
args[n] = [1];
|
262 |
+
}
|
263 |
+
}
|
264 |
+
v = {container:'div', container_id:'', container_class:'', menu_class:'menu-widget', widget_class:''};
|
265 |
+
for(n in v){
|
266 |
+
if(settings[n] !== v[n]){
|
267 |
+
args[n] = settings[n];
|
268 |
+
}
|
269 |
+
}
|
270 |
+
v = {wrap_link:'before', wrap_link_text:'link_before'};
|
271 |
+
for(n in v){
|
272 |
+
m = settings[v[n]].toString().match(/^<(\w+)/);
|
273 |
+
if(m && m[1]){
|
274 |
+
args[n] = m[1];
|
275 |
+
}
|
276 |
+
}
|
277 |
+
v = [];
|
278 |
+
for(n in args){
|
279 |
+
//array indicates 'as is', otherwise surround it in double quotes...
|
280 |
+
v.push( $.isArray(args[n]) ? n + '=' + args[n][0] : n + '="' + args[n] + '"' );
|
281 |
+
}
|
282 |
+
assist.getDialog(fm).find('code').text('[custom_menu_wizard ' + v.join(' ') + ']');
|
283 |
+
},
|
284 |
+
/**
|
285 |
+
*
|
286 |
+
* @this {Element}
|
287 |
+
* @param {Object} e Event object
|
288 |
+
* @param {Object} fm jQuery of widget form
|
289 |
+
* @param {Object} settings Form element values
|
290 |
+
*/
|
291 |
+
show : function(e, fm, settings){ //scope is a widget form element
|
292 |
+
//hide_empty is assumed to be On (WP < v3.6) or will automatically be On (WP v3.6+)
|
293 |
+
fm = fm || $(this).closest('form');
|
294 |
+
settings = settings || assist.getSettings(fm);
|
295 |
+
var dialog = assist.getDialog(fm),
|
296 |
+
themenu = dialog.find('.cmw-demo-themenu'),
|
297 |
+
items = themenu.find('.picked'),
|
298 |
+
html = '',
|
299 |
+
title = '',
|
300 |
+
currLevel = 0,
|
301 |
+
output = dialog.find('.cmw-demo-theoutput-wrap').empty(),
|
302 |
+
listClass = ['menu-widget'],
|
303 |
+
itemList = {};
|
304 |
+
if(items.length && output.length){
|
305 |
+
if(settings.filter > 0 && settings.title_from_parent){
|
306 |
+
title = themenu.find('.the-parent').children('a').text() || '';
|
307 |
+
}
|
308 |
+
if(!title && settings.title_from_current){
|
309 |
+
title = themenu.find('.current-menu-item').text() || '';
|
310 |
+
}
|
311 |
+
if(!title && !settings.hide_title){
|
312 |
+
title = settings.title || '';
|
313 |
+
}
|
314 |
+
items.each(function(i){
|
315 |
+
var self = $(this),
|
316 |
+
data = self.data(),
|
317 |
+
trace = data.trace ? data.trace.toString().split(',') : [],
|
318 |
+
iid = data.itemid.toString(),
|
319 |
+
level = 1,
|
320 |
+
anchor = self.children('a');
|
321 |
+
if(!settings.flat_output){
|
322 |
+
itemList[iid] = 1;
|
323 |
+
for(i = 0; i < trace.length; i++){
|
324 |
+
if(itemList[trace[i]]){
|
325 |
+
level++;
|
326 |
+
}
|
327 |
+
}
|
328 |
+
}
|
329 |
+
if(currLevel){
|
330 |
+
if(level > currLevel){
|
331 |
+
html += settings.ol_sub ? '<ol>' : '<ul>';
|
332 |
+
}else{
|
333 |
+
while(currLevel > level){
|
334 |
+
--currLevel;
|
335 |
+
html += '</li>' + (settings.ol_sub ? '</ol>' : '</ul>');
|
336 |
+
}
|
337 |
+
html += '</li>';
|
338 |
+
}
|
339 |
+
}
|
340 |
+
html += '<li class="cmw-level-' + level + (data.included || '') + '"><a href="#' + anchor.data('indx') + '">' + anchor.text() + '</a>';
|
341 |
+
currLevel = level;
|
342 |
+
});
|
343 |
+
while(currLevel > 1){
|
344 |
+
--currLevel;
|
345 |
+
html += '</li>' + (settings.ol_sub ? '</ol>' : '</ul>');
|
346 |
+
}
|
347 |
+
html += '</li>';
|
348 |
+
listClass.push( dialog.find('.cmw-demo-fallback').data('fellback') );
|
349 |
+
html = (settings.ol_root ? '<ol' : '<ul') + ' class="' + $.trim(listClass.join(' ')) + '">' + html + (settings.ol_root ? '</ol>' : '</ul>');
|
350 |
+
output.html(html);
|
351 |
+
if(title){
|
352 |
+
output.prepend('<h3>' + title + '</h3>');
|
353 |
+
}
|
354 |
+
output.find('li').filter(function(){
|
355 |
+
return !!$(this).children('ul, ol').length;
|
356 |
+
}).addClass('cmw-has-submenu');
|
357 |
+
}
|
358 |
+
assist.shortcode(fm, settings);
|
359 |
+
},
|
360 |
+
/**
|
361 |
+
* updates the graphic menu structure from the widget form data
|
362 |
+
* @this {Element} An input (radio or checkbox) or select element from the widget form
|
363 |
+
* @param {Object} e Event object
|
364 |
+
*/
|
365 |
+
update : function(e){
|
366 |
+
var fm = $(this).closest('form'),
|
367 |
+
dialog = assist.getDialog(fm),
|
368 |
+
maxLevel, settings, includeParent, includeParentSiblings, themenu, items,
|
369 |
+
currentItemLI, currentItemLevel, fallback, parent, i, j;
|
370 |
+
if(!dialog.length || !dialog.dialog('isOpen')){
|
371 |
+
return;
|
372 |
+
}
|
373 |
+
|
374 |
+
if($(e.target).hasClass(dotPrefix.substr(1) + '-selectmenu')){
|
375 |
+
assist.createMenu(dialog, fm);
|
376 |
+
}
|
377 |
+
settings = assist.getSettings(fm);
|
378 |
+
includeParent = settings.include_parent;
|
379 |
+
includeParentSiblings = settings.include_parent_siblings;
|
380 |
+
themenu = dialog.find('.cmw-demo-themenu');
|
381 |
+
maxLevel = themenu.data().maxLevel;
|
382 |
+
currentItemLI = themenu.find('.current-menu-item').closest('li');
|
383 |
+
currentItemLevel = currentItemLI.length ? currentItemLI.data().level : -1;
|
384 |
+
items = themenu.find('li').removeData('included').removeClass('the-parent');
|
385 |
+
|
386 |
+
if(settings.filter < 0){
|
387 |
+
items = items.filter(function(){
|
388 |
+
var checkbox = $(this).children('input'),
|
389 |
+
checked = (settings._items_sep + settings._items + settings._items_sep).indexOf(settings._items_sep + checkbox[0].value + settings._items_sep) > -1;
|
390 |
+
checkbox.prop('checked', checked);
|
391 |
+
return checked;
|
392 |
+
});
|
393 |
+
if(!settings._items){
|
394 |
+
items = $([]);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
if(items.length && !currentItemLI.length && (settings.contains_current || (settings.filter > 0 && settings.filter_item < 1))){
|
399 |
+
items = $([]);
|
400 |
+
}
|
401 |
+
|
402 |
+
if(items.length && settings.filter > 0){
|
403 |
+
//kids of...
|
404 |
+
if(settings.filter_item > 0){
|
405 |
+
//specific item...
|
406 |
+
parent = items.filter('[data-itemid=' + settings.filter_item + ']');
|
407 |
+
}else if(!settings.filter_item){
|
408 |
+
//current...
|
409 |
+
if(currentItemLI.find('li').length){
|
410 |
+
parent = currentItemLI;
|
411 |
+
}else if(settings.fallback_no_children){
|
412 |
+
//fall back to current parent...
|
413 |
+
parent = themenu.find('.current-menu-parent').closest('li');
|
414 |
+
if(!parent.length){
|
415 |
+
parent = themenu; //beware!
|
416 |
+
}
|
417 |
+
includeParent = includeParent || settings.fallback_nc_include_parent;
|
418 |
+
includeParentSiblings = includeParentSiblings || settings.fallback_nc_include_parent_siblings;
|
419 |
+
fallback = 'cmw-fellback-to-parent';
|
420 |
+
}
|
421 |
+
}else{
|
422 |
+
//parent or root...
|
423 |
+
if(currentItemLevel === 1 && settings.fallback_no_ancestor){
|
424 |
+
parent = currentItemLI;
|
425 |
+
includeParent = includeParent || settings.fallback_include_parent;
|
426 |
+
includeParentSiblings = includeParentSiblings || settings.fallback_include_parent_siblings;
|
427 |
+
fallback = 'cmw-fellback-to-current';
|
428 |
+
}else if(currentItemLevel === 1){
|
429 |
+
parent = themenu; //beware!
|
430 |
+
}else if(settings.filter_item < -1){
|
431 |
+
parent = themenu.find('.current-menu-ancestor').eq(0).closest('li');
|
432 |
+
}else{
|
433 |
+
parent = themenu.find('.current-menu-parent').closest('li');
|
434 |
+
}
|
435 |
+
}
|
436 |
+
}
|
437 |
+
|
438 |
+
if(items.length){
|
439 |
+
if(!settings.filter){
|
440 |
+
//showall : use the levels...
|
441 |
+
if(settings.depth_rel_current && settings.depth && currentItemLI.length && currentItemLevel >= settings.start_level){
|
442 |
+
j = currentItemLevel + settings.depth - 1;
|
443 |
+
}else{
|
444 |
+
j = settings.depth ? settings.start_level + settings.depth - 1 : 9999;
|
445 |
+
}
|
446 |
+
for(i = 1; i <= maxLevel; i++){
|
447 |
+
if(i < settings.start_level || i > j){
|
448 |
+
items = items.not('.level-' + i);
|
449 |
+
}
|
450 |
+
}
|
451 |
+
}else if(parent && parent.length){
|
452 |
+
//kids of...
|
453 |
+
if(settings.depth_rel_current && settings.depth && currentItemLI.length && parent.has(currentItemLI[0])){
|
454 |
+
j = currentItemLevel - 1 + settings.depth;
|
455 |
+
}else{
|
456 |
+
j = settings.depth ? Math.max( (parent.data().level || 0) + settings.depth, settings.start_level + settings.depth - 1 ) : 9999;
|
457 |
+
}
|
458 |
+
items = parent.find('li').filter(function(){
|
459 |
+
var level = $(this).data().level;
|
460 |
+
return level >= settings.start_level && level <= j;
|
461 |
+
});
|
462 |
+
}else if(settings.filter > 0){
|
463 |
+
//kids-of, but no parent found...
|
464 |
+
items = $([]);
|
465 |
+
}
|
466 |
+
}
|
467 |
+
|
468 |
+
if(items.length){
|
469 |
+
if(settings.filter > 0 && parent && parent.is('li')){
|
470 |
+
//kids of an item...
|
471 |
+
if(includeParentSiblings){
|
472 |
+
items = items.add( parent.siblings('li').data('included', ' cmw-an-included-parent-sibling') );
|
473 |
+
includeParent = true;
|
474 |
+
}
|
475 |
+
if(settings.include_ancestors){
|
476 |
+
items = items.add( parent.parentsUntil(themenu, 'li').data('included', ' cmw-an-included-ancestor') );
|
477 |
+
includeParent = true;
|
478 |
+
}
|
479 |
+
if(includeParent){
|
480 |
+
items = items.add( parent.data('included', ' cmw-the-included-parent') );
|
481 |
+
}
|
482 |
+
}
|
483 |
+
}
|
484 |
+
|
485 |
+
//must contain current item?...
|
486 |
+
if(items.length && settings.contains_current && (!currentItemLI.length || !items.filter(currentItemLI).length)){
|
487 |
+
items = $([]);
|
488 |
+
}
|
489 |
+
|
490 |
+
if(items.length && parent && parent.is('li')){
|
491 |
+
parent.addClass('the-parent');
|
492 |
+
}
|
493 |
+
fallback = items.length ? fallback : '';
|
494 |
+
dialog.find('.cmw-demo-fallback').data('fellback', fallback).toggleClass('cmw-demo-fellback', !!fallback);
|
495 |
+
themenu.toggleClass('cmw-demo-filteritems', settings.filter < 0)
|
496 |
+
.find('.picked').not( items.addClass('picked') ).removeClass('picked');
|
497 |
+
assist.show.call(this, e, fm, settings);
|
498 |
+
}
|
499 |
+
};
|
500 |
+
|
501 |
$(document)
|
502 |
//fieldsets...
|
503 |
.on('click', dotPrefix + '-collapsible-fieldset', function(){
|
504 |
+
var self = $(this),
|
505 |
+
chkbox = self.find('input').eq(0),
|
506 |
collapse = !chkbox.prop('checked');
|
507 |
if(chkbox.length){
|
508 |
chkbox.prop('checked', collapse);
|
509 |
+
self.find('div').toggleClass('cmw-collapsed-fieldset', collapse);
|
510 |
+
self.next('div')[collapse?'slideUp':'slideDown']();
|
511 |
}
|
512 |
this.blur();
|
513 |
return false;
|
514 |
})
|
515 |
//change of menu, and enableif / disableif...
|
516 |
.on('change', dotPrefix + '-listen', function(){
|
517 |
+
var fm = $(this.form),
|
518 |
+
selectMenu = fm.find(dotPrefix + '-selectmenu'),
|
519 |
+
showAll = fm.find(dotPrefix + '-showall').prop('checked'),
|
520 |
+
showSpecific = fm.find(dotPrefix + '-showspecific').prop('checked'),
|
521 |
+
filterItem = fm.find(dotPrefix + '-childrenof'),
|
522 |
fiVal = parseInt(filterItem.val(), 10),
|
523 |
groupClone;
|
524 |
if(selectMenu.is(this)){
|
525 |
+
//change of menu : swap out the childrenof's optgroup for the new one...
|
526 |
selectMenu = this.selectedIndex;
|
527 |
if(!filterItem.find('optgroup').filter(function(){
|
528 |
var keep = $(this).data('cmwOptgroupIndex') === selectMenu;
|
543 |
}
|
544 |
}
|
545 |
$.each(
|
546 |
+
{ '' : showAll || showSpecific,
|
547 |
+
'-ss' : showSpecific,
|
548 |
+
'not-rp' : showAll || showSpecific || fiVal >= 0,
|
549 |
+
'not-ci' : showAll || showSpecific || !!fiVal
|
550 |
},
|
551 |
function(k, v){
|
552 |
+
$(dotPrefix + '-disableif' + k, this.form).toggleClass('cmw-colour-grey', v).find('input,select').prop('disabled', v);
|
553 |
});
|
554 |
+
})
|
555 |
+
//any change event on inputs or selects...
|
556 |
+
.on('change', dotPrefix + '-onchange', assist.update)
|
557 |
+
//assist dialog...
|
558 |
+
.on('click', dotPrefix + '-toggle-assist', assist.init)
|
559 |
+
//when a widget is closed, close its open dialog...
|
560 |
+
.on('click', '.widget-action, .widget-control-close', function(){
|
561 |
+
$(this).closest('div.widget').find('.widget-custom-menu-wizard-onchange').each(function(){
|
562 |
+
var dialog = $('#' + $(this).data().cmwDialogId);
|
563 |
+
if(dialog.length && dialog.dialog('isOpen')){
|
564 |
+
dialog.dialog('close');
|
565 |
+
}
|
566 |
+
});
|
567 |
});
|
568 |
|
569 |
+
//1. when a widget is opened or saved, trigger change on the filter_item select
|
570 |
+
//2. when a widget is deleted, destroy its dialog
|
571 |
+
//To achieve this I've elected to modify WP's window.wpWidgets object and intercept some of its methods
|
572 |
+
// - for (1), the fixLabels() method, which handily gets called whenever a widget is opened or saved
|
573 |
+
// - for (2), the save() method
|
574 |
+
if(window.wpWidgets){
|
575 |
+
if(window.wpWidgets.fixLabels && !window.wpWidgets._cmw_fixLabels){
|
576 |
+
//save the original...
|
577 |
+
window.wpWidgets._cmw_fixLabels = window.wpWidgets.fixLabels;
|
578 |
+
//replace the original...
|
579 |
+
window.wpWidgets.fixLabels = function(widget){
|
580 |
+
//trigger change on selectmenu...
|
581 |
+
widget.find('.widget-custom-menu-wizard-selectmenu').trigger('change');
|
582 |
+
//run the original...
|
583 |
+
window.wpWidgets._cmw_fixLabels(widget);
|
584 |
+
};
|
585 |
+
}
|
586 |
+
if(window.wpWidgets.save && !window.wpWidgets._cmw_save){
|
587 |
+
//save the original...
|
588 |
+
window.wpWidgets._cmw_save = window.wpWidgets.save;
|
589 |
+
//replace the original...
|
590 |
+
window.wpWidgets.save = function(widget, del, animate, order){
|
591 |
+
//destroy dialog if deleting the widget...
|
592 |
+
if(del){
|
593 |
+
widget.find('.widget-custom-menu-wizard-onchange').each(function(){
|
594 |
+
var dialog = $('#' + $(this).data().cmwDialogId);
|
595 |
+
if(dialog.length){
|
596 |
+
dialog.dialog('destroy');
|
597 |
+
dialog.remove();
|
598 |
+
}
|
599 |
+
});
|
600 |
+
}
|
601 |
+
//run the original...
|
602 |
+
window.wpWidgets._cmw_save(widget, del, animate, order);
|
603 |
+
};
|
604 |
+
}
|
605 |
}else{
|
606 |
//one-off fallback...
|
607 |
$(dotPrefix + '-selectmenu').trigger('change');
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Plugin Name: Custom Menu Wizard
|
2 |
+
* Version: 2.0.0
|
3 |
+
* Author: Roger Barrett
|
4 |
+
*
|
5 |
+
* Script for controlling this widget's options (in Admin -> Widgets)
|
6 |
+
*/
|
7 |
+
jQuery(function(f){var n={getDialog:function(c){return f("#"+c.find(".widget-custom-menu-wizard-onchange").data().cmwDialogId)},getSettings:function(c){var a={};f.each(c.serializeArray(),function(d,c){var b=c.name.replace(/.*\[([^\]]+)\]$/,"$1"),e="items"!==b&&/^-?\d+$/.test(c.value)?parseInt(c.value,10):c.value;a[b]=e;"items"===b&&(a._items_sep=!e||/(^\d+$|,)/.test(f.trim(e))?",":" ",e=f.map(e.split(/[,\s]+/),function(a){a=a?parseInt(a,10):0;return isNaN(a)||1>a?null:a}),a._items=e.join(a._items_sep))});
|
8 |
+
return a},buildRecurse:function(c,a,d){var f="",b,e;a=(a||0)+1;d=d||"";for(b in c)e=b.split("|")[0],f+='<li class="level-'+a+'" data-itemid="'+e+'" data-level="'+a+'" data-trace="'+d+'">',f+='<a class="ui-corner-all" href="#"><span class="ui-corner-all" title="#'+e+'">'+b.replace(/^\d+\|/,""),f+='</span></a><input type="checkbox" value="'+e+'" />',c[b]&&(f+="<ul>"+n.buildRecurse(c[b],a,e+(d?",":"")+d)+"</ul>"),f+="</li>";return f},changeMenu:function(c){c=f(this);var a=f(c.closest(".ui-dialog-content").data().cmwTriggerChange).closest("form").find(".widget-custom-menu-wizard-setitems"),
|
9 |
+
d=f.trim(a.val()),d=!d||/(^\d+$|,)/.test(d)?",":" ";a.val(c.closest(".cmw-demo-themenu").find("input").map(function(){return this.checked?this.value:null}).get().join(d)).trigger("change")},clickMenu:function(c){var a=f(this);c=["current-menu-item","current-menu-parent","current-menu-ancestor"];var d=a.closest(".ui-dialog-content"),h=d.find(".cmw-demo-themenu"),a=a.find("span").not("."+c[0]).parentsUntil(h,"li"),b,e=function(){this.title=this.title+" "+b.replace(" "," & ").replace(/-/g," ")};h.find("."+
|
10 |
+
c.join(",.")).removeClass(c.join(" ")).each(function(){this.title=this.title.replace(/\s.*$/,"")});for(h=0;h<a.length;h++)b=1===h?c.join(" "):c[0],a.eq(h).children("a").find("span").addClass(b).each(e),1<c.length&&c.shift();f(d.data().cmwTriggerChange).trigger("change");return!1},clickOutput:function(c){c=this.href.split("#")[1];f(this).closest(".ui-dialog-content").find(".cmw-demo-themenu a").eq(c).not(":has(.current-menu-item)").trigger("click");this.blur();return!1},createMenu:function(c,a){var d=
|
11 |
+
c.data(),h=c.find(".cmw-demo-themenu"),b=a.find(".widget-custom-menu-wizard-selectmenu"),e=parseInt(b.val(),10),m=h.find("ul").eq(0),k=h.data(),g;m.length&&m.data("menuid")===e||(g=f("<ul>"+n.buildRecurse(a.find(".widget-custom-menu-wizard-childrenof optgroup").data().cmwItems||{})+"</ul>"),m.remove(),c.dialog("option","title",d.cmwTitlePrefix+b.find("option:selected").text()),k.maxLevel=0,h.append(g.data("menuid",e)).find("a").each(function(a){var b=f(this).parent("li").data().level;f(this).data("indx",
|
12 |
+
a);b&&b>k.maxLevel&&(k.maxLevel=b)}))},init:function(c){var a=f(this);c=a.closest(".widget-custom-menu-wizard-onchange").data();var d=f("#"+c.cmwDialogId),a=a.closest("form");d.length||(d=f("<div/>",{id:c.cmwDialogId}).addClass("widget-custom-menu-wizard-dialog").data({cmwTriggerChange:c.cmwDialogTrigger,cmwTitlePrefix:c.cmwDialogTitle}).append(f("<div/>").addClass("cmw-demo-theoutput").html("<strong>"+c.cmwDialogOutput+'</strong> …<div class="cmw-demo-theoutput-wrap ui-corner-all"></div><div class="cmw-demo-fallback"><small>'+
|
13 |
+
c.cmwDialogFallback+"</small></div>")).append(f("<div/>").addClass("cmw-demo-themenu").html("<small><em>"+c.cmwDialogPrompt+"</em></small>")).append(f("<div/>").addClass("cmw-demo-theshortcode").html('<code class="ui-corner-all">[custom_menu_wizard]</code>')),d.find(".cmw-demo-themenu").on("click","a",n.clickMenu),d.find(".cmw-demo-themenu").on("change","input",n.changeMenu),d.find(".cmw-demo-theoutput").on("click","a",n.clickOutput),d.dialog({autoOpen:!1,width:Math.min(0.8*f(window).width(),600),
|
14 |
+
modal:!1}));d.dialog("isOpen")?d.dialog("close"):(n.createMenu(d,a),d.dialog("open"),f(c.cmwDialogTrigger).trigger("change"));this.blur();return!1},shortcode:function(c,a){var d={menu:[a.menu]},h,b,e;a.title&&(d.title=a.title);if(0<a.filter)switch(a.filter_item){case 0:d.children_of="current";break;case -1:d.children_of="parent";break;case -2:d.children_of="root";break;default:d.children_of=[a.filter_item]}0>a.filter&&(d.items=a._items);0<a.filter&&0>a.filter_item&&a.fallback_no_ancestor&&(d.fallback_parent=
|
15 |
+
a.fallback_include_parent_siblings?"siblings":a.fallback_include_parent?"parent":[1]);0<a.filter&&!a.filter_item&&a.fallback_no_children&&(d.fallback_current=a.fallback_nc_include_parent_siblings?"siblings":a.fallback_nc_include_parent?"parent":[1]);1<a.start_level&&(d.start_level=[a.start_level]);0<a.depth&&(d.depth=[a.depth]);a.depth_rel_current&&0<a.depth&&(d.depth_rel_current=[1]);e=[];0<a.filter&&(a.include_parent_siblings?e.push("siblings"):a.include_parent&&e.push("parent"),a.include_ancestors&&
|
16 |
+
e.push("ancestors"),e.length&&(d.include=e.join(" ")));e=[];0<a.filter&&a.title_from_parent&&e.push("parent");a.title_from_current&&e.push("current");e.length&&(d.title_from=e.join(" "));for(e in{flat_output:1,contains_current:1,ol_root:1,ol_sub:1})a[e]&&(d[e]=[1]);h={container:"div",container_id:"",container_class:"",menu_class:"menu-widget",widget_class:""};for(e in h)a[e]!==h[e]&&(d[e]=a[e]);h={wrap_link:"before",wrap_link_text:"link_before"};for(e in h)(b=a[h[e]].toString().match(/^<(\w+)/))&&
|
17 |
+
b[1]&&(d[e]=b[1]);h=[];for(e in d)h.push(f.isArray(d[e])?e+"="+d[e][0]:e+'="'+d[e]+'"');n.getDialog(c).find("code").text("[custom_menu_wizard "+h.join(" ")+"]")},show:function(c,a,d){a=a||f(this).closest("form");d=d||n.getSettings(a);c=n.getDialog(a);var h=c.find(".cmw-demo-themenu"),b=h.find(".picked"),e="",m="",k=0,g=c.find(".cmw-demo-theoutput-wrap").empty(),p=["menu-widget"],q={};if(b.length&&g.length){0<d.filter&&d.title_from_parent&&(m=h.find(".the-parent").children("a").text()||"");!m&&d.title_from_current&&
|
18 |
+
(m=h.find(".current-menu-item").text()||"");m||d.hide_title||(m=d.title||"");for(b.each(function(a){var b=f(this),c=b.data(),h=c.trace?c.trace.toString().split(","):[];a=c.itemid.toString();var g=1,b=b.children("a");if(!d.flat_output)for(q[a]=1,a=0;a<h.length;a++)q[h[a]]&&g++;if(k)if(g>k)e+=d.ol_sub?"<ol>":"<ul>";else{for(;k>g;)--k,e+="</li>"+(d.ol_sub?"</ol>":"</ul>");e+="</li>"}e+='<li class="cmw-level-'+g+(c.included||"")+'"><a href="#'+b.data("indx")+'">'+b.text()+"</a>";k=g});1<k;)--k,e+="</li>"+
|
19 |
+
(d.ol_sub?"</ol>":"</ul>");e+="</li>";p.push(c.find(".cmw-demo-fallback").data("fellback"));e=(d.ol_root?"<ol":"<ul")+' class="'+f.trim(p.join(" "))+'">'+e+(d.ol_root?"</ol>":"</ul>");g.html(e);m&&g.prepend("<h3>"+m+"</h3>");g.find("li").filter(function(){return!!f(this).children("ul, ol").length}).addClass("cmw-has-submenu")}n.shortcode(a,d)},update:function(c){var a=f(this).closest("form"),d=n.getDialog(a),h,b,e,m,k,g,p,q,r,l,s;if(d.length&&d.dialog("isOpen")){f(c.target).hasClass("widget-custom-menu-wizard-selectmenu")&&
|
20 |
+
n.createMenu(d,a);b=n.getSettings(a);e=b.include_parent;m=b.include_parent_siblings;k=d.find(".cmw-demo-themenu");h=k.data().maxLevel;p=k.find(".current-menu-item").closest("li");q=p.length?p.data().level:-1;g=k.find("li").removeData("included").removeClass("the-parent");0>b.filter&&(g=g.filter(function(){var a=f(this).children("input"),c=-1<(b._items_sep+b._items+b._items_sep).indexOf(b._items_sep+a[0].value+b._items_sep);a.prop("checked",c);return c}),b._items||(g=f([])));g.length&&!p.length&&(b.contains_current||
|
21 |
+
0<b.filter&&1>b.filter_item)&&(g=f([]));g.length&&0<b.filter&&(0<b.filter_item?l=g.filter("[data-itemid="+b.filter_item+"]"):b.filter_item?1===q&&b.fallback_no_ancestor?(l=p,e=e||b.fallback_include_parent,m=m||b.fallback_include_parent_siblings,r="cmw-fellback-to-current"):l=1===q?k:-1>b.filter_item?k.find(".current-menu-ancestor").eq(0).closest("li"):k.find(".current-menu-parent").closest("li"):p.find("li").length?l=p:b.fallback_no_children&&(l=k.find(".current-menu-parent").closest("li"),l.length||
|
22 |
+
(l=k),e=e||b.fallback_nc_include_parent,m=m||b.fallback_nc_include_parent_siblings,r="cmw-fellback-to-parent"));if(g.length)if(b.filter)l&&l.length?(s=b.depth_rel_current&&b.depth&&p.length&&l.has(p[0])?q-1+b.depth:b.depth?Math.max((l.data().level||0)+b.depth,b.start_level+b.depth-1):9999,g=l.find("li").filter(function(){var a=f(this).data().level;return a>=b.start_level&&a<=s})):0<b.filter&&(g=f([]));else for(s=b.depth_rel_current&&b.depth&&p.length&&q>=b.start_level?q+b.depth-1:b.depth?b.start_level+
|
23 |
+
b.depth-1:9999,q=1;q<=h;q++)if(q<b.start_level||q>s)g=g.not(".level-"+q);g.length&&0<b.filter&&l&&l.is("li")&&(m&&(g=g.add(l.siblings("li").data("included"," cmw-an-included-parent-sibling")),e=!0),b.include_ancestors&&(g=g.add(l.parentsUntil(k,"li").data("included"," cmw-an-included-ancestor")),e=!0),e&&(g=g.add(l.data("included"," cmw-the-included-parent"))));!g.length||!b.contains_current||p.length&&g.filter(p).length||(g=f([]));g.length&&l&&l.is("li")&&l.addClass("the-parent");r=g.length?r:"";
|
24 |
+
d.find(".cmw-demo-fallback").data("fellback",r).toggleClass("cmw-demo-fellback",!!r);k.toggleClass("cmw-demo-filteritems",0>b.filter).find(".picked").not(g.addClass("picked")).removeClass("picked");n.show.call(this,c,a,b)}}};f(document).on("click",".widget-custom-menu-wizard-collapsible-fieldset",function(){var c=f(this),a=c.find("input").eq(0),d=!a.prop("checked");a.length&&(a.prop("checked",d),c.find("div").toggleClass("cmw-collapsed-fieldset",d),c.next("div")[d?"slideUp":"slideDown"]());this.blur();
|
25 |
+
return!1}).on("change",".widget-custom-menu-wizard-listen",function(){var c=f(this.form),a=c.find(".widget-custom-menu-wizard-selectmenu"),d=c.find(".widget-custom-menu-wizard-showall").prop("checked"),h=c.find(".widget-custom-menu-wizard-showspecific").prop("checked"),c=c.find(".widget-custom-menu-wizard-childrenof"),b=parseInt(c.val(),10),e;a.is(this)&&(a=this.selectedIndex,c.find("optgroup").filter(function(){var b=f(this).data("cmwOptgroupIndex")===a;b||f(this).remove();return b}).length||(e=
|
26 |
+
f("#"+c.attr("id")+"_ignore").find("optgroup").eq(a).clone(),e.length&&(0<b&&(b=0,c.val(b)),e.find("option[selected]").removeAttr("selected").prop("selected",!1),c.append(e))));f.each({"":d||h,"-ss":h,"not-rp":d||h||0<=b,"not-ci":d||h||!!b},function(a,b){f(".widget-custom-menu-wizard-disableif"+a,this.form).toggleClass("cmw-colour-grey",b).find("input,select").prop("disabled",b)})}).on("change",".widget-custom-menu-wizard-onchange",n.update).on("click",".widget-custom-menu-wizard-toggle-assist",n.init).on("click",
|
27 |
+
".widget-action, .widget-control-close",function(){f(this).closest("div.widget").find(".widget-custom-menu-wizard-onchange").each(function(){var c=f("#"+f(this).data().cmwDialogId);c.length&&c.dialog("isOpen")&&c.dialog("close")})});window.wpWidgets?(window.wpWidgets.fixLabels&&!window.wpWidgets._cmw_fixLabels&&(window.wpWidgets._cmw_fixLabels=window.wpWidgets.fixLabels,window.wpWidgets.fixLabels=function(c){c.find(".widget-custom-menu-wizard-selectmenu").trigger("change");window.wpWidgets._cmw_fixLabels(c)}),
|
28 |
+
window.wpWidgets.save&&!window.wpWidgets._cmw_save&&(window.wpWidgets._cmw_save=window.wpWidgets.save,window.wpWidgets.save=function(c,a,d,h){a&&c.find(".widget-custom-menu-wizard-onchange").each(function(){var a=f("#"+f(this).data().cmwDialogId);a.length&&(a.dialog("destroy"),a.remove())});window.wpWidgets._cmw_save(c,a,d,h)})):f(".widget-custom-menu-wizard-selectmenu").trigger("change")});
|
@@ -2,16 +2,28 @@
|
|
2 |
/*
|
3 |
* Plugin Name: Custom Menu Wizard
|
4 |
* Plugin URI: http://wordpress.org/plugins/custom-menu-wizard/
|
5 |
-
* Description:
|
6 |
-
* Version:
|
7 |
* Author: Roger Barrett
|
8 |
* Author URI: http://www.wizzud.com/
|
9 |
* License: GPL2+
|
10 |
*/
|
11 |
|
12 |
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
* v1.2.2 change log:
|
14 |
* - bugfix : fallback for Current Item with no children was failing because the parent's children weren't being picked out correctly
|
|
|
15 |
* v1.2.1 change log:
|
16 |
* - added some extra custom classes, when applicable : cmw-fellback-to-current & cmw-fellback-to-parent (on outer UL/OL) and cmw-the-included-parent, cmw-an-included-parent-sibling & cmw-an-included-ancestor (on relevant LIs)
|
17 |
* - corrected 'show all from start level 1' processing so that custom classes get applied and 'Title from "Current" Item' works (regardless of filter settings)
|
@@ -36,7 +48,7 @@
|
|
36 |
* - moved the setting of 'disabled' attributes on INPUTs/SELECTs from PHP into javascript
|
37 |
*/
|
38 |
|
39 |
-
$Custom_Menu_Wizard_Widget_Version = '
|
40 |
|
41 |
/**
|
42 |
* registers the widget and adds the shortcode
|
@@ -51,10 +63,93 @@ add_action('widgets_init', 'custom_menu_wizard_register_widget');
|
|
51 |
* enqueues script file for the widget admin
|
52 |
*/
|
53 |
function custom_menu_wizard_widget_admin_script(){
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
}
|
56 |
add_action('admin_print_scripts-widgets.php', 'custom_menu_wizard_widget_admin_script');
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
/*
|
59 |
* Custom Menu Wizard Walker class
|
60 |
* NB: Walker_Nav_Menu class is in wp-includes/nav-menu-template.php, and is itself an
|
@@ -104,7 +199,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
104 |
|
105 |
$cmw =& $args->_custom_menu_wizard;
|
106 |
//in $cmw (array) :
|
107 |
-
// filter :
|
108 |
// filter_item : 0 = current item, -1 = parent of current (v1.1.0), -2 = root ancestor of current (v1.1.0); else a menu item id
|
109 |
// flat_output : true = equivalent of $max_depth == -1
|
110 |
// include_parent : true = include the filter_item menu item
|
@@ -114,12 +209,15 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
114 |
// title_from_current : true = widget wants current item's title (v1.2.0)
|
115 |
// start_level : integer, 1+
|
116 |
// depth : integer, replacement for max_depth and also applied to 'flat' output
|
|
|
117 |
// fallback_no_ancestor : true = if looking for an ancestor (root or parent) of a top-level current item, fallback to current item (v1.1.0)
|
118 |
// fallback_include_parent : true = if fallback_no_ancestor comes into play then force include_parent to true (v1.1.0)
|
119 |
// fallback_include_parent_siblings : true = if fallback_no_ancestor comes into play then force include_parent_siblings to true (v1.1.0)
|
120 |
// fallback_no_children : true = if looking for a current item, and that item turns out to have no children, fallback to current parent (v1.2.0)
|
121 |
// fallback_nc_include_parent : true = if fallback_no_children comes into play then force include_parent to true (v1.2.0)
|
122 |
// fallback_nc_include_parent_siblings : true = if fallback_no_children comes into play then force include_parent_siblings to true (v1.2.0)
|
|
|
|
|
123 |
//
|
124 |
// _walker (array) : for anything that only the walker can determine and that needs to be communicated back to the widget instance
|
125 |
//
|
@@ -128,11 +226,12 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
128 |
//second item is [2] whether it's at root or subordinate to first item)
|
129 |
$cmw['_walker']['fellback'] = false;
|
130 |
|
131 |
-
$find_kids_of = $cmw['filter'];
|
|
|
132 |
$find_current_item = $find_kids_of && empty( $cmw['filter_item'] );
|
133 |
$find_current_parent = $find_kids_of && $cmw['filter_item'] == -1; //v1.1.0
|
134 |
$find_current_root = $find_kids_of && $cmw['filter_item'] == -2; //v1.1.0
|
135 |
-
$
|
136 |
//these could change depending on whether a fallback comes into play (v1.1.0)
|
137 |
$include_parent = $cmw['include_parent'];
|
138 |
$include_parent_siblings = $cmw['include_parent_siblings'];
|
@@ -140,229 +239,278 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
140 |
$id_field = $this->db_fields['id']; //eg. = 'db_id'
|
141 |
$parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
|
142 |
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
-
$keep_ids = array();
|
149 |
-
$keep_items = array();
|
150 |
-
$temp = array(0 => array('kids' => array()));
|
151 |
foreach( $elements as $i=>$item ){
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
'breadcrumb' => array( $i ),
|
158 |
-
'parent' => 0,
|
159 |
-
'kids' => array()
|
160 |
-
);
|
161 |
-
$temp[0]['kids'][] = $i;
|
162 |
-
}elseif( isset( $temp[ $item->$parent_field ] ) ){
|
163 |
-
//set one greater than parent's level, and ancestors are parent's ancestors plus the parent...
|
164 |
-
$temp[ $item->$id_field ] = array(
|
165 |
-
'level' => $temp[ $item->$parent_field ]['level'] + 1,
|
166 |
-
'breadcrumb' => $temp[ $item->$parent_field ]['breadcrumb'],
|
167 |
-
'parent' => $item->$parent_field,
|
168 |
-
'kids' => array()
|
169 |
-
);
|
170 |
-
$temp[ $item->$id_field ]['breadcrumb'][] = $i;
|
171 |
-
$temp[ $item->$parent_field ]['kids'][] = $i;
|
172 |
-
}
|
173 |
-
//if $temp[] hasn't been set then it's an orphan; in order to keep orphans, max_depth must be 0 (ie. unlimited)
|
174 |
//note that if a child is an orphan then all descendants of that child are also considered to be orphans!
|
175 |
//also note that orphans (in the original menu) are ignored by this widget!
|
176 |
-
|
177 |
-
|
178 |
-
//let's keep track of current menu item (as index into $elements)...
|
179 |
if( $item->current ){
|
180 |
-
$
|
181 |
}
|
182 |
-
//
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
//
|
217 |
-
$
|
218 |
}
|
219 |
-
//...and reset start level...
|
220 |
-
$start_level = $cmw['start_level'];
|
221 |
}
|
222 |
-
//having found at least one, any more have to be:
|
223 |
-
// - within max_depth of the first one found, and
|
224 |
-
// - either it's an unspecific search, or we have the parent already
|
225 |
-
}elseif( $temp[ $item->$id_field ]['level'] <= $max_level && ( !$find_kids_of || in_array( $item->$parent_field, $keep_ids ) ) ){
|
226 |
-
$keep_ids[] = $item->$id_field;
|
227 |
-
$keep_items[] = $item;
|
228 |
}
|
229 |
}
|
230 |
}
|
231 |
-
} //end foreach
|
232 |
-
|
233 |
-
//v1.2.0 do we need to invoke the fallback for a childless 'children of current item'?...
|
234 |
-
//note that this is slightly different to the no_ancestor fallback, in that we are treating it like a switch from current item
|
235 |
-
//to current parent, *except* that here the fallback for not having an ancestor is to pretend there's a level-0 ancestor (above
|
236 |
-
//root); obviously it (the level-0 ancestor) will no item of its own, which means the kids now have no (real) parent
|
237 |
-
if( $find_current_item && $cmw['fallback_no_children'] && empty( $keep_items ) && !empty( $keep_ids ) ){
|
238 |
-
//what are the options?
|
239 |
-
// - the current item & its siblings
|
240 |
-
// - ... optionally plus its parent (if there is one)
|
241 |
-
// - ... optionally plus its parent (if there is one) and the parent's siblings
|
242 |
-
//keep_ids[0] is the id of the current item; put the parent's kids into keep_items...
|
243 |
-
foreach( $temp[ $temp[ $keep_ids[0] ]['parent'] ]['kids'] as $item ){
|
244 |
-
//v1.2.2 note : each 'kid' is an index into $elements!
|
245 |
-
$keep_items[] = $elements[ $item ];
|
246 |
-
}
|
247 |
-
$include_parent = $include_parent || $cmw['fallback_nc_include_parent'];
|
248 |
-
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_nc_include_parent_siblings'];
|
249 |
-
$cmw['_walker']['fellback'] = 'to-parent'; //v1.2.1
|
250 |
}
|
251 |
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
array_pop( $breadcrumb );
|
259 |
-
//last element is now the parent (if there is one)
|
260 |
-
$i = $j = count( $breadcrumb );
|
261 |
-
//might we want the parent's title as the widget title?...
|
262 |
-
if( $find_kids_of && $cmw['title_from_parent'] && $i > 0 ){
|
263 |
$cmw['_walker']['parent_title'] = apply_filters(
|
264 |
'the_title',
|
265 |
-
$elements[ $
|
266 |
-
$elements[ $
|
267 |
);
|
268 |
}
|
269 |
-
//
|
270 |
-
|
271 |
-
if( !empty( $ci_index ) && $cmw['title_from_current'] ){
|
272 |
$cmw['_walker']['current_title'] = apply_filters(
|
273 |
'the_title',
|
274 |
-
$elements[ $
|
275 |
-
$elements[ $
|
276 |
);
|
277 |
}
|
278 |
|
279 |
-
//
|
280 |
-
//
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
//remove
|
290 |
-
$
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
$
|
296 |
-
}
|
297 |
-
if( $parentAt > -1 ){
|
298 |
-
array_unshift( $keep_items, $elements[ $siblings[ $i ] ]);
|
299 |
-
$keep_items[0]->classes[] = $parentAt == $i ? 'cmw-the-included-parent' : 'cmw-an-included-parent-sibling';
|
300 |
}
|
301 |
}
|
302 |
-
//
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
}
|
309 |
-
$i = $j = count( $breadcrumb );
|
310 |
-
//don't include_parent now because we just have...
|
311 |
-
$include_parent = false;
|
312 |
-
$paClass = 'cmw-an-included-ancestor';
|
313 |
}
|
314 |
-
unset( $siblings );
|
315 |
-
}
|
316 |
-
|
317 |
-
if( $find_kids_of && $i > 0 ){
|
318 |
-
if( $cmw['include_ancestors'] ){
|
319 |
-
$j = 0; //everything in breadcrumb, from bottom to top
|
320 |
-
}elseif( $include_parent ){
|
321 |
-
--$j; //just the last item from breadcrumb
|
322 |
-
}
|
323 |
-
while( $i > $j ){
|
324 |
-
array_unshift( $keep_items, $elements[ $breadcrumb[ --$i ] ]);
|
325 |
-
$keep_items[0]->classes[] = $paClass;
|
326 |
-
$paClass = 'cmw-an-included-ancestor';
|
327 |
-
}
|
328 |
-
}
|
329 |
-
unset( $breadcrumb );
|
330 |
-
}
|
331 |
-
|
332 |
-
//for each item we're keeping, use the temp array to hold:
|
333 |
-
// [0] => the level within the new structure (starting at 1), and
|
334 |
-
// [1] => the number of kids each item has
|
335 |
-
$temp = array();
|
336 |
-
foreach( $keep_items as $item ){
|
337 |
-
if( isset( $temp[ $item->$parent_field ] ) ){
|
338 |
-
$temp[ $item->$id_field ] = array( $temp[ $item->$parent_field ][0] + 1, 0 );
|
339 |
-
$temp[ $item->$parent_field ][1] += 1;
|
340 |
-
}else{
|
341 |
-
$temp[ $item->$id_field ] = array( 1, 0 );
|
342 |
}
|
343 |
}
|
344 |
|
345 |
-
//
|
346 |
-
//new classes to indicate level (starting at 1) and whether any item has kids
|
347 |
-
//
|
348 |
-
//note that we have already filtered out real orphans, but we may have introduced top-level
|
349 |
-
//items that would appear to be orphans to the parent::walk() method, so we need to set all
|
350 |
-
//the top-level items to appear as if they are root-level items...
|
351 |
$elements = array();
|
352 |
$i = 1;
|
353 |
-
foreach( $
|
354 |
-
$
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
if( $temp[ $item->$id_field ][0] == 1 ){
|
359 |
-
//fake as root level item...
|
360 |
-
$item->$parent_field = 0;
|
361 |
}
|
362 |
-
|
|
|
|
|
363 |
}
|
364 |
-
unset( $
|
365 |
-
|
366 |
//since we've done all the depth filtering, set max_depth to unlimited (unless 'flat' was requested!)...
|
367 |
if( !$cmw['flat_output'] ){
|
368 |
$max_depth = 0;
|
@@ -372,7 +520,26 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
372 |
return empty( $elements ) ? '' : parent::walk( apply_filters( 'custom_menu_wizard_walker_items', $elements, $args ), $max_depth, $args );
|
373 |
}
|
374 |
|
375 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
|
377 |
/**
|
378 |
* Custom Menu Wizard Widget class
|
@@ -381,7 +548,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
381 |
|
382 |
var $_cmw_switches = array(
|
383 |
'hide_title' => 0,
|
384 |
-
'
|
|
|
385 |
'fallback_no_ancestor' => 0, //v1.1.0 added
|
386 |
'fallback_include_parent' => 0, //v1.1.0 added
|
387 |
'fallback_include_parent_siblings' => 0, //v1.1.0 added
|
@@ -407,6 +575,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
407 |
);
|
408 |
var $_cmw_strings = array(
|
409 |
'title' => '',
|
|
|
410 |
'container' => 'div',
|
411 |
'container_id' => '',
|
412 |
'container_class' => '',
|
@@ -421,6 +590,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
421 |
);
|
422 |
var $_cmw_integers = array(
|
423 |
'depth' => 0,
|
|
|
424 |
'filter_item' => -2, //v1.1.0 changed from 0
|
425 |
'menu' => 0,
|
426 |
'start_level' => 1
|
@@ -591,6 +761,9 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
591 |
'flat_output' => $instance['flat_output'],
|
592 |
'start_level' => $instance['start_level'],
|
593 |
'depth' => $instance['depth'],
|
|
|
|
|
|
|
594 |
//v1.2.1 this is for the walker's use...
|
595 |
'_walker' => array()
|
596 |
)
|
@@ -670,6 +843,18 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
670 |
foreach( $this->_cmw_html as $k=>$v ){
|
671 |
$instance[ $k ] = isset( $new_instance[ $k ] ) ? trim( $new_instance[ $k ] ) : $v;
|
672 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
673 |
|
674 |
return $instance;
|
675 |
}
|
@@ -714,6 +899,16 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
714 |
return;
|
715 |
}
|
716 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
717 |
/**
|
718 |
* permanently visible section : Title (with Hide) and Menu
|
719 |
*/
|
@@ -730,6 +925,9 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
730 |
</p>
|
731 |
|
732 |
<p>
|
|
|
|
|
|
|
733 |
<label for="<?php echo $this->get_field_id('menu'); ?>"><?php _e('Select Menu:'); ?></label>
|
734 |
<select id="<?php echo $this->get_field_id('menu'); ?>"
|
735 |
class="widget-<?php echo $this->id_base; ?>-selectmenu widget-<?php echo $this->id_base; ?>-listen"
|
@@ -752,18 +950,22 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
752 |
*/
|
753 |
$this->_open_a_field_section($instance, 'Filter', 'fs_filter');
|
754 |
?>
|
755 |
-
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
756 |
<p>
|
|
|
|
|
|
|
757 |
<label>
|
758 |
-
<input id="<?php echo $this->get_field_id('filter'); ?>_0"
|
759 |
-
|
|
|
760 |
<?php _e('Show all'); ?></label>
|
761 |
<br /><label>
|
762 |
<input id="<?php echo $this->get_field_id('filter'); ?>_1" class="widget-<?php echo $this->id_base; ?>-listen"
|
763 |
-
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="1" <?php checked($instance['filter']); ?> />
|
764 |
<?php _e('Children of:'); ?></label>
|
765 |
-
<select id="<?php echo $this->get_field_id('filter_item'); ?>"
|
766 |
-
|
|
|
767 |
<option value="0" <?php selected( $instance['filter_item'], 0 ); ?>><?php _e('Current Item'); ?></option>
|
768 |
<option value="-2" <?php selected( $instance['filter_item'], -2 ); ?>><?php _e('Current Root Item'); ?></option>
|
769 |
<option value="-1" <?php selected( $instance['filter_item'], -1 ); ?>><?php _e('Current Parent Item'); ?></option>
|
@@ -777,34 +979,68 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
777 |
foreach( $menus as $i=>$menu ){
|
778 |
//as of v1.2.0 : no items, no optgroup!
|
779 |
if( !empty( $menu->_items ) ){
|
780 |
-
|
781 |
-
$itemindents = array('0' => 0);
|
782 |
-
$
|
783 |
foreach( $menu->_items as $item ){
|
784 |
//exclude orpans!
|
785 |
if( isset($itemindents[ $item->menu_item_parent ])){
|
786 |
-
$
|
787 |
-
$
|
788 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
789 |
selected( $instance['filter_item'], $item->ID, false ) . '>' .
|
790 |
-
str_repeat(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
791 |
}
|
|
|
|
|
|
|
|
|
792 |
}
|
793 |
-
$
|
794 |
}
|
795 |
}
|
796 |
$menuOptions = implode("\n", $menuOptions);
|
797 |
echo $menuOptions;
|
798 |
?>
|
799 |
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
800 |
<select id="<?php echo $this->get_field_id('filter_item_ignore'); ?>" disabled="disabled"
|
801 |
-
|
802 |
-
name="<?php echo $this->get_field_name('filter_item_ignore'); ?>">
|
803 |
<?php echo $menuOptions; ?>
|
804 |
</select>
|
805 |
</p>
|
806 |
|
807 |
-
<p>
|
808 |
<label for="<?php echo $this->get_field_id('start_level'); ?>"><?php _e('Starting Level:'); ?></label>
|
809 |
<select id="<?php echo $this->get_field_id('start_level'); ?>" name="<?php echo $this->get_field_name('start_level'); ?>">
|
810 |
<?php
|
@@ -819,7 +1055,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
819 |
<br /><small><em><?php _e('Level to start testing items for inclusion'); ?></em></small>
|
820 |
</p>
|
821 |
|
822 |
-
<p>
|
823 |
<label for="<?php echo $this->get_field_id('depth'); ?>"><?php _e('For Depth:'); ?></label>
|
824 |
<select id="<?php echo $this->get_field_id('depth'); ?>" name="<?php echo $this->get_field_name('depth'); ?>">
|
825 |
<option value="0" <?php selected( $instance['depth'], 0 ); ?>><?php _e('unlimited'); ?></option>
|
@@ -832,7 +1068,12 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
832 |
}
|
833 |
?>
|
834 |
</select>
|
835 |
-
<br /><small><em><?php _e('Relative to
|
|
|
|
|
|
|
|
|
|
|
836 |
</p>
|
837 |
<?php $this->_close_a_field_section(); ?>
|
838 |
|
@@ -842,15 +1083,17 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
842 |
*/
|
843 |
$this->_open_a_field_section($instance, 'Fallbacks', 'fs_fallbacks');
|
844 |
?>
|
845 |
-
<
|
846 |
-
|
|
|
|
|
847 |
<small><strong><?php _e( 'If "Children of" is <em>Current Root / Parent Item</em>, and no ancestor exists' ); ?> :</strong></small>
|
848 |
<br /><label>
|
849 |
<input id="<?php echo $this->get_field_id('fallback_no_ancestor'); ?>"
|
850 |
name="<?php echo $this->get_field_name('fallback_no_ancestor'); ?>" type="checkbox" value="1"
|
851 |
<?php checked($instance['fallback_no_ancestor']); ?> />
|
852 |
<?php _e('Switch to Current Item, and'); ?></label>
|
853 |
-
<br /><label
|
854 |
<input id="<?php echo $this->get_field_id('fallback_include_parent'); ?>"
|
855 |
name="<?php echo $this->get_field_name('fallback_include_parent'); ?>" type="checkbox" value="1"
|
856 |
<?php checked($instance['fallback_include_parent']); ?> />
|
@@ -859,17 +1102,17 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
859 |
<input id="<?php echo $this->get_field_id('fallback_include_parent_siblings'); ?>"
|
860 |
name="<?php echo $this->get_field_name('fallback_include_parent_siblings'); ?>" type="checkbox" value="1"
|
861 |
<?php checked($instance['fallback_include_parent_siblings']); ?> />
|
862 |
-
<?php _e('
|
863 |
</p>
|
864 |
|
865 |
-
<p class="widget-<?php echo $this->id_base; ?>-disableifnot-ci"
|
866 |
<small><strong><?php _e( 'If "Children of" is <em>Current Item</em>, and current item has no children' ); ?> :</strong></small>
|
867 |
<br /><label>
|
868 |
<input id="<?php echo $this->get_field_id('fallback_no_children'); ?>"
|
869 |
name="<?php echo $this->get_field_name('fallback_no_children'); ?>" type="checkbox" value="1"
|
870 |
<?php checked($instance['fallback_no_children']); ?> />
|
871 |
<?php _e('Switch to Current Parent Item, and'); ?></label>
|
872 |
-
<br /><label
|
873 |
<input id="<?php echo $this->get_field_id('fallback_nc_include_parent'); ?>"
|
874 |
name="<?php echo $this->get_field_name('fallback_nc_include_parent'); ?>" type="checkbox" value="1"
|
875 |
<?php checked($instance['fallback_nc_include_parent']); ?> />
|
@@ -878,7 +1121,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
878 |
<input id="<?php echo $this->get_field_id('fallback_nc_include_parent_siblings'); ?>"
|
879 |
name="<?php echo $this->get_field_name('fallback_nc_include_parent_siblings'); ?>" type="checkbox" value="1"
|
880 |
<?php checked($instance['fallback_nc_include_parent_siblings']); ?> />
|
881 |
-
<?php _e('
|
882 |
</p>
|
883 |
|
884 |
|
@@ -890,8 +1133,10 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
890 |
*/
|
891 |
$this->_open_a_field_section($instance, 'Output', 'fs_output');
|
892 |
?>
|
893 |
-
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
894 |
<p>
|
|
|
|
|
|
|
895 |
<label>
|
896 |
<input id="<?php echo $this->get_field_id('flat_output'); ?>_0" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
897 |
type="radio" value="0" <?php checked(!$instance['flat_output']); ?> />
|
@@ -902,6 +1147,15 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
902 |
<?php _e('Flat'); ?></label>
|
903 |
</p>
|
904 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
905 |
<p class="widget-<?php echo $this->id_base; ?>-disableif">
|
906 |
<label>
|
907 |
<input id="<?php echo $this->get_field_id('include_parent'); ?>"
|
@@ -912,7 +1166,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
912 |
<input id="<?php echo $this->get_field_id('include_parent_siblings'); ?>"
|
913 |
name="<?php echo $this->get_field_name('include_parent_siblings'); ?>" type="checkbox"
|
914 |
value="1" <?php checked($instance['include_parent_siblings']); ?> />
|
915 |
-
<?php _e('
|
916 |
<br /><label>
|
917 |
<input id="<?php echo $this->get_field_id('include_ancestors'); ?>"
|
918 |
name="<?php echo $this->get_field_name('include_ancestors'); ?>" type="checkbox"
|
@@ -1045,6 +1299,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
1045 |
</p>
|
1046 |
<?php $this->_close_a_field_section(); ?>
|
1047 |
|
|
|
|
|
1048 |
<?php
|
1049 |
} //end form()
|
1050 |
|
@@ -1057,13 +1313,13 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
1057 |
*/
|
1058 |
function _open_a_field_section( &$instance, $text, $fname ){
|
1059 |
?>
|
1060 |
-
<div class="stuffbox widget-<?php echo $this->id_base; ?>-collapsible-fieldset" title="<?php _e( 'Click to show/hide' ); ?>"
|
1061 |
<input id="<?php echo $this->get_field_id($fname); ?>" class="hidden-field" name="<?php echo $this->get_field_name($fname); ?>"
|
1062 |
type="checkbox" value="1" <?php checked( $instance[$fname] ); ?> />
|
1063 |
-
<div style="background:
|
1064 |
-
<h3
|
1065 |
</div>
|
1066 |
-
<div class="
|
1067 |
<?php
|
1068 |
} //end _open_a_field_section()
|
1069 |
|
@@ -1114,22 +1370,25 @@ function custom_menu_wizard_widget_shortcode($atts, $content, $tag){
|
|
1114 |
$instance = shortcode_atts( array(
|
1115 |
'title' => '',
|
1116 |
'menu' => 0, // menu id, slug or name
|
1117 |
-
//determines filter & filter_item...
|
1118 |
-
'children_of' => '', // empty = show all; menu item id or title (caseless), or current|current-item|parent|current-parent|root|current-ancestor
|
|
|
1119 |
'start_level' => 1,
|
1120 |
'depth' => 0, // 0 = unlimited
|
1121 |
//only if children_of is (parent|current-parent|root|current-ancestor); determines fallback_no_ancestor, fallback_include_parent & fallback_include_parent_siblings...
|
1122 |
'fallback_parent' => 0, // 1 = use current-item; 'parent' = *and* include parent, 'siblings' = *and* include both parent and its siblings
|
1123 |
//only if children_of is (current|current-item); determines fallback_no_children, fallback_nc_include_parent & fallback_nc_include_parent_siblings...
|
1124 |
'fallback_current' => 0, // 1 = use current-parent; 'parent' = *and* include parent (if available), 'siblings' = *and* include both parent (if available) and its siblings
|
1125 |
-
|
1126 |
'flat_output' => 0,
|
|
|
1127 |
//determines include_parent, include_parent_siblings & include_ancestors...
|
1128 |
'include' =>'', //comma|space|hyphen separated list of 'parent', 'siblings', 'ancestors'
|
1129 |
'ol_root' => 0,
|
1130 |
'ol_sub' => 0,
|
1131 |
//determines title_from_parent & title_from_current...
|
1132 |
'title_from' => '', //comma|space|hyphen separated list of 'parent', 'current'
|
|
|
1133 |
//strings...
|
1134 |
'container' => 'div', // a tag : div|nav are WP restrictions, not the widget's; '' = no container
|
1135 |
'container_id' => '',
|
@@ -1167,36 +1426,40 @@ function custom_menu_wizard_widget_shortcode($atts, $content, $tag){
|
|
1167 |
unset( $menus );
|
1168 |
|
1169 |
if( $ok ){
|
1170 |
-
//children_of => filter & filter_item...
|
1171 |
-
if( empty( $instance['children_of'] ) ){
|
1172 |
-
$instance['children_of'] = '';
|
1173 |
-
}
|
1174 |
$instance['filter'] = $instance['filter_item'] = 0;
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
case 'current': case 'current-item':
|
1183 |
-
$instance['filter'] = 1;
|
1184 |
-
break;
|
1185 |
-
default:
|
1186 |
-
$instance['filter'] = 1;
|
1187 |
-
$instance['filter_item'] = strtolower( $instance['children_of'] );
|
1188 |
-
}
|
1189 |
-
unset( $instance['children_of'] );
|
1190 |
-
//if filter_item is non-numeric then it could be the title of a menu item, but we need it to be the menu item's id...
|
1191 |
-
if( !is_numeric( $instance['filter_item'] ) ){
|
1192 |
-
foreach( $items as $item ){
|
1193 |
-
$ok = strtolower( $item->title ) == $instance['filter_item'];
|
1194 |
-
if( $ok ){
|
1195 |
-
$instance['filter_item'] = $item->ID;
|
1196 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1197 |
}
|
1198 |
}
|
|
|
|
|
1199 |
}
|
|
|
1200 |
}
|
1201 |
|
1202 |
if( $ok ){
|
@@ -1269,6 +1532,7 @@ function custom_menu_wizard_widget_shortcode($atts, $content, $tag){
|
|
1269 |
$instance['link_before'] = '<' . $instance['wrap_link_text'] . '>';
|
1270 |
$instance['link_after'] = '</' . $instance['wrap_link_text'] . '>';
|
1271 |
}
|
|
|
1272 |
//handle widget_class here because we have full control over $before_widget...
|
1273 |
$before_widget_class = array(
|
1274 |
'widget_custom_menu_wizard',
|
2 |
/*
|
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: 2.0.0
|
7 |
* Author: Roger Barrett
|
8 |
* Author URI: http://www.wizzud.com/
|
9 |
* License: GPL2+
|
10 |
*/
|
11 |
|
12 |
/*
|
13 |
+
* v2.0.0 change log:
|
14 |
+
* - Possible Breaker! : start level has been made consistent for showall and kids-off filters. Previously, a kids-of filter on an item at level 2,
|
15 |
+
* with start level set to 4, would return no output because the immediate kids (at level 3) were outside the start level; now, there will
|
16 |
+
* be output, starting with the grand-kids (at level 4)
|
17 |
+
* - Possible Breaker! : there is now an artificial "root" above the top level menu items, which means that a parent or root children-of filter will no
|
18 |
+
* longer fail for a top-level current menu item; this may well obviate the need for the current item fallback, but it has been left in for
|
19 |
+
* backward compatibility.
|
20 |
+
* - added option for calculating depth relative to current menu item
|
21 |
+
* - added option allowing list output to be dependent on current menu item being present somewhere in the list
|
22 |
+
* - refactored the code
|
23 |
+
*
|
24 |
* v1.2.2 change log:
|
25 |
* - bugfix : fallback for Current Item with no children was failing because the parent's children weren't being picked out correctly
|
26 |
+
*
|
27 |
* v1.2.1 change log:
|
28 |
* - added some extra custom classes, when applicable : cmw-fellback-to-current & cmw-fellback-to-parent (on outer UL/OL) and cmw-the-included-parent, cmw-an-included-parent-sibling & cmw-an-included-ancestor (on relevant LIs)
|
29 |
* - corrected 'show all from start level 1' processing so that custom classes get applied and 'Title from "Current" Item' works (regardless of filter settings)
|
48 |
* - moved the setting of 'disabled' attributes on INPUTs/SELECTs from PHP into javascript
|
49 |
*/
|
50 |
|
51 |
+
$Custom_Menu_Wizard_Widget_Version = '2.0.0';
|
52 |
|
53 |
/**
|
54 |
* registers the widget and adds the shortcode
|
63 |
* enqueues script file for the widget admin
|
64 |
*/
|
65 |
function custom_menu_wizard_widget_admin_script(){
|
66 |
+
global $wp_scripts;
|
67 |
+
wp_enqueue_style('custom-menu-wizard-plugin-styles', plugins_url('/custom-menu-wizard.css', __FILE__), array(), $Custom_Menu_Wizard_Widget_Version);
|
68 |
+
wp_enqueue_script('custom-menu-wizard-plugin-script', plugins_url('/custom-menu-wizard.min.js', __FILE__), array('jquery-ui-dialog'), $Custom_Menu_Wizard_Widget_Version);
|
69 |
+
if( !wp_style_is( 'jquery-ui', 'registered' ) ) {
|
70 |
+
$jquery_ui_version = isset( $wp_scripts->registered['jquery-ui-core']->ver ) ? $wp_scripts->registered['jquery-ui-core']->ver : '1.9.2';
|
71 |
+
wp_register_style( 'jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/' . $jquery_ui_version . '/themes/smoothness/jquery-ui.css' );
|
72 |
+
}
|
73 |
+
wp_enqueue_style( 'jquery-ui' );
|
74 |
}
|
75 |
add_action('admin_print_scripts-widgets.php', 'custom_menu_wizard_widget_admin_script');
|
76 |
|
77 |
+
/**
|
78 |
+
* puts the contents of the Upgrade Notice (from readme.txt) for a new version under the widget's entry in Appearances - Widgets
|
79 |
+
*/
|
80 |
+
function custom_menu_wizard_update_message($plugin_data, $r){
|
81 |
+
global $Custom_Menu_Wizard_Widget_Version;
|
82 |
+
$readme = wp_remote_fopen( 'http://plugins.svn.wordpress.org/custom-menu-wizard/trunk/readme.txt' );
|
83 |
+
// $readme = file_get_contents( plugins_url( '/readme.txt', __FILE__ ) );
|
84 |
+
if(!empty($readme)){
|
85 |
+
//grab the Upgrade Notice section from the readme...
|
86 |
+
if(preg_match('/== upgrade notice ==(.+)(==|$)/ims', $readme, $match) > 0){
|
87 |
+
$readme = $match[1];
|
88 |
+
}else{
|
89 |
+
$readme = '';
|
90 |
+
}
|
91 |
+
}
|
92 |
+
if(!empty($readme)){
|
93 |
+
//if there's a heading for the currently installed version, take anything above it...
|
94 |
+
if(($match = strpos($readme, "= $Custom_Menu_Wizard_Widget_Version =")) !== false){
|
95 |
+
$readme = substr($readme, 0, $match);
|
96 |
+
}
|
97 |
+
//trim it...
|
98 |
+
$readme = trim(str_replace("\r", '', $readme), " \n");
|
99 |
+
}
|
100 |
+
if(!empty($readme)){
|
101 |
+
$readme = preg_replace(
|
102 |
+
array(
|
103 |
+
'/^= (\d+\.\d+\.\d+.*) =/m', // => /P H4 Upgrade Notice ... /H4 P
|
104 |
+
'/(__|\*\*)!\s?([^*]+!)\1/', // => STRONG red ... /STRONG
|
105 |
+
'/(__|\*\*)([^*]+)\1/', // => STRONG ... /STRONG
|
106 |
+
'/\*([^*]+)\*/', // => EM ... /EM
|
107 |
+
'/`([^`]+)`/', // => CODE ... /CODE
|
108 |
+
'/\[([^\]]+)\]\(([^\)]+)\)/', // => A ... /A
|
109 |
+
'/\n\+\s+/', // => SPAN indented bullet
|
110 |
+
'/\n[ \n]*/', // => BR
|
111 |
+
//remove breaks that immediately follow/precede a paragraph start/end tag...
|
112 |
+
'/(<p[^>]*>)<br\s\/>/', // => P
|
113 |
+
'/<br\s\/>(<\/p>)/' // => /P
|
114 |
+
),
|
115 |
+
array(
|
116 |
+
'</p><h4 style="margin:0;"><em>' . __("Upgrade Notice") . ' $1</em></h4><p style="margin:0.25em 1em;">',
|
117 |
+
'<strong style="color:#cc0000;">$2</strong>',
|
118 |
+
'<strong>$2</strong>',
|
119 |
+
'<em>$1</em>',
|
120 |
+
'<code>$1</code>',
|
121 |
+
'<a href="$2">$1</a>',
|
122 |
+
"\n" . ' <span style="margin:0 0.5em;">•</span>',
|
123 |
+
'<br />',
|
124 |
+
'$1',
|
125 |
+
'$1'
|
126 |
+
),
|
127 |
+
//convert html chars...
|
128 |
+
esc_html($readme)
|
129 |
+
);
|
130 |
+
//remove the *first* P end tag...
|
131 |
+
$readme = preg_replace('/<\/p>/', '', $readme . '</p>', 1);
|
132 |
+
}
|
133 |
+
//show if not empty...
|
134 |
+
if(!empty($readme)){
|
135 |
+
?>
|
136 |
+
<div style="font-weight:normal;background-color:#fff0c0;border:1px solid #ff9933;border-radius:0.5em;margin:0.5em;">
|
137 |
+
<div style="margin:0.5em 0.5em 0.5em 1em;max-height:12em;overflow:auto;">
|
138 |
+
<?php echo $readme; ?>
|
139 |
+
</div>
|
140 |
+
</div>
|
141 |
+
<?php
|
142 |
+
}
|
143 |
+
}
|
144 |
+
/**
|
145 |
+
* if the plugin has an update...
|
146 |
+
*/
|
147 |
+
function custom_menu_wizard_admin_menu(){
|
148 |
+
add_action('in_plugin_update_message-' . plugin_basename(__FILE__), 'custom_menu_wizard_update_message', 10, 2);
|
149 |
+
}
|
150 |
+
add_action('admin_menu', 'custom_menu_wizard_admin_menu');
|
151 |
+
|
152 |
+
|
153 |
/*
|
154 |
* Custom Menu Wizard Walker class
|
155 |
* NB: Walker_Nav_Menu class is in wp-includes/nav-menu-template.php, and is itself an
|
199 |
|
200 |
$cmw =& $args->_custom_menu_wizard;
|
201 |
//in $cmw (array) :
|
202 |
+
// filter : 0 = show all; 1 = kids of (current [root|parent] item or specific item); -1 = specific items (v2.0.0)
|
203 |
// filter_item : 0 = current item, -1 = parent of current (v1.1.0), -2 = root ancestor of current (v1.1.0); else a menu item id
|
204 |
// flat_output : true = equivalent of $max_depth == -1
|
205 |
// include_parent : true = include the filter_item menu item
|
209 |
// title_from_current : true = widget wants current item's title (v1.2.0)
|
210 |
// start_level : integer, 1+
|
211 |
// depth : integer, replacement for max_depth and also applied to 'flat' output
|
212 |
+
// depth_rel_current : true = changes depth calc from "relative to first filtered item found" to "relative to current item's level" (if current item is found below level/branch) (v2.0.0)
|
213 |
// fallback_no_ancestor : true = if looking for an ancestor (root or parent) of a top-level current item, fallback to current item (v1.1.0)
|
214 |
// fallback_include_parent : true = if fallback_no_ancestor comes into play then force include_parent to true (v1.1.0)
|
215 |
// fallback_include_parent_siblings : true = if fallback_no_ancestor comes into play then force include_parent_siblings to true (v1.1.0)
|
216 |
// fallback_no_children : true = if looking for a current item, and that item turns out to have no children, fallback to current parent (v1.2.0)
|
217 |
// fallback_nc_include_parent : true = if fallback_no_children comes into play then force include_parent to true (v1.2.0)
|
218 |
// fallback_nc_include_parent_siblings : true = if fallback_no_children comes into play then force include_parent_siblings to true (v1.2.0)
|
219 |
+
// contains_current : true = the output - both Filtered and any Included items - must contain the current menu item (v2.0.0)
|
220 |
+
// items : comma-or-space delimited list of item ids
|
221 |
//
|
222 |
// _walker (array) : for anything that only the walker can determine and that needs to be communicated back to the widget instance
|
223 |
//
|
226 |
//second item is [2] whether it's at root or subordinate to first item)
|
227 |
$cmw['_walker']['fellback'] = false;
|
228 |
|
229 |
+
$find_kids_of = $cmw['filter'] > 0;
|
230 |
+
$find_specific_items = $cmw['filter'] < 1; //v2.0.0
|
231 |
$find_current_item = $find_kids_of && empty( $cmw['filter_item'] );
|
232 |
$find_current_parent = $find_kids_of && $cmw['filter_item'] == -1; //v1.1.0
|
233 |
$find_current_root = $find_kids_of && $cmw['filter_item'] == -2; //v1.1.0
|
234 |
+
$depth_rel_current = $cmw['depth_rel_current'] && $cmw['depth'] > 0; //v2.0.0
|
235 |
//these could change depending on whether a fallback comes into play (v1.1.0)
|
236 |
$include_parent = $cmw['include_parent'];
|
237 |
$include_parent_siblings = $cmw['include_parent_siblings'];
|
239 |
$id_field = $this->db_fields['id']; //eg. = 'db_id'
|
240 |
$parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
|
241 |
|
242 |
+
$structure = array(0 => array(
|
243 |
+
'level' => 0,
|
244 |
+
'ancestors' => array(),
|
245 |
+
'kids' => array(),
|
246 |
+
'element' => -1,
|
247 |
+
'keepCount' => 0
|
248 |
+
));
|
249 |
+
$levels = array(
|
250 |
+
array() //for the artificial level-0
|
251 |
+
);
|
252 |
+
$allLevels = 9999;
|
253 |
+
$startWithKidsOf = -1;
|
254 |
|
|
|
|
|
|
|
255 |
foreach( $elements as $i=>$item ){
|
256 |
+
$itemID = $item->$id_field;
|
257 |
+
$parentID = empty( $item->$parent_field ) ? 0 : $item->$parent_field;
|
258 |
+
|
259 |
+
|
260 |
+
//if $structure[] hasn't been set then it's an orphan; in order to keep orphans, max_depth must be 0 (ie. unlimited)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
//note that if a child is an orphan then all descendants of that child are also considered to be orphans!
|
262 |
//also note that orphans (in the original menu) are ignored by this widget!
|
263 |
+
if( isset( $structure[ $parentID ] ) ){
|
264 |
+
//keep track of current item (as a structure key)...
|
|
|
265 |
if( $item->current ){
|
266 |
+
$currentItem = $itemID;
|
267 |
}
|
268 |
+
//this level...
|
269 |
+
$thisLevel = $structure[ $parentID ]['level'] + 1;
|
270 |
+
if( empty( $levels[ $thisLevel ] ) ){
|
271 |
+
$levels[ $thisLevel ] = array();
|
272 |
+
}
|
273 |
+
$levels[ $thisLevel ][] = $itemID;
|
274 |
+
|
275 |
+
$structure[ $itemID ] = array(
|
276 |
+
//level within structure...
|
277 |
+
'level' => $thisLevel,
|
278 |
+
//ancestors (from the artificial level-0, right down to parent, inclusive) within structure...
|
279 |
+
'ancestors' => $structure[ $parentID ]['ancestors'],
|
280 |
+
//kids within structure, ie array of itemID's...
|
281 |
+
'kids' => array(),
|
282 |
+
//item within elements...
|
283 |
+
'element' => $i,
|
284 |
+
//assume no matches...
|
285 |
+
'keep' => false
|
286 |
+
);
|
287 |
+
$structure[ $itemID ]['ancestors'][] = $parentID;
|
288 |
+
$structure[ $parentID ]['kids'][] = $itemID;
|
289 |
+
}
|
290 |
+
} //end foreach
|
291 |
+
|
292 |
+
//no point doing much more if we need the current item and we haven't found it, or if we're looking for specific items with none given...
|
293 |
+
$continue = true;
|
294 |
+
if( empty( $currentItem ) && ( $find_current_item || $find_current_parent || $find_current_root || $cmw['contains_current'] ) ){
|
295 |
+
$continue = false;
|
296 |
+
}elseif( $find_specific_items && empty( $cmw['items'] ) ){
|
297 |
+
$continue = false;
|
298 |
+
}
|
299 |
+
|
300 |
+
// IMPORTANT : as of v2.0.0, start level has been rationalised so that it acts the same across all filters (except for specific items!).
|
301 |
+
// Previously ...
|
302 |
+
// start level for a show-all filter literally started at the specified level and reported all levels until depth was reached.
|
303 |
+
// however, start level for a kids-of filter specified the level that the *immediate* kids of the selected filter had to be at
|
304 |
+
// or below. That was consistent for a specific item, current-item and current-parent filter, but for a current-root filter what
|
305 |
+
// it actually did was test the current item against the start level, not the current item's root ancestor! Inconsistent!
|
306 |
+
// But regardless of the current-root filter's use of start level, there was still the inconsistency between show-all and
|
307 |
+
// kids-of usage.
|
308 |
+
// Now (as of v2.0.0) ...
|
309 |
+
// start level and depth have been changed to definitively be secondary filters to the show-all & kids-of primary filter.
|
310 |
+
// The primary filter - show-all, or a kids-of - will provide the initial set of items, and the secondary - start level & depth -
|
311 |
+
// will further refine that set, with start level being an absolute, and depth still being relative to the first item found.
|
312 |
+
// The sole exception to this is when Depth Relative to Current Menu Item is set, which modifies the calculation of depth (only)
|
313 |
+
// such that it becomes relative to the level at which the current menu item can be found (but only if it can be found at or
|
314 |
+
// below start level).
|
315 |
+
// The effects of this change are that previously, filtering for kids of an item that was at level 2, with a start level of 4,
|
316 |
+
// would fail to return any items because the immediate kids (at level 3) were outside the start level. Now, the returned items
|
317 |
+
// will begin with the grand-kids (ie. those at level 4).
|
318 |
+
// Note that neither start level nor depth are applicable to a specific items filter (also new at v2.0.0)!
|
319 |
+
|
320 |
+
//the kids-of filters...
|
321 |
+
if( $continue && $find_kids_of ){
|
322 |
+
//specific item...
|
323 |
+
if( $cmw['filter_item'] > 0 && isset( $structure[ $cmw['filter_item'] ] ) && !empty( $structure[ $cmw['filter_item'] ]['kids'] ) ){
|
324 |
+
$startWithKidsOf = $cmw['filter_item'];
|
325 |
+
}
|
326 |
+
if( $find_current_item ){
|
327 |
+
if( !empty( $structure[ $currentItem ]['kids'] ) ){
|
328 |
+
$startWithKidsOf = $currentItem;
|
329 |
+
}elseif( $cmw['fallback_no_children'] ){
|
330 |
+
//no kids, and fallback to current parent is set...
|
331 |
+
//note that there is no "double fallback", so current parent "can" be the artifical zero element (level-0) *if*
|
332 |
+
// the current item is a singleton( ie. no kids & no ancestors)!
|
333 |
+
$ancestor = array_slice( $structure[ $currentItem ]['ancestors'], -1, 1 );
|
334 |
+
$startWithKidsOf = $ancestor[0]; //can be zero!
|
335 |
+
$include_parent = $include_parent || $cmw['fallback_nc_include_parent'];
|
336 |
+
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_nc_include_parent_siblings'];
|
337 |
+
$cmw['_walker']['fellback'] = 'to-parent';
|
338 |
+
}
|
339 |
+
}elseif( $find_current_parent || $find_current_root ){
|
340 |
+
//as of v2.0.0 the fallback to current item - for current menu items at the top level - is deprecated, but
|
341 |
+
//retained for a while to maintain backward compatibility
|
342 |
+
//if no parent : fall back to current item (if set)...
|
343 |
+
if( $structure[ $currentItem ]['level'] == 1 && $cmw['fallback_no_ancestor'] ){
|
344 |
+
$startWithKidsOf = $currentItem;
|
345 |
+
$include_parent = $include_parent || $cmw['fallback_include_parent'];
|
346 |
+
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_include_parent_siblings'];
|
347 |
+
$cmw['_walker']['fellback'] = 'to-current';
|
348 |
+
}else{
|
349 |
+
//as of v2.0.0, the artificial level-0 counts as parent of a top-level current menu item...
|
350 |
+
if( $find_current_parent ){
|
351 |
+
$ancestor = -1;
|
352 |
+
}elseif( $structure[ $currentItem ]['level'] > 1 ){
|
353 |
+
$ancestor = 1;
|
354 |
+
}else{
|
355 |
+
$ancestor = 0;
|
356 |
+
}
|
357 |
+
$ancestor = array_slice( $structure[ $currentItem ]['ancestors'], $ancestor, 1 );
|
358 |
+
if( !empty( $ancestor ) ){
|
359 |
+
$startWithKidsOf = $ancestor[0]; //as of v2.0.0, this can now be zero!
|
360 |
+
}
|
361 |
+
}
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
if( $continue ){
|
366 |
+
//right, let's set the keep flags
|
367 |
+
//for specific items, go straight in on the item id (start level and depth do not apply here)...
|
368 |
+
if( $find_specific_items ){
|
369 |
+
foreach( preg_split('/[,\s]+/', $cmw['items'] ) as $itemID ){
|
370 |
+
if( isset( $structure[ $itemID ] ) ){
|
371 |
+
$structure[ $itemID ]['keep'] = true;
|
372 |
+
$structure[0]['keepCount']++;
|
373 |
+
}
|
374 |
+
}
|
375 |
+
//for show-all filter, just use the levels...
|
376 |
+
}elseif( !$find_kids_of ){
|
377 |
+
//prior to v2.0.0, depth was always related to the first item found, and still is *unless* depth_rel_current is set
|
378 |
+
if( $depth_rel_current && !empty( $currentItem ) && $structure[ $currentItem ]['level'] >= $cmw['start_level'] ){
|
379 |
+
$bottomLevel = $structure[ $currentItem ]['level'] + $cmw['depth'] - 1;
|
380 |
+
}else{
|
381 |
+
$bottomLevel = $cmw['depth'] > 0 ? $cmw['start_level'] + $cmw['depth'] - 1 : $allLevels;
|
382 |
+
}
|
383 |
+
for( $i = $cmw['start_level']; isset( $levels[ $i ] ) && $i <= $bottomLevel; $i++ ){
|
384 |
+
foreach( $levels[ $i ] as $itemID ){
|
385 |
+
$structure[ $itemID ]['keep'] = true;
|
386 |
+
$structure[0]['keepCount']++;
|
387 |
+
}
|
388 |
+
}
|
389 |
+
//for kids-of filters, run a recursive through the structure's kids...
|
390 |
+
}elseif( $startWithKidsOf > -1 ){
|
391 |
+
//prior to v2.0.0, depth was always related to the first item found, and still is *unless* depth_rel_current is set
|
392 |
+
//NB the in_array() of ancestors prevents depth_rel_current when startWithKidsOf == currentItem
|
393 |
+
if( $depth_rel_current && !empty( $currentItem ) && $structure[ $currentItem ]['level'] >= $cmw['start_level']
|
394 |
+
&& in_array( $startWithKidsOf, $structure[ $currentItem ]['ancestors'] ) ){
|
395 |
+
$bottomLevel = $structure[ $currentItem ]['level'] - 1 + $cmw['depth'];
|
396 |
+
}else{
|
397 |
+
$bottomLevel = $cmw['depth'] > 0
|
398 |
+
? max( $structure[ $startWithKidsOf ]['level'] + $cmw['depth'], $cmw['start_level'] + $cmw['depth'] - 1 )
|
399 |
+
: $allLevels;
|
400 |
+
}
|
401 |
+
//$structure[0]['keepCount'] gets incremented in this recursive method...
|
402 |
+
$this->_cmw_set_keep_kids( $structure, $startWithKidsOf, $cmw['start_level'], $bottomLevel );
|
403 |
+
}
|
404 |
+
|
405 |
+
if( $structure[0]['keepCount'] > 0 ){
|
406 |
+
//we have some items! we now may need to set some more keep flags, depending on the include settings...
|
407 |
+
|
408 |
+
//do we need to include parent, parent siblings, and/or ancestors?...
|
409 |
+
//NB these are not restricted by start_level!
|
410 |
+
if( $find_kids_of && $startWithKidsOf > 0 ){
|
411 |
+
if( $include_parent ){
|
412 |
+
$structure[ $startWithKidsOf ]['keep'] = true;
|
413 |
+
//add the class directly to the elements item...
|
414 |
+
$elements[ $structure[ $startWithKidsOf ]['element'] ]->classes[] = 'cmw-the-included-parent';
|
415 |
+
}
|
416 |
+
if( $include_parent_siblings ){
|
417 |
+
$ancestor = array_slice( $structure[ $startWithKidsOf ]['ancestors'], -1, 1);
|
418 |
+
foreach($structure[ $ancestor[0] ]['kids'] as $itemID ){
|
419 |
+
//may have already been kept by include_parent...
|
420 |
+
if( !$structure[ $itemID ]['keep'] ){
|
421 |
+
$structure[ $itemID ]['keep'] = true;
|
422 |
+
//add the class directly to the elements item...
|
423 |
+
$elements[ $structure[ $itemID ]['element'] ]->classes[] = 'cmw-an-included-parent-sibling';
|
424 |
}
|
425 |
+
}
|
426 |
+
}
|
427 |
+
if( $cmw['include_ancestors'] ){
|
428 |
+
foreach( $structure[ $startWithKidsOf ]['ancestors'] as $itemID ){
|
429 |
+
if( $itemID > 0 && !$structure[ $itemID ]['keep'] ){
|
430 |
+
$structure[ $itemID ]['keep'] = true;
|
431 |
+
//add the class directly to the elements item...
|
432 |
+
$elements[ $structure[ $itemID ]['element'] ]->classes[] = 'cmw-an-included-parent-ancestor';
|
433 |
}
|
|
|
|
|
434 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
435 |
}
|
436 |
}
|
437 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
}
|
439 |
|
440 |
+
$substructure = array();
|
441 |
+
//check that (a) we have items, and (b) if we must have current menu item, we've got it...
|
442 |
+
if( $structure[0]['keepCount'] > 0 && ( !$cmw['contains_current'] || $structure[ $currentItem ]['keep'] ) ){
|
443 |
+
|
444 |
+
//might we want the parent's title as the widget title?...
|
445 |
+
if( $find_kids_of && $cmw['title_from_parent'] && $startWithKidsOf > 0 ){
|
|
|
|
|
|
|
|
|
|
|
446 |
$cmw['_walker']['parent_title'] = apply_filters(
|
447 |
'the_title',
|
448 |
+
$elements[ $structure[ $startWithKidsOf ]['element'] ]->title,
|
449 |
+
$elements[ $structure[ $startWithKidsOf ]['element'] ]->ID
|
450 |
);
|
451 |
}
|
452 |
+
//might we want the current item's title as the widget title?...
|
453 |
+
if( !empty( $currentItem ) && $cmw['title_from_current'] ){
|
|
|
454 |
$cmw['_walker']['current_title'] = apply_filters(
|
455 |
'the_title',
|
456 |
+
$elements[ $structure[ $currentItem ]['element'] ]->title,
|
457 |
+
$elements[ $structure[ $currentItem ]['element'] ]->ID
|
458 |
);
|
459 |
}
|
460 |
|
461 |
+
//now we need to gather together all the 'keep' items from structure;
|
462 |
+
//while doing so, we need to set up levels and kids, ready for adding classes...
|
463 |
+
foreach( $structure as $k=>$v ){
|
464 |
+
if( $v['keep'] ){
|
465 |
+
$substructure[ $k ] = $v;
|
466 |
+
//take a copy of the elements item...
|
467 |
+
$substructure[ $k ]['element'] = $elements[ $v['element'] ];
|
468 |
+
//use kids as a has-submenu flag...
|
469 |
+
$substructure[ $k ]['kids'] = 0;
|
470 |
+
//any surviving parent (except the artificial level-0) should have submenu class set on it...
|
471 |
+
array_shift( $v['ancestors'] ); //remove the level-0
|
472 |
+
for( $i = count( $v['ancestors'] ) - 1; $i >= 0; $i-- ){
|
473 |
+
if( $substructure[ $v['ancestors'][ $i ] ]['keep'] ){
|
474 |
+
$substructure[ $v['ancestors'][ $i ] ]['kids']++;
|
475 |
+
}else{
|
476 |
+
//not a 'kept' ancestor so remove it...
|
477 |
+
array_splice( $v['ancestors'], $i, 1 );
|
|
|
|
|
|
|
|
|
478 |
}
|
479 |
}
|
480 |
+
//ancestors now only has 'kept' ancestors...
|
481 |
+
$substructure[ $k ]['level'] = count( $v['ancestors'] ) + 1;
|
482 |
+
//need to ensure that the parent_field of all the new top-level (ie. root) items is set to
|
483 |
+
//zero, otherwise the parent::walk() will assume they're orphans and ignore them.
|
484 |
+
//however, we also need to check - especially for a specific-items filter (v2.0.0) - that parent_field of a
|
485 |
+
//child actually points to the closest 'kept' ancestor; otherwise, given A (kept) > B (not kept) > C (kept)
|
486 |
+
//the parent_field of C would point to a non-existent B and would subsequently be considered an orphan!
|
487 |
+
if( $substructure[ $k ]['level'] == 1){
|
488 |
+
$substructure[ $k ]['element']->$parent_field = 0;
|
489 |
+
}else{
|
490 |
+
//NB even though this really only needs to be done for $find_specific_items, I'm doing it regardless.
|
491 |
+
//set to the closest ancestor, ie. the new(?) parent...
|
492 |
+
$ancestor = array_slice( $v['ancestors'], -1, 1 );
|
493 |
+
$substructure[ $k ]['element']->$parent_field = $ancestor[0];
|
494 |
}
|
|
|
|
|
|
|
|
|
495 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
496 |
}
|
497 |
}
|
498 |
|
499 |
+
//put substructure's elements back into $elements (remember that it's a 1-based array!)...
|
|
|
|
|
|
|
|
|
|
|
500 |
$elements = array();
|
501 |
$i = 1;
|
502 |
+
foreach( $substructure as $k=>$v ){
|
503 |
+
$elements[ $i ] = $v['element'];
|
504 |
+
//add the submenu class?...
|
505 |
+
if( $v['kids'] > 0 ){
|
506 |
+
$elements[ $i ]->classes[] = 'cmw-has-submenu';
|
|
|
|
|
|
|
507 |
}
|
508 |
+
//add the level class...
|
509 |
+
$elements[ $i ]->classes[] = 'cmw-level-' . $v['level'];
|
510 |
+
$i++;
|
511 |
}
|
512 |
+
unset( $structure, $substructure );
|
513 |
+
|
514 |
//since we've done all the depth filtering, set max_depth to unlimited (unless 'flat' was requested!)...
|
515 |
if( !$cmw['flat_output'] ){
|
516 |
$max_depth = 0;
|
520 |
return empty( $elements ) ? '' : parent::walk( apply_filters( 'custom_menu_wizard_walker_items', $elements, $args ), $max_depth, $args );
|
521 |
}
|
522 |
|
523 |
+
/**
|
524 |
+
* recursively set the keep flag if within specified level/depth
|
525 |
+
*/
|
526 |
+
function _cmw_set_keep_kids( &$structure, $itemId, $topLevel, $bottomLevel ){
|
527 |
+
$ct = count( $structure[ $itemId ]['kids'] );
|
528 |
+
for( $i = 0; $i < $ct; $i++ ){
|
529 |
+
$j = $structure[ $itemId ]['kids'][ $i ];
|
530 |
+
if( $structure[ $j ]['level'] <= $bottomLevel ){
|
531 |
+
$structure[ $j ]['keep'] = $structure[ $j ]['level'] >= $topLevel;
|
532 |
+
if( $structure[ $j ]['keep'] ){
|
533 |
+
$structure[0]['keepCount']++;
|
534 |
+
}
|
535 |
+
}
|
536 |
+
if( $structure[ $j ]['level'] < $bottomLevel ){
|
537 |
+
$this->_cmw_set_keep_kids( $structure, $j, $topLevel, $bottomLevel );
|
538 |
+
}
|
539 |
+
}
|
540 |
+
}
|
541 |
+
|
542 |
+
} //end Custom_Menu_Wizard_Walker class
|
543 |
|
544 |
/**
|
545 |
* Custom Menu Wizard Widget class
|
548 |
|
549 |
var $_cmw_switches = array(
|
550 |
'hide_title' => 0,
|
551 |
+
'contains_current' => 0, //v2.0.0 added
|
552 |
+
'depth_rel_current' => 0, //v2.0.0 added
|
553 |
'fallback_no_ancestor' => 0, //v1.1.0 added
|
554 |
'fallback_include_parent' => 0, //v1.1.0 added
|
555 |
'fallback_include_parent_siblings' => 0, //v1.1.0 added
|
575 |
);
|
576 |
var $_cmw_strings = array(
|
577 |
'title' => '',
|
578 |
+
'items' => '', //v2.0.0 added
|
579 |
'container' => 'div',
|
580 |
'container_id' => '',
|
581 |
'container_class' => '',
|
590 |
);
|
591 |
var $_cmw_integers = array(
|
592 |
'depth' => 0,
|
593 |
+
'filter' => -1, //v2.0.0 changed from switch
|
594 |
'filter_item' => -2, //v1.1.0 changed from 0
|
595 |
'menu' => 0,
|
596 |
'start_level' => 1
|
761 |
'flat_output' => $instance['flat_output'],
|
762 |
'start_level' => $instance['start_level'],
|
763 |
'depth' => $instance['depth'],
|
764 |
+
'depth_rel_current' => $instance['depth_rel_current'], //v2.0.0
|
765 |
+
'contains_current' => $instance['contains_current'], //v2.0.0
|
766 |
+
'items' => $instance['items'], //v2.0.0
|
767 |
//v1.2.1 this is for the walker's use...
|
768 |
'_walker' => array()
|
769 |
)
|
843 |
foreach( $this->_cmw_html as $k=>$v ){
|
844 |
$instance[ $k ] = isset( $new_instance[ $k ] ) ? trim( $new_instance[ $k ] ) : $v;
|
845 |
}
|
846 |
+
//items special case...
|
847 |
+
if( !empty( $instance['items'] ) ){
|
848 |
+
$sep = preg_match( '/(^\d+$|,)/', $instance['items'] ) > 0 ? ',' : ' ';
|
849 |
+
$a = array();
|
850 |
+
foreach( preg_split('/[,\s]+/', $instance['items'], -1, PREG_SPLIT_NO_EMPTY ) as $v ){
|
851 |
+
$i = intval( $v );
|
852 |
+
if( $i > 0 ){
|
853 |
+
$a[] = $i;
|
854 |
+
}
|
855 |
+
}
|
856 |
+
$instance['items'] = implode( $sep, $a );
|
857 |
+
}
|
858 |
|
859 |
return $instance;
|
860 |
}
|
899 |
return;
|
900 |
}
|
901 |
|
902 |
+
?>
|
903 |
+
<div class="widget-<?php echo $this->id_base; ?>-onchange"
|
904 |
+
data-cmw-dialog-title='<?php _e('Selected Menu : '); ?>'
|
905 |
+
data-cmw-dialog-prompt='<?php _e('Click an item to toggle "Current Menu Item"'); ?>'
|
906 |
+
data-cmw-dialog-output='<?php _e('Basic Output'); ?>'
|
907 |
+
data-cmw-dialog-fallback='<?php _e('Fallback invoked'); ?>'
|
908 |
+
data-cmw-dialog-trigger='#<?php echo $this->get_field_id('filter_item'); ?>'
|
909 |
+
data-cmw-dialog-id='<?php echo $this->get_field_id('dialog'); ?>'>
|
910 |
+
<?php
|
911 |
+
|
912 |
/**
|
913 |
* permanently visible section : Title (with Hide) and Menu
|
914 |
*/
|
925 |
</p>
|
926 |
|
927 |
<p>
|
928 |
+
<small class="cmw-toggle-assist">
|
929 |
+
<a class="widget-<?php echo $this->id_base; ?>-toggle-assist" href="#"><?php _e('assist'); ?></a>
|
930 |
+
</small>
|
931 |
<label for="<?php echo $this->get_field_id('menu'); ?>"><?php _e('Select Menu:'); ?></label>
|
932 |
<select id="<?php echo $this->get_field_id('menu'); ?>"
|
933 |
class="widget-<?php echo $this->id_base; ?>-selectmenu widget-<?php echo $this->id_base; ?>-listen"
|
950 |
*/
|
951 |
$this->_open_a_field_section($instance, 'Filter', 'fs_filter');
|
952 |
?>
|
|
|
953 |
<p>
|
954 |
+
<small class="cmw-toggle-assist">
|
955 |
+
<a class="widget-<?php echo $this->id_base; ?>-toggle-assist" href="#"><?php _e('assist'); ?></a>
|
956 |
+
</small>
|
957 |
<label>
|
958 |
+
<input id="<?php echo $this->get_field_id('filter'); ?>_0"
|
959 |
+
class="widget-<?php echo $this->id_base; ?>-showall widget-<?php echo $this->id_base; ?>-listen"
|
960 |
+
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="0" <?php checked($instance['filter'], 0); ?> />
|
961 |
<?php _e('Show all'); ?></label>
|
962 |
<br /><label>
|
963 |
<input id="<?php echo $this->get_field_id('filter'); ?>_1" class="widget-<?php echo $this->id_base; ?>-listen"
|
964 |
+
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="1" <?php checked($instance['filter'], 1); ?> />
|
965 |
<?php _e('Children of:'); ?></label>
|
966 |
+
<select id="<?php echo $this->get_field_id('filter_item'); ?>"
|
967 |
+
class="widget-<?php echo $this->id_base; ?>-childrenof widget-<?php echo $this->id_base; ?>-listen"
|
968 |
+
name="<?php echo $this->get_field_name('filter_item'); ?>">
|
969 |
<option value="0" <?php selected( $instance['filter_item'], 0 ); ?>><?php _e('Current Item'); ?></option>
|
970 |
<option value="-2" <?php selected( $instance['filter_item'], -2 ); ?>><?php _e('Current Root Item'); ?></option>
|
971 |
<option value="-1" <?php selected( $instance['filter_item'], -1 ); ?>><?php _e('Current Parent Item'); ?></option>
|
979 |
foreach( $menus as $i=>$menu ){
|
980 |
//as of v1.2.0 : no items, no optgroup!
|
981 |
if( !empty( $menu->_items ) ){
|
982 |
+
$grpdata = array();
|
983 |
+
$itemindents = array( '0' => array( 'level'=>0, 'grpkey'=>'' ) );
|
984 |
+
$menuGrpOpts = array();
|
985 |
foreach( $menu->_items as $item ){
|
986 |
//exclude orpans!
|
987 |
if( isset($itemindents[ $item->menu_item_parent ])){
|
988 |
+
$title = apply_filters( 'the_title', $item->title, $item->ID );
|
989 |
+
$level = $itemindents[ $item->menu_item_parent ]['level'] + 1;
|
990 |
+
$grpkey = $item->ID . '|' . $title;
|
991 |
+
$grpdata[ $grpkey ] = array();
|
992 |
+
if( !empty( $itemindents[ $item->menu_item_parent ]['grpkey'] )){
|
993 |
+
$grpdata[ $itemindents[ $item->menu_item_parent ]['grpkey'] ][ $grpkey ] = array();
|
994 |
+
}
|
995 |
+
|
996 |
+
$itemindents[ $item->ID ] = array( 'level'=>$level, 'grpkey'=>$grpkey );
|
997 |
+
$maxlevel = max( $maxlevel, $level );
|
998 |
+
//v2.0.0 indents changed to non-breaking spaces...
|
999 |
+
$menuGrpOpts[] = '<option value="' . $item->ID . '" ' .
|
1000 |
selected( $instance['filter_item'], $item->ID, false ) . '>' .
|
1001 |
+
str_repeat( ' ', ($level - 1) * 3 ) . $title . '</option>';
|
1002 |
+
}
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
//the menu had items, but they might all have been orphans?...
|
1006 |
+
if( !empty( $menuGrpOpts ) ){
|
1007 |
+
foreach( array_reverse( $grpdata ) as $k=>$v ){
|
1008 |
+
if( empty( $v ) ){
|
1009 |
+
$grpdata[ $k ] = false;
|
1010 |
+
}else{
|
1011 |
+
foreach( $v as $n=>$j ){
|
1012 |
+
$grpdata[ $k ][ $n ] = $grpdata[ $n ];
|
1013 |
+
unset( $grpdata[ $n ] );
|
1014 |
+
}
|
1015 |
+
}
|
1016 |
}
|
1017 |
+
$grpdata = json_encode( $grpdata );
|
1018 |
+
$menuOptions[] = '<optgroup label="' . $menu->name . '" data-cmw-optgroup-index="' . $i . '" data-cmw-items="' . esc_attr($grpdata) . '">';
|
1019 |
+
$menuOptions[] = implode("\n", $menuGrpOpts);
|
1020 |
+
$menuOptions[] = '</optgroup>';
|
1021 |
}
|
1022 |
+
unset( $menuGrpOpts, $grpdata, $itemindents );
|
1023 |
}
|
1024 |
}
|
1025 |
$menuOptions = implode("\n", $menuOptions);
|
1026 |
echo $menuOptions;
|
1027 |
?>
|
1028 |
</select>
|
1029 |
+
<br /><label>
|
1030 |
+
<input id="<?php echo $this->get_field_id('filter'); ?>_2"
|
1031 |
+
class="widget-<?php echo $this->id_base; ?>-showspecific widget-<?php echo $this->id_base; ?>-listen"
|
1032 |
+
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="-1" <?php checked($instance['filter'], -1); ?> />
|
1033 |
+
<?php _e('Items:'); ?></label>
|
1034 |
+
<input id="<?php echo $this->get_field_id('items'); ?>" class="widget-<?php echo $this->id_base; ?>-setitems"
|
1035 |
+
name="<?php echo $this->get_field_name('items'); ?>" type="text" value="<?php echo $instance['items']; ?>" />
|
1036 |
+
|
1037 |
<select id="<?php echo $this->get_field_id('filter_item_ignore'); ?>" disabled="disabled"
|
1038 |
+
class='cmw-off-the-page' name="<?php echo $this->get_field_name('filter_item_ignore'); ?>">
|
|
|
1039 |
<?php echo $menuOptions; ?>
|
1040 |
</select>
|
1041 |
</p>
|
1042 |
|
1043 |
+
<p class="widget-<?php echo $this->id_base; ?>-disableif-ss">
|
1044 |
<label for="<?php echo $this->get_field_id('start_level'); ?>"><?php _e('Starting Level:'); ?></label>
|
1045 |
<select id="<?php echo $this->get_field_id('start_level'); ?>" name="<?php echo $this->get_field_name('start_level'); ?>">
|
1046 |
<?php
|
1055 |
<br /><small><em><?php _e('Level to start testing items for inclusion'); ?></em></small>
|
1056 |
</p>
|
1057 |
|
1058 |
+
<p class="widget-<?php echo $this->id_base; ?>-disableif-ss">
|
1059 |
<label for="<?php echo $this->get_field_id('depth'); ?>"><?php _e('For Depth:'); ?></label>
|
1060 |
<select id="<?php echo $this->get_field_id('depth'); ?>" name="<?php echo $this->get_field_name('depth'); ?>">
|
1061 |
<option value="0" <?php selected( $instance['depth'], 0 ); ?>><?php _e('unlimited'); ?></option>
|
1068 |
}
|
1069 |
?>
|
1070 |
</select>
|
1071 |
+
<br /><small><em><?php _e('Relative to first Filter item found, <strong>unless</strong>…'); ?></em></small>
|
1072 |
+
<br /><label>
|
1073 |
+
<input id="<?php echo $this->get_field_id('depth_rel_current'); ?>"
|
1074 |
+
name="<?php echo $this->get_field_name('depth_rel_current'); ?>" type="checkbox" value="1"
|
1075 |
+
<?php checked($instance['depth_rel_current']); ?> />
|
1076 |
+
<?php _e('Relative to "Current" Item <small><em>(if found)</em></small>'); ?></label>
|
1077 |
</p>
|
1078 |
<?php $this->_close_a_field_section(); ?>
|
1079 |
|
1083 |
*/
|
1084 |
$this->_open_a_field_section($instance, 'Fallbacks', 'fs_fallbacks');
|
1085 |
?>
|
1086 |
+
<p class="clear widget-<?php echo $this->id_base; ?>-disableifnot-rp">
|
1087 |
+
<small class="cmw-toggle-assist">
|
1088 |
+
<a class="widget-<?php echo $this->id_base; ?>-toggle-assist" href="#"><?php _e('assist'); ?></a>
|
1089 |
+
</small>
|
1090 |
<small><strong><?php _e( 'If "Children of" is <em>Current Root / Parent Item</em>, and no ancestor exists' ); ?> :</strong></small>
|
1091 |
<br /><label>
|
1092 |
<input id="<?php echo $this->get_field_id('fallback_no_ancestor'); ?>"
|
1093 |
name="<?php echo $this->get_field_name('fallback_no_ancestor'); ?>" type="checkbox" value="1"
|
1094 |
<?php checked($instance['fallback_no_ancestor']); ?> />
|
1095 |
<?php _e('Switch to Current Item, and'); ?></label>
|
1096 |
+
<br /><label class="cmw-pad-left-1">
|
1097 |
<input id="<?php echo $this->get_field_id('fallback_include_parent'); ?>"
|
1098 |
name="<?php echo $this->get_field_name('fallback_include_parent'); ?>" type="checkbox" value="1"
|
1099 |
<?php checked($instance['fallback_include_parent']); ?> />
|
1102 |
<input id="<?php echo $this->get_field_id('fallback_include_parent_siblings'); ?>"
|
1103 |
name="<?php echo $this->get_field_name('fallback_include_parent_siblings'); ?>" type="checkbox" value="1"
|
1104 |
<?php checked($instance['fallback_include_parent_siblings']); ?> />
|
1105 |
+
<?php _e('with Siblings'); ?></label>
|
1106 |
</p>
|
1107 |
|
1108 |
+
<p class="widget-<?php echo $this->id_base; ?>-disableifnot-ci">
|
1109 |
<small><strong><?php _e( 'If "Children of" is <em>Current Item</em>, and current item has no children' ); ?> :</strong></small>
|
1110 |
<br /><label>
|
1111 |
<input id="<?php echo $this->get_field_id('fallback_no_children'); ?>"
|
1112 |
name="<?php echo $this->get_field_name('fallback_no_children'); ?>" type="checkbox" value="1"
|
1113 |
<?php checked($instance['fallback_no_children']); ?> />
|
1114 |
<?php _e('Switch to Current Parent Item, and'); ?></label>
|
1115 |
+
<br /><label class="cmw-pad-left-1">
|
1116 |
<input id="<?php echo $this->get_field_id('fallback_nc_include_parent'); ?>"
|
1117 |
name="<?php echo $this->get_field_name('fallback_nc_include_parent'); ?>" type="checkbox" value="1"
|
1118 |
<?php checked($instance['fallback_nc_include_parent']); ?> />
|
1121 |
<input id="<?php echo $this->get_field_id('fallback_nc_include_parent_siblings'); ?>"
|
1122 |
name="<?php echo $this->get_field_name('fallback_nc_include_parent_siblings'); ?>" type="checkbox" value="1"
|
1123 |
<?php checked($instance['fallback_nc_include_parent_siblings']); ?> />
|
1124 |
+
<?php _e('with Siblings'); ?></label>
|
1125 |
</p>
|
1126 |
|
1127 |
|
1133 |
*/
|
1134 |
$this->_open_a_field_section($instance, 'Output', 'fs_output');
|
1135 |
?>
|
|
|
1136 |
<p>
|
1137 |
+
<small class="cmw-toggle-assist">
|
1138 |
+
<a class="widget-<?php echo $this->id_base; ?>-toggle-assist" href="#"><?php _e('assist'); ?></a>
|
1139 |
+
</small>
|
1140 |
<label>
|
1141 |
<input id="<?php echo $this->get_field_id('flat_output'); ?>_0" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
1142 |
type="radio" value="0" <?php checked(!$instance['flat_output']); ?> />
|
1147 |
<?php _e('Flat'); ?></label>
|
1148 |
</p>
|
1149 |
|
1150 |
+
<p>
|
1151 |
+
<label>
|
1152 |
+
<input id="<?php echo $this->get_field_id('contains_current'); ?>"
|
1153 |
+
name="<?php echo $this->get_field_name('contains_current'); ?>" type="checkbox"
|
1154 |
+
value="1" <?php checked($instance['contains_current']); ?> />
|
1155 |
+
<?php _e('Must Contain "Current" Item'); ?></label>
|
1156 |
+
<br /><small><em><?php _e('Checks both Filtered and Included items'); ?></em></small>
|
1157 |
+
</p>
|
1158 |
+
|
1159 |
<p class="widget-<?php echo $this->id_base; ?>-disableif">
|
1160 |
<label>
|
1161 |
<input id="<?php echo $this->get_field_id('include_parent'); ?>"
|
1166 |
<input id="<?php echo $this->get_field_id('include_parent_siblings'); ?>"
|
1167 |
name="<?php echo $this->get_field_name('include_parent_siblings'); ?>" type="checkbox"
|
1168 |
value="1" <?php checked($instance['include_parent_siblings']); ?> />
|
1169 |
+
<?php _e('with Siblings'); ?></label>
|
1170 |
<br /><label>
|
1171 |
<input id="<?php echo $this->get_field_id('include_ancestors'); ?>"
|
1172 |
name="<?php echo $this->get_field_name('include_ancestors'); ?>" type="checkbox"
|
1299 |
</p>
|
1300 |
<?php $this->_close_a_field_section(); ?>
|
1301 |
|
1302 |
+
</div>
|
1303 |
+
|
1304 |
<?php
|
1305 |
} //end form()
|
1306 |
|
1313 |
*/
|
1314 |
function _open_a_field_section( &$instance, $text, $fname ){
|
1315 |
?>
|
1316 |
+
<div class="stuffbox widget-<?php echo $this->id_base; ?>-collapsible-fieldset" title="<?php _e( 'Click to show/hide' ); ?>">
|
1317 |
<input id="<?php echo $this->get_field_id($fname); ?>" class="hidden-field" name="<?php echo $this->get_field_name($fname); ?>"
|
1318 |
type="checkbox" value="1" <?php checked( $instance[$fname] ); ?> />
|
1319 |
+
<div style="background-image:url(images/arrows.png);" class="<?php echo $instance[$fname] ? 'cmw-collapsed-fieldset' : ''; ?>"></div>
|
1320 |
+
<h3><?php _e( $text ); ?></h3>
|
1321 |
</div>
|
1322 |
+
<div class="<?php echo $instance[$fname] ? 'cmw-start-fieldset-collapsed' : ''; ?>">
|
1323 |
<?php
|
1324 |
} //end _open_a_field_section()
|
1325 |
|
1370 |
$instance = shortcode_atts( array(
|
1371 |
'title' => '',
|
1372 |
'menu' => 0, // menu id, slug or name
|
1373 |
+
//determines filter & filter_item ('items' takes precedence over 'children_of' because it's more specific)...
|
1374 |
+
'children_of' => '', // empty = show all (dep. on 'items'); menu item id or title (caseless), or current|current-item|parent|current-parent|root|current-ancestor
|
1375 |
+
'items' => '', // v2.0.0 empty = show all (dep. on 'children_of'); comma- or space-separated list of menu item ids (start level and depth don't apply)
|
1376 |
'start_level' => 1,
|
1377 |
'depth' => 0, // 0 = unlimited
|
1378 |
//only if children_of is (parent|current-parent|root|current-ancestor); determines fallback_no_ancestor, fallback_include_parent & fallback_include_parent_siblings...
|
1379 |
'fallback_parent' => 0, // 1 = use current-item; 'parent' = *and* include parent, 'siblings' = *and* include both parent and its siblings
|
1380 |
//only if children_of is (current|current-item); determines fallback_no_children, fallback_nc_include_parent & fallback_nc_include_parent_siblings...
|
1381 |
'fallback_current' => 0, // 1 = use current-parent; 'parent' = *and* include parent (if available), 'siblings' = *and* include both parent (if available) and its siblings
|
1382 |
+
//switches...
|
1383 |
'flat_output' => 0,
|
1384 |
+
'contains_current' => 0, // v2.0.0
|
1385 |
//determines include_parent, include_parent_siblings & include_ancestors...
|
1386 |
'include' =>'', //comma|space|hyphen separated list of 'parent', 'siblings', 'ancestors'
|
1387 |
'ol_root' => 0,
|
1388 |
'ol_sub' => 0,
|
1389 |
//determines title_from_parent & title_from_current...
|
1390 |
'title_from' => '', //comma|space|hyphen separated list of 'parent', 'current'
|
1391 |
+
'depth_rel_current' => 0, // v2.0.0
|
1392 |
//strings...
|
1393 |
'container' => 'div', // a tag : div|nav are WP restrictions, not the widget's; '' = no container
|
1394 |
'container_id' => '',
|
1426 |
unset( $menus );
|
1427 |
|
1428 |
if( $ok ){
|
|
|
|
|
|
|
|
|
1429 |
$instance['filter'] = $instance['filter_item'] = 0;
|
1430 |
+
if( empty( $instance['items'] ) ){
|
1431 |
+
//children_of => filter & filter_item...
|
1432 |
+
if( empty( $instance['children_of'] ) ){
|
1433 |
+
$instance['children_of'] = '';
|
1434 |
+
}
|
1435 |
+
switch( $instance['children_of'] ){
|
1436 |
+
case '':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1437 |
break;
|
1438 |
+
case 'root': case 'current-ancestor':
|
1439 |
+
--$instance['filter_item']; //ends up as -2
|
1440 |
+
case 'parent': case 'current-parent':
|
1441 |
+
--$instance['filter_item']; //ends up as -1
|
1442 |
+
case 'current': case 'current-item':
|
1443 |
+
$instance['filter'] = 1;
|
1444 |
+
break;
|
1445 |
+
default:
|
1446 |
+
$instance['filter'] = 1;
|
1447 |
+
$instance['filter_item'] = strtolower( $instance['children_of'] );
|
1448 |
+
}
|
1449 |
+
//if filter_item is non-numeric then it could be the title of a menu item, but we need it to be the menu item's id...
|
1450 |
+
if( !is_numeric( $instance['filter_item'] ) ){
|
1451 |
+
foreach( $items as $item ){
|
1452 |
+
$ok = strtolower( $item->title ) == $instance['filter_item'];
|
1453 |
+
if( $ok ){
|
1454 |
+
$instance['filter_item'] = $item->ID;
|
1455 |
+
break;
|
1456 |
+
}
|
1457 |
}
|
1458 |
}
|
1459 |
+
}else{
|
1460 |
+
$instance['filter'] = -1;
|
1461 |
}
|
1462 |
+
unset( $instance['children_of'] );
|
1463 |
}
|
1464 |
|
1465 |
if( $ok ){
|
1532 |
$instance['link_before'] = '<' . $instance['wrap_link_text'] . '>';
|
1533 |
$instance['link_after'] = '</' . $instance['wrap_link_text'] . '>';
|
1534 |
}
|
1535 |
+
|
1536 |
//handle widget_class here because we have full control over $before_widget...
|
1537 |
$before_widget_class = array(
|
1538 |
'widget_custom_menu_wizard',
|
@@ -1,592 +0,0 @@
|
|
1 |
-
<!DOCTYPE html>
|
2 |
-
<html lang="en-GB">
|
3 |
-
<head>
|
4 |
-
<title>Custom Menu Wizard : Interactive Demo</title>
|
5 |
-
<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
|
6 |
-
<script type='text/javascript' src='custom-menu-wizard.js'></script>
|
7 |
-
<style type='text/css'>
|
8 |
-
html, body {width:100%; border:0 none; margin:0; padding:0;}
|
9 |
-
body {font-family:arial,sans-serif; font-size:14px; font-weight:normal; line-height:1.25; color:#333333; background-color:#ffffff;}
|
10 |
-
div, p, h3, ul, ol, li, form, input, select, label, a, code {position:relative;}
|
11 |
-
a {color:#333333; text-decoration:none;}
|
12 |
-
code {color:#000099;}
|
13 |
-
p {margin: 1em 0;}
|
14 |
-
input, select, button {font-family:inherit; font-size:inherit; font-weight:inherit; color:inherit; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box;}
|
15 |
-
select {max-width:100%;}
|
16 |
-
label {vertical-align:middle;}
|
17 |
-
form {display:block; border:1px solid #999999; border-radius:0.5em; margin:0; padding:0;}
|
18 |
-
h3 {border-bottom:1px solid #cccccc;margin:0 0 0.25em; padding: 0.5em 0 0.25em;}
|
19 |
-
button {background-color:#cccccc; border-color:#999999; border-radius:0.4em 0 0.4em 0; border-style:solid; border-width:1px 0 0 1px; bottom:0; color:#000000; cursor:pointer; margin:0; padding:0 0.2em; position:absolute; right:0;}
|
20 |
-
button:hover {background-color:#666666; color:#ffffff;}
|
21 |
-
optgroup option {padding-left:0.75em;}
|
22 |
-
#theform {margin:1em; width:300px;}
|
23 |
-
#formheader {background-color:#666666; border-radius:0.4em 0.4em 0 0; color:#FFFFFF; margin:0 0 -0.5em; padding:0.25em 0; text-align:center;}
|
24 |
-
#formfields {padding:0 1em;}
|
25 |
-
#moreinfo {padding:0.5em 0; text-align:center;}
|
26 |
-
#moreinfo a {color:#0000ee;}
|
27 |
-
#theoutput {margin:1em;}
|
28 |
-
#widget-output {margin:0.5em 0; padding:0 1em; border:1px solid #cccccc; border-radius:0.5em; min-height:2em; min-width:9em;}
|
29 |
-
#widget-output ul, #widget-output ol {margin:0.5em 0 0.5em 1.5em; padding:0;}
|
30 |
-
#widget-output li ul {margin:0 0 0 1em;}
|
31 |
-
#widget-output li ol {margin:0 0 0 1.5em;}
|
32 |
-
#widget-output ul {list-style-type:disc;}
|
33 |
-
#widget-output ul ul {list-style-type:circle;}
|
34 |
-
#widget-output ul ul ul {list-style-type:square;}
|
35 |
-
#widget-output ul ul ul ul {list-style-type:disc;}
|
36 |
-
#widget-output ul ul ul ul ul {list-style-type:circle;}
|
37 |
-
#widget-output ol {list-style-type:decimal;}
|
38 |
-
#widget-output ol ol {list-style-type:upper-alpha;}
|
39 |
-
#widget-output ol ol ol {list-style-type:lower-alpha;}
|
40 |
-
#widget-output ol ol ol ol {list-style-type:lower-roman;}
|
41 |
-
#widget-output ol ol ol ol ol {list-style-type:decimal;}
|
42 |
-
#fallback {display:none; text-align:right; color:#006600;}
|
43 |
-
#fallback.cmw-fellback-to-current, #fallback.cmw-fellback-to-parent {display:block;}
|
44 |
-
#themenu {margin:1em;}
|
45 |
-
#themenu ul {font-size:12px; list-style-type:none; margin:1em 0; padding:0;}
|
46 |
-
#themenu ul ul {margin:0 0 0 5em;}
|
47 |
-
#themenu li {display:block; margin:0; padding:0;}
|
48 |
-
#themenu a {display:inline-block; text-align:center; padding:0.3333em; margin:0.1667em; border-radius:0.3333em;}
|
49 |
-
#themenu span {display:block; width:6em; height:1.75em; line-height:1.75; border:1px solid #999999; border-radius:0.25em; box-shadow:2px 2px 2px 0px #666666;}
|
50 |
-
#thefooter {float:left; clear:left; margin:0 1em; color:#808080;}
|
51 |
-
#thefooter div {font-size:12px;}
|
52 |
-
#theshortcode {color:#333333;}
|
53 |
-
.alignleft {float:left;}
|
54 |
-
.alignright {float:right;}
|
55 |
-
.collapsible {background-color:#ffffff; background-image:-webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e0e0e0)); background-image:-webkit-linear-gradient(top, #FFFFFF, #E0E0E0); background-image:-moz-linear-gradient(top, #FFFFFF, #E0E0E0); background-image:-ms-linear-gradient(top, #FFFFFF, #E0E0E0); background-image:-o-linear-gradient(top, #FFFFFF, #E0E0E0); background-image:linear-gradient(to bottom, #FFFFFF, #E0E0E0); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff, endColorstr=#e0e0e0); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff, endColorstr=#e0e0e0)";border:1px solid #CCCCCC; border-radius:0.3333em; cursor:pointer; font-size:12px; line-height:1.75; padding:0 0.5em;}
|
56 |
-
.collapsible span {display:none; position:relative; float:right; color:#999999;}
|
57 |
-
.collapsible:hover span {color:#333333;}
|
58 |
-
.collapsible span:first-child, .collapsible.closed span:last-child {display:inline;}
|
59 |
-
.collapsible.closed span:first-child {display:none;}
|
60 |
-
.current-menu-ancestor {border-color:#cccc00 !important; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 153, 1)), to(rgba(255, 255, 153, 0.1))); background-image:-webkit-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:-moz-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:-ms-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:-o-linear-gradient(top, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); background-image:linear-gradient(to bottom, rgba(255, 255, 153, 1), rgba(255, 255, 153, 0.1)); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff99, endColorstr=#1affff99); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff99, endColorstr=#1affff99)";}
|
61 |
-
.current-menu-item {border-color:#cc0000 !important; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 204, 204, 1)), to(rgba(255, 204, 204, 0.1))); background-image:-webkit-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:-moz-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:-ms-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:-o-linear-gradient(top, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); background-image:linear-gradient(to bottom, rgba(255, 204, 204, 1), rgba(255, 204, 204, 0.1)); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcccc, endColorstr=#1affcccc); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcccc, endColorstr=#1affcccc)";}
|
62 |
-
.current-menu-parent {border-color:#ff9900 !important; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 204, 153, 1)), to(rgba(255, 204, 153, 0.1))); background-image:-webkit-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:-moz-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:-ms-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:-o-linear-gradient(top, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); background-image:linear-gradient(to bottom, rgba(255, 204, 153, 1), rgba(255, 204, 153, 0.1)); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcc99, endColorstr=#1affcc99); -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffcc99, endColorstr=#1affcc99)";}
|
63 |
-
.grey {color:#999999;}
|
64 |
-
.picked > a {background-color:#000066; color:#ffffff; font-weight:bold;}
|
65 |
-
.tryit {margin-left:1em; text-shadow:1px 1px 1px #ff0000;}
|
66 |
-
.widefat {width:100%;}
|
67 |
-
</style>
|
68 |
-
</head>
|
69 |
-
<body>
|
70 |
-
<div>
|
71 |
-
<div id='theform' class='alignright'>
|
72 |
-
<form>
|
73 |
-
<div id='formheader'>
|
74 |
-
<strong>Custom Menu Wizard</strong> Interactive Demo
|
75 |
-
<br /><small>v1.2.2 <em>(subset of admin options)</em></small><strong class="tryit"><em>Try it out…</em></strong>
|
76 |
-
</div>
|
77 |
-
<div id='formfields'>
|
78 |
-
|
79 |
-
<p>
|
80 |
-
<label for="widget-custom-menu-wizard-2-title">Title:</label>
|
81 |
-
<label class="alignright">
|
82 |
-
<input type="checkbox" value="1" name="hide_title" id="widget-custom-menu-wizard-2-hide_title">
|
83 |
-
Hide</label>
|
84 |
-
<input type="text" value="" name="title" class="widefat" id="widget-custom-menu-wizard-2-title">
|
85 |
-
<small><em>Title can be set, but need not be displayed</em></small>
|
86 |
-
</p>
|
87 |
-
|
88 |
-
<p class='collapsible'>Filter<span>▲</span><span>▼</span></p>
|
89 |
-
|
90 |
-
<p>
|
91 |
-
<label>
|
92 |
-
<input type="radio" checked="checked" value="0" name="filter" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_0">
|
93 |
-
Show all</label>
|
94 |
-
<br /><label>
|
95 |
-
<input type="radio" value="1" name="filter" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_1">
|
96 |
-
Children of:</label>
|
97 |
-
<select name="filter_item" style="max-width:100%;" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_item">
|
98 |
-
<option selected="selected" value="0">Current Item</option>
|
99 |
-
<option value="-2">Current Root Item</option>
|
100 |
-
<option value="-1">Current Parent Item</option>
|
101 |
-
<optgroup label="the-menu"></optgroup>
|
102 |
-
</select>
|
103 |
-
</p>
|
104 |
-
|
105 |
-
<p>
|
106 |
-
<label for="widget-custom-menu-wizard-2-start_level">Starting Level:</label>
|
107 |
-
<select name="start_level" id="widget-custom-menu-wizard-2-start_level">
|
108 |
-
</select>
|
109 |
-
<br /><small><em>Level to start testing items for inclusion</em></small>
|
110 |
-
</p>
|
111 |
-
|
112 |
-
<p>
|
113 |
-
<label for="widget-custom-menu-wizard-2-depth">For Depth:</label>
|
114 |
-
<select name="depth" id="widget-custom-menu-wizard-2-depth">
|
115 |
-
<option selected="selected" value="0">unlimited</option>
|
116 |
-
</select>
|
117 |
-
<br /><small><em>Relative to the first Filtered item found</em></small>
|
118 |
-
</p>
|
119 |
-
|
120 |
-
<p class='collapsible end-collapsible'>Fallbacks<span>▲</span><span>▼</span></p>
|
121 |
-
|
122 |
-
<p class="widget-custom-menu-wizard-disableifnot-rp">
|
123 |
-
<small><strong>If "Children of" is <em>Current Root / Parent Item</em>, and no ancestor exists :</strong></small>
|
124 |
-
<br /><label>
|
125 |
-
<input type="checkbox" value="1" name="fallback_no_ancestor" id="widget-custom-menu-wizard-2-fallback_no_ancestor">
|
126 |
-
Switch to Current Item, and</label>
|
127 |
-
<br /><label style="padding-left:1em;">
|
128 |
-
<input type="checkbox" value="1" name="fallback_include_parent" id="widget-custom-menu-wizard-2-fallback_include_parent">
|
129 |
-
Include Parent... </label>
|
130 |
-
<label>
|
131 |
-
<input type="checkbox" value="1" name="fallback_include_parent_siblings" id="widget-custom-menu-wizard-2-fallback_include_parent_siblings">
|
132 |
-
& its Siblings</label>
|
133 |
-
<br /><small><em>If Current Root/Parent and no ancestor exists</em></small>
|
134 |
-
</p>
|
135 |
-
|
136 |
-
<p class="widget-custom-menu-wizard-disableifnot-ci">
|
137 |
-
<small><strong>If "Children of" is <em>Current Item</em>, and current item has no children :</strong></small>
|
138 |
-
<br /><label>
|
139 |
-
<input type="checkbox" value="1" name="fallback_no_children" id="widget-custom-menu-wizard-2-fallback_no_children">
|
140 |
-
Switch to Current Parent Item, and</label>
|
141 |
-
<br /><label style="padding-left:1em;">
|
142 |
-
<input type="checkbox" value="1" name="fallback_nc_include_parent" id="widget-custom-menu-wizard-2-fallback_nc_include_parent">
|
143 |
-
Include Parent... </label>
|
144 |
-
<label>
|
145 |
-
<input type="checkbox" value="1" name="fallback_nc_include_parent_siblings" id="widget-custom-menu-wizard-2-fallback_nc_include_parent_siblings">
|
146 |
-
& its Siblings</label>
|
147 |
-
</p>
|
148 |
-
|
149 |
-
<p class='collapsible end-collapsible'>Output<span>▲</span><span>▼</span></p>
|
150 |
-
|
151 |
-
<p>
|
152 |
-
<label>
|
153 |
-
<input type="radio" checked="checked" value="0" name="flat_output" id="widget-custom-menu-wizard-2-flat_output_0">
|
154 |
-
Hierarchical</label>
|
155 |
-
<label>
|
156 |
-
<input type="radio" value="1" name="flat_output" id="widget-custom-menu-wizard-2-flat_output_1">
|
157 |
-
Flat</label>
|
158 |
-
</p>
|
159 |
-
|
160 |
-
<p class="widget-custom-menu-wizard-disableif">
|
161 |
-
<label>
|
162 |
-
<input type="checkbox" value="1" name="include_parent" id="widget-custom-menu-wizard-2-include_parent">
|
163 |
-
Include Parent... </label>
|
164 |
-
<label>
|
165 |
-
<input type="checkbox" value="1" name="include_parent_siblings" id="widget-custom-menu-wizard-2-include_parent_siblings">
|
166 |
-
& its Siblings</label>
|
167 |
-
<br /><label>
|
168 |
-
<input type="checkbox" value="1" name="include_ancestors" id="widget-custom-menu-wizard-2-include_ancestors">
|
169 |
-
Include Ancestors</label>
|
170 |
-
<br /><label>
|
171 |
-
<input type="checkbox" value="1" name="title_from_parent" id="widget-custom-menu-wizard-2-title_from_parent">
|
172 |
-
Title from Parent</label>
|
173 |
-
<br /><small><em>Only if the "Children of" Filter returns items</em></small>
|
174 |
-
</p>
|
175 |
-
|
176 |
-
<p>
|
177 |
-
<label>
|
178 |
-
<input type="checkbox" value="1" name="title_from_current" id="widget-custom-menu-wizard-2-title_from_current">
|
179 |
-
Title from "Current" Item</label>
|
180 |
-
<br /><small><em>Lower priority than "Title from Parent"</em></small>
|
181 |
-
</p>
|
182 |
-
|
183 |
-
<p>
|
184 |
-
Change UL to OL:
|
185 |
-
<br /><label>
|
186 |
-
<input type="checkbox" value="1" name="ol_root" id="widget-custom-menu-wizard-2-ol_root">
|
187 |
-
Top Level</label>
|
188 |
-
<label>
|
189 |
-
<input type="checkbox" value="1" name="ol_sub" id="widget-custom-menu-wizard-2-ol_sub">
|
190 |
-
Sub-Levels</label>
|
191 |
-
</p>
|
192 |
-
|
193 |
-
<p class="grey end-collapsible">
|
194 |
-
<small><em>Note that since WP v3.6 does it automatically,
|
195 |
-
<br />"Hide Widget if Empty" is ON for this demo.</em></small>
|
196 |
-
</p>
|
197 |
-
|
198 |
-
</div>
|
199 |
-
<button title="Reset the form to its defaults...">reset</button>
|
200 |
-
</form>
|
201 |
-
|
202 |
-
<div id="moreinfo">
|
203 |
-
<small>Doc.:
|
204 |
-
<a href="http://wordpress.org/plugins/custom-menu-wizard/" target='_blank'>wordpress.org/plugins/custom-menu-wizard/</a>
|
205 |
-
</small>
|
206 |
-
</div>
|
207 |
-
|
208 |
-
</div>
|
209 |
-
|
210 |
-
<div id='theoutput' class='alignright'>
|
211 |
-
<strong>Basic Output</strong> …
|
212 |
-
<div id='widget-output'></div>
|
213 |
-
<div id='fallback'><small>Fallback invoked</small></div>
|
214 |
-
</div>
|
215 |
-
|
216 |
-
<div id='themenu' class='alignleft'>
|
217 |
-
<div>
|
218 |
-
<strong>"Selected" Menu</strong> <small class='grey'>(example)</small>
|
219 |
-
<small><em>Click an item to toggle "Current Item"</em></small>
|
220 |
-
</div>
|
221 |
-
<ul>
|
222 |
-
<li>
|
223 |
-
<a href='#'><span>alpha</span></a>
|
224 |
-
<ul>
|
225 |
-
<li>
|
226 |
-
<a href='#'><span>bravo</span></a>
|
227 |
-
</li>
|
228 |
-
<li>
|
229 |
-
<a href='#'><span>charlie</span></a>
|
230 |
-
<ul>
|
231 |
-
<li>
|
232 |
-
<a href='#'><span>delta</span></a>
|
233 |
-
<ul>
|
234 |
-
<li>
|
235 |
-
<a href='#'><span>echo</span></a>
|
236 |
-
<ul>
|
237 |
-
<li>
|
238 |
-
<a href='#'><span>foxtrot</span></a>
|
239 |
-
</li>
|
240 |
-
<li>
|
241 |
-
<a href='#'><span>golf</span></a>
|
242 |
-
</li>
|
243 |
-
</ul>
|
244 |
-
</li>
|
245 |
-
</ul>
|
246 |
-
</li>
|
247 |
-
<li>
|
248 |
-
<a href='#'><span>hotel</span></a>
|
249 |
-
<ul>
|
250 |
-
<li>
|
251 |
-
<a href='#'><span>india</span></a>
|
252 |
-
<ul>
|
253 |
-
<li>
|
254 |
-
<a href='#'><span>juliet</span></a>
|
255 |
-
</li>
|
256 |
-
</ul>
|
257 |
-
</li>
|
258 |
-
</ul>
|
259 |
-
</li>
|
260 |
-
</ul>
|
261 |
-
</li>
|
262 |
-
<li>
|
263 |
-
<a href='#'><span>kilo</span></a>
|
264 |
-
</li>
|
265 |
-
</ul>
|
266 |
-
</li>
|
267 |
-
<li>
|
268 |
-
<a href='#'><span>lima</span></a>
|
269 |
-
<ul>
|
270 |
-
<li>
|
271 |
-
<a href='#'><span>mike</span></a>
|
272 |
-
<ul>
|
273 |
-
<li>
|
274 |
-
<a href='#'><span>november</span></a>
|
275 |
-
</li>
|
276 |
-
</ul>
|
277 |
-
</li>
|
278 |
-
</ul>
|
279 |
-
</li>
|
280 |
-
<li>
|
281 |
-
<a href='#'><span>oscar</span></a>
|
282 |
-
</li>
|
283 |
-
</ul>
|
284 |
-
</div>
|
285 |
-
|
286 |
-
<div id='thefooter'>
|
287 |
-
<div id='theshortcode'>Shortcode : <code id='shortcode'></code></div>
|
288 |
-
<div>
|
289 |
-
Please note that this page is a simulator : it uses javascript to reproduce what the widget
|
290 |
-
would do, without interacting with WordPress in any way.
|
291 |
-
</div>
|
292 |
-
</div>
|
293 |
-
|
294 |
-
</div>
|
295 |
-
<script type='text/javascript'>
|
296 |
-
jQuery(function($){
|
297 |
-
var maxlevel = 0,
|
298 |
-
switches = {hide_title:1, filter:1, fallback_no_ancestor:1, fallback_include_parent:1, fallback_include_parent_siblings:1, fallback_no_children:1, fallback_nc_include_parent:1, fallback_nc_include_parent_siblings:1, flat_output:1, include_parent:1, include_parent_siblings:1, include_ancestors:1, title_from_parent:1, title_from_current:1, ol_root:1, ol_sub:1},
|
299 |
-
integers = {filter_item:1, start_level:1, depth:1},
|
300 |
-
getSettings = function(){
|
301 |
-
var settings = {};
|
302 |
-
$.each($('form').serializeArray(), function(i, v){
|
303 |
-
settings[v.name] = switches[v.name] ? v.value === '1' : (integers[v.name] ? parseInt(v.value, 10) : v.value);
|
304 |
-
});
|
305 |
-
return settings;
|
306 |
-
},
|
307 |
-
hyphenIndent = function(s, n){
|
308 |
-
while(--n){
|
309 |
-
s = '- ' + s;
|
310 |
-
}
|
311 |
-
return s;
|
312 |
-
},
|
313 |
-
shortcode = function(settings){
|
314 |
-
var args = {
|
315 |
-
'menu' : 'example',
|
316 |
-
},
|
317 |
-
v, n;
|
318 |
-
if(settings.title){
|
319 |
-
args.title = settings.title;
|
320 |
-
}
|
321 |
-
if(settings.filter){
|
322 |
-
switch(settings.filter_item){
|
323 |
-
case 0: args.children_of = 'current'; break;
|
324 |
-
case -1: args.children_of = 'parent'; break;
|
325 |
-
case -2: args.children_of = 'root'; break;
|
326 |
-
default:
|
327 |
-
args.children_of = $('#themenu a').eq(settings.filter_item - 1).text();
|
328 |
-
}
|
329 |
-
}
|
330 |
-
if(settings.filter && settings.filter_item < 0 && settings.fallback_no_ancestor){
|
331 |
-
if(settings.fallback_include_parent_siblings){
|
332 |
-
args.fallback_parent = 'siblings';
|
333 |
-
}else if(settings.fallback_include_parent){
|
334 |
-
args.fallback_parent = 'parent';
|
335 |
-
}else{
|
336 |
-
args.fallback_parent = [1];
|
337 |
-
}
|
338 |
-
}
|
339 |
-
if(settings.filter && !settings.filter_item && settings.fallback_no_children){
|
340 |
-
if(settings.fallback_nc_include_parent_siblings){
|
341 |
-
args.fallback_current = 'siblings';
|
342 |
-
}else if(settings.fallback_nc_include_parent){
|
343 |
-
args.fallback_current = 'parent';
|
344 |
-
}else{
|
345 |
-
args.fallback_current = [1];
|
346 |
-
}
|
347 |
-
}
|
348 |
-
if(settings.start_level > 1){
|
349 |
-
args.start_level = [settings.start_level];
|
350 |
-
}
|
351 |
-
if(settings.depth > 0){
|
352 |
-
args.depth = [settings.depth];
|
353 |
-
}
|
354 |
-
n = [];
|
355 |
-
if(settings.filter){
|
356 |
-
if(settings.include_parent_siblings){
|
357 |
-
n.push('siblings');
|
358 |
-
}else if(settings.include_parent){
|
359 |
-
n.push('parent')
|
360 |
-
}
|
361 |
-
if(settings.include_ancestors){
|
362 |
-
n.push('ancestors');
|
363 |
-
}
|
364 |
-
if(n.length){
|
365 |
-
args.include = n.join(' ');
|
366 |
-
}
|
367 |
-
}
|
368 |
-
n = [];
|
369 |
-
if(settings.filter && settings.title_from_parent){
|
370 |
-
n.push('parent');
|
371 |
-
}
|
372 |
-
if(settings.title_from_current){
|
373 |
-
n.push('current');
|
374 |
-
}
|
375 |
-
if(n.length){
|
376 |
-
args.title_from = n.join(' ');
|
377 |
-
}
|
378 |
-
for(n in {flat_output:1, ol_root:1, ol_sub:1}){
|
379 |
-
if(settings[n]){
|
380 |
-
args[n] = [1];
|
381 |
-
}
|
382 |
-
}
|
383 |
-
v = [];
|
384 |
-
for(n in args){
|
385 |
-
v.push( $.isArray(args[n]) ? n + '=' + args[n][0] : n + '="' + args[n] + '"' );
|
386 |
-
}
|
387 |
-
$('code').text('[custom_menu_wizard ' + v.join(' ') + ']');
|
388 |
-
},
|
389 |
-
show = function(e, settings){
|
390 |
-
//hide_empty is assumed to be on (WP < v3.6) or will automatically on (WP v3.6+)
|
391 |
-
var output = $('#widget-output').empty(),
|
392 |
-
items = $('.picked'),
|
393 |
-
html = '',
|
394 |
-
title = '',
|
395 |
-
currLevel = 0,
|
396 |
-
startLevel;
|
397 |
-
settings = settings || getSettings();
|
398 |
-
if(items.length){
|
399 |
-
if(settings.filter && settings.title_from_parent){
|
400 |
-
title = $('.the-parent').children('a').text() || '';
|
401 |
-
}
|
402 |
-
if(!title && settings.title_from_current){
|
403 |
-
title = $('.current-menu-item').text() || '';
|
404 |
-
}
|
405 |
-
if(!title && !settings.hide_title){
|
406 |
-
title = settings.title || '';
|
407 |
-
}
|
408 |
-
items.each(function(){
|
409 |
-
var level = settings.flat_output ? 1 : parseInt(this.className.match(/level-(\d+)/)[1], 10),
|
410 |
-
anchor = $(this).children('a');
|
411 |
-
if(currLevel){
|
412 |
-
if(level > currLevel){
|
413 |
-
html += settings.ol_sub ? '<ol>' : '<ul>';
|
414 |
-
}else{
|
415 |
-
while(currLevel > level){
|
416 |
-
--currLevel;
|
417 |
-
html += '</li>' + (settings.ol_sub ? '</ol>' : '</ul>');
|
418 |
-
}
|
419 |
-
html += '</li>';
|
420 |
-
}
|
421 |
-
}else{
|
422 |
-
startLevel = level;
|
423 |
-
}
|
424 |
-
html += '<li class="cmw-level-' + (level - startLevel + 1) + ($(this).data().included || '') + '"><a href="#' + anchor.data('indx') + '">' + anchor.text() + '</a>';
|
425 |
-
currLevel = level;
|
426 |
-
});
|
427 |
-
while(currLevel > startLevel){
|
428 |
-
--currLevel;
|
429 |
-
html += '</li>' + (settings.ol_sub ? '</ol>' : '</ul>');
|
430 |
-
}
|
431 |
-
html += '</li>';
|
432 |
-
output.html( (settings.ol_root ? '<ol' : '<ul') + ' class="' + $.trim( 'menu-widget ' + ($('#fallback').get(0).className || '') ) + '">' + html + (settings.ol_root ? '</ol>' : '</ul>') );
|
433 |
-
if(title){
|
434 |
-
output.prepend('<h3>' + title + '</h3>');
|
435 |
-
}
|
436 |
-
output.find('li').filter(function(){
|
437 |
-
return !!$(this).children('ul, ol').length;
|
438 |
-
}).addClass('cmw-has-submenu');
|
439 |
-
}
|
440 |
-
shortcode(settings);
|
441 |
-
},
|
442 |
-
walk = function(e){
|
443 |
-
var settings = getSettings(),
|
444 |
-
includeParent = settings.include_parent,
|
445 |
-
includeParentSiblings = settings.include_parent_siblings,
|
446 |
-
items = $('#themenu li').removeData('included').removeClass('the-parent'),
|
447 |
-
picked = items.filter('.picked'),
|
448 |
-
cls = [],
|
449 |
-
firstParent = true,
|
450 |
-
fallback, parent, i;
|
451 |
-
if(!settings.filter){
|
452 |
-
//show all...
|
453 |
-
for(i = 1; i < settings.start_level; i++){
|
454 |
-
items = items.not('.level-' + i);
|
455 |
-
}
|
456 |
-
if(settings.depth){
|
457 |
-
for(i = i + settings.depth; i < maxlevel + 1; i++){
|
458 |
-
items = items.not('.level-' + i);
|
459 |
-
}
|
460 |
-
}
|
461 |
-
}else{
|
462 |
-
//parent item...
|
463 |
-
if(settings.filter_item > 0){
|
464 |
-
parent = items.eq(settings.filter_item - 1);
|
465 |
-
}else if(!settings.filter_item){
|
466 |
-
parent = $('.current-menu-item').closest('li');
|
467 |
-
}else{
|
468 |
-
if(settings.filter_item < -1){
|
469 |
-
//this could be more than one!...
|
470 |
-
parent = $('.current-menu-ancestor').closest('li');
|
471 |
-
}else{
|
472 |
-
parent = $('.current-menu-parent').closest('li');
|
473 |
-
}
|
474 |
-
if(!parent.length && settings.fallback_no_ancestor){
|
475 |
-
parent = $('.current-menu-item').closest('li');
|
476 |
-
includeParent = includeParent || settings.fallback_include_parent;
|
477 |
-
includeParentSiblings = includeParentSiblings || settings.fallback_include_parent_siblings;
|
478 |
-
if(parent.length){
|
479 |
-
fallback = 'cmw-fellback-to-current';
|
480 |
-
}
|
481 |
-
}
|
482 |
-
}
|
483 |
-
//could be multiple - only want first one that matches start_level...
|
484 |
-
parent = parent.filter(function(){
|
485 |
-
var level = parseInt(this.className.match(/level-(\d+)/)[1], 10),
|
486 |
-
rtn = firstParent && level > settings.start_level - 2,
|
487 |
-
i, j;
|
488 |
-
for(i = level + 1, j = 0; rtn && i <= maxlevel && (!settings.depth || j < settings.depth); i++, j++){
|
489 |
-
cls.push('.level-' + i);
|
490 |
-
}
|
491 |
-
if(rtn){
|
492 |
-
firstParent = false;
|
493 |
-
}
|
494 |
-
return rtn;
|
495 |
-
});
|
496 |
-
//kids...
|
497 |
-
items = parent.find('li').filter( cls.join(',') );
|
498 |
-
//...if current item is looked for and found, but has no kids, and fallback is set...
|
499 |
-
if(parent.length && !settings.filter_item && !items.length && settings.fallback_no_children){
|
500 |
-
items = parent.siblings('li').add( parent );
|
501 |
-
includeParent = includeParent || settings.fallback_nc_include_parent;
|
502 |
-
includeParentSiblings = includeParentSiblings || settings.fallback_nc_include_parent_siblings;
|
503 |
-
parent = parent.parents('li').eq(0);
|
504 |
-
if(parent.length){
|
505 |
-
fallback = 'cmw-fellback-to-parent';
|
506 |
-
}
|
507 |
-
}
|
508 |
-
if(items.length){
|
509 |
-
if(includeParentSiblings){
|
510 |
-
items = items.add( parent.siblings('li').data('included', ' cmw-an-included-parent-sibling') ).add( parent );
|
511 |
-
includeParent = true;
|
512 |
-
}
|
513 |
-
if(settings.include_ancestors){
|
514 |
-
items = items.add( parent.parentsUntil('#themenu', 'li').data('included', ' cmw-an-included-ancestor') ).add( parent );
|
515 |
-
includeParent = true;
|
516 |
-
}
|
517 |
-
if(includeParent){
|
518 |
-
items = items.add( parent.data('included', ' cmw-the-included-parent') );
|
519 |
-
}
|
520 |
-
parent.addClass('the-parent');
|
521 |
-
}
|
522 |
-
}
|
523 |
-
$('#fallback').removeClass();
|
524 |
-
if(items.length && fallback){
|
525 |
-
$('#fallback').addClass(fallback);
|
526 |
-
}
|
527 |
-
picked.not(items).removeClass('picked');
|
528 |
-
items.addClass('picked');
|
529 |
-
show.call(this, e, settings);
|
530 |
-
},
|
531 |
-
flds = $('input,select');
|
532 |
-
$('#themenu a').on('click', function(){
|
533 |
-
//click on a #themenu item to [un]make it the current item...
|
534 |
-
var cls = ['current-menu-item', 'current-menu-parent', 'current-menu-ancestor'],
|
535 |
-
inPath = $(this).find('span').not('.' + cls[0]).parentsUntil('#themenu', 'li'),
|
536 |
-
i, n;
|
537 |
-
$('.' + cls.join(',.')).removeClass().removeAttr('title');
|
538 |
-
for(i = 0; i < inPath.length; i++){
|
539 |
-
n = i === 1 ? cls.join(' ') : cls[0];
|
540 |
-
inPath.eq(i).children('a').find('span').addClass(n).attr({title:n.replace(' ', ' & ').replace(/-/g, ' ')});
|
541 |
-
if(cls.length > 1){
|
542 |
-
cls.shift();
|
543 |
-
}
|
544 |
-
}
|
545 |
-
flds.eq(0).trigger('change');
|
546 |
-
return false;
|
547 |
-
}).map(function(i){
|
548 |
-
//create filter_item's optgroup options...
|
549 |
-
var el = $(this).data('indx', i),
|
550 |
-
level = el.parentsUntil('#themenu', 'li').length;
|
551 |
-
maxlevel = Math.max(maxlevel, level);
|
552 |
-
el.parent().addClass('level-' + level);
|
553 |
-
return $('<option/>', {value:i + 1}).text( hyphenIndent(el.text(), level) ).get(0);
|
554 |
-
}).appendTo('optgroup');
|
555 |
-
//allow setting current from widget output (only setting, not un-setting!)...
|
556 |
-
$('#widget-output').on('click', 'a', function(){
|
557 |
-
var indx = this.href.split('#')[1];
|
558 |
-
$('#themenu a').eq(indx).not(':has(.current-menu-item)').trigger('click');
|
559 |
-
return false;
|
560 |
-
});
|
561 |
-
//populate starting-level and depth options...
|
562 |
-
for(i = 1; i < maxlevel + 1; i++){
|
563 |
-
var levels = i < 2 ? ' level' : ' levels',
|
564 |
-
att = {value:i};
|
565 |
-
$('<option/>', att).text(i + levels).appendTo('#widget-custom-menu-wizard-2-depth');
|
566 |
-
if(i < 2){
|
567 |
-
att.selected = 'selected';
|
568 |
-
}
|
569 |
-
$('<option/>', att).text(i).appendTo('#widget-custom-menu-wizard-2-start_level');
|
570 |
-
}
|
571 |
-
//interactivity (need to ensure that any delegated handlers from the included script get run first)...
|
572 |
-
flds.not( flds.filter('[type="text"]').on('blur', show) ).addClass('demo-change');
|
573 |
-
$(document).on('change', '.demo-change', walk);
|
574 |
-
//reset...
|
575 |
-
$('button').on('click', function(){
|
576 |
-
$('form').get(0).reset();
|
577 |
-
$('#widget-custom-menu-wizard-2-filter_item').trigger('change');
|
578 |
-
return false;
|
579 |
-
}).trigger('click');
|
580 |
-
//collapsibles...
|
581 |
-
$('.collapsible').on('click', function(){
|
582 |
-
var Self = $(this)
|
583 |
-
data = Self.data();
|
584 |
-
Self.toggleClass('closed', !data.closed).nextUntil('.end-collapsible')[data.closed ? 'slideDown' : 'slideUp']();
|
585 |
-
data.closed = !data.closed;
|
586 |
-
this.blur();
|
587 |
-
return false;
|
588 |
-
}).slice(1).trigger('click');
|
589 |
-
});
|
590 |
-
</script>
|
591 |
-
</body>
|
592 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -3,10 +3,10 @@ Contributors: wizzud
|
|
3 |
Tags: menu,widget,widgets,navigation,nav,custom menus,custom menu,partial menu,menu level,menu branch
|
4 |
Requires at least: 3.0.1
|
5 |
Tested up to: 3.6
|
6 |
-
Stable tag:
|
7 |
License: GPLv2 or Later
|
8 |
|
9 |
-
|
10 |
|
11 |
== Description ==
|
12 |
|
@@ -28,11 +28,14 @@ Features include:
|
|
28 |
* Use Ordered Lists (OL) for the top and/or sub levels instead of Unordered Lists (UL)
|
29 |
* *As of v1.1.0* : Select a branch based on the ultimate ancestor (root level) of the "current" item
|
30 |
* *As of v1.2.0* : Shortcode, [custom_menu_wizard], available to run the widget from within content
|
|
|
|
|
|
|
31 |
|
32 |
-
|
33 |
-
|
34 |
|
35 |
-
|
36 |
|
37 |
There are quite a few options, which makes the widget settings box very long. I have therefore grouped most of the options into
|
38 |
logical sections and made each section collapsible (with remembered state once saved). As of v1.2.1, only the Filter section is
|
@@ -78,21 +81,37 @@ open by default; all sections below that start off collapsed.
|
|
78 |
|
79 |
If you change `Select Menu`, the options presented in this dropdown will change accordingly and the selected option will revert to the default.
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
* **Starting Level** *(select, default: "1")*
|
82 |
|
83 |
This is the level within the chosen menu (from `Select Menu`) that the widget will start looking for items to keep. Obviously, level 1
|
84 |
is the root level (ie. those items that have no parent item); level 2 is all the immediate children of the root level items, and so on.
|
85 |
Note that for a `Children of` filter there is no difference between level 1 and level 2 (because there are no children at level 1).
|
|
|
86 |
|
87 |
* **For Depth** *(select, default: "unlimited")*
|
88 |
|
89 |
This is the maximum depth of the eventual output structure after filtering, and in the case of `Flat` output being requested it is
|
90 |
still applied - as if the output were `Hierarchical` and then flattened at the very last moment.
|
91 |
|
92 |
-
You need to be aware that the
|
93 |
`For Depth` setting is applied relative to the level at which the first item to be kept is found. For example, say you were to set
|
94 |
`Children of` to "Current Item", `Starting Level` to "2", and `For Depth` to "2 levels" : if the current item was found at level 3,
|
95 |
then you would get the current item's immediate children (from level 4), plus *their* immediate children (from level 5).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
* **Fallbacks**
|
98 |
|
@@ -156,6 +175,10 @@ open by default; all sections below that start off collapsed.
|
|
156 |
Output in a single list format, ignoring any parent-child relationship other than to maintain the same physical order as would be
|
157 |
presented in a `Hierarchical` output.
|
158 |
|
|
|
|
|
|
|
|
|
159 |
* **Include Parent...** *(checkbox)*
|
160 |
|
161 |
If checked, include the parent item in the output. Only applies to a successful `Children of` filter.
|
@@ -250,12 +273,13 @@ open by default; all sections below that start off collapsed.
|
|
250 |
|
251 |
Text or HTML that will be placed immediately after each menu item's link text.
|
252 |
|
253 |
-
|
|
|
|
|
|
|
254 |
|
255 |
-
The shortcode is
|
256 |
-
|
257 |
-
Please note that the `Hide Widget if Empty` option is not available to the shortcode : it is set to enabled, and if there are no menu items
|
258 |
-
found then there will be no output from the shortcode.
|
259 |
|
260 |
* **title** *(string)*
|
261 |
|
@@ -268,7 +292,8 @@ found then there will be no output from the shortcode.
|
|
268 |
|
269 |
* **children_of** *(string | integer)*
|
270 |
|
271 |
-
If empty
|
|
|
272 |
|
273 |
* If numeric, it is taken as being the id of a menu item. The widget will look for the `Children of` that menu item (within `menu`).
|
274 |
(Hint : In Menus Admin, hover over the item's **Remove** link and note the number after *menu-item=* in the URL)
|
@@ -283,7 +308,10 @@ found then there will be no output from the shortcode.
|
|
283 |
|
284 |
* If any other string, it is taken to be the title of a menu item. The widget will look for the `Children of` that menu item
|
285 |
(within `menu`). Please note that the code looks for a *caseless* title match, so specifying `children_of="my menu item"` will
|
286 |
-
match against a menu item with the title "My Menu Item".
|
|
|
|
|
|
|
287 |
|
288 |
* **fallback_parent** *(string | integer)*
|
289 |
|
@@ -310,9 +338,13 @@ found then there will be no output from the shortcode.
|
|
310 |
* **start_level** *(integer, default 1)* See widget's `Starting Level` option, under **Filter** above.
|
311 |
|
312 |
* **depth** *(integer, default 0)* See widget's `For Depth` option, under **Filter** above.
|
|
|
|
|
313 |
|
314 |
* **flat_output** *(switch, off by default, 1 to enable)* See widget's `Flat` option, under **Output** above.
|
315 |
|
|
|
|
|
316 |
* **include** *(string)*
|
317 |
|
318 |
* *'parent'* : Enables widget's `Include Parent...` **Output** option
|
@@ -347,13 +379,13 @@ found then there will be no output from the shortcode.
|
|
347 |
|
348 |
* **wrap_link** *(string)*
|
349 |
|
350 |
-
This is an optional tag name (eg. *'div'*, *'p'*, *'span*
|
351 |
and sent through to the widget as its `Before the Link` and `After the Link` options. Please note that the shortcode usage - a simple
|
352 |
tag name - is much more restrictive than the widget's options, which allow HTML.
|
353 |
|
354 |
* **wrap_link_text** *(string)*
|
355 |
|
356 |
-
This is an optional tag name (eg. *'span
|
357 |
and sent through to the widget as its `Before the Link Text` and `After the Link Text` options. Please note that the shortcode usage - a
|
358 |
simple tag name - is much more restrictive than the widget's options, which allow HTML.
|
359 |
|
@@ -361,15 +393,21 @@ found then there will be no output from the shortcode.
|
|
361 |
|
362 |
* Show the entire "main" menu :
|
363 |
|
364 |
-
`
|
|
|
|
|
365 |
|
366 |
* Show the children of the Current Item within the "main" menu, for unlimited depth, and include the Current Item's parent :
|
367 |
|
368 |
-
`
|
|
|
|
|
369 |
|
370 |
* From the "animals" menu, show all the items *immediately* below (depth=1) "Small Dogs", plus "Small Dogs" and its sibling items, as ordered lists :
|
371 |
|
372 |
-
`
|
|
|
|
|
373 |
|
374 |
== Installation ==
|
375 |
|
@@ -380,11 +418,56 @@ found then there will be no output from the shortcode.
|
|
380 |
1. Activate the plugin through the 'Plugins' menu in your WP Admin
|
381 |
|
382 |
The widget will now be available in the 'Widgets' admin page.
|
383 |
-
As long as you already have at least one Menu defined, you can add the new widget to a sidebar and configure it however you want.
|
|
|
384 |
|
385 |
== Frequently Asked Questions ==
|
386 |
|
387 |
-
If you have a question or problem, please use the integrated Support forum.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
|
389 |
== Screenshots ==
|
390 |
|
@@ -394,10 +477,26 @@ If you have a question or problem, please use the integrated Support forum.
|
|
394 |
|
395 |
3. Even more widget options
|
396 |
|
397 |
-
4.
|
398 |
|
399 |
== Changelog ==
|
400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
= 1.2.2 =
|
402 |
|
403 |
* bugfix : fallback for Current Item with no children was failing because the parent's children weren't being picked out correctly
|
@@ -414,7 +513,7 @@ If you have a question or problem, please use the integrated Support forum.
|
|
414 |
|
415 |
* in demo.html, added a link to the documentation page
|
416 |
|
417 |
-
* corrected 2 of the shortcode examples in the readme.txt, and made emulator (
|
418 |
|
419 |
= 1.2.0 =
|
420 |
|
@@ -434,7 +533,7 @@ If you have a question or problem, please use the integrated Support forum.
|
|
434 |
|
435 |
* added 'Current Root Item' and 'Current Parent Item' to the `Children of` filter
|
436 |
|
437 |
-
* added `Fallback to Current Item` option, with
|
438 |
|
439 |
* added an Output option to include both the parent item **and** the parent's siblings (for a successful `Children of` filter)
|
440 |
|
@@ -456,6 +555,23 @@ Initial release
|
|
456 |
|
457 |
== Upgrade Notice ==
|
458 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
459 |
= 1.2.1 =
|
460 |
|
461 |
Added a few extra custom classes, and changed the defaults for new widgets such that only the Filter section is open by default.
|
@@ -464,6 +580,6 @@ Fixed a couple of the shortcode examples in the readme.txt, and added display of
|
|
464 |
|
465 |
= 1.2.0 =
|
466 |
|
467 |
-
Added custom_menu_wizard shortcode, to run the widget from within content.
|
468 |
-
|
469 |
-
after the widget has been saved (also affected disabled fields and styling).
|
3 |
Tags: menu,widget,widgets,navigation,nav,custom menus,custom menu,partial menu,menu level,menu branch
|
4 |
Requires at least: 3.0.1
|
5 |
Tested up to: 3.6
|
6 |
+
Stable tag: 2.0.0
|
7 |
License: GPLv2 or Later
|
8 |
|
9 |
+
Show branches or levels of your menu in a widget, or in content using a shortcode, with full customisation.
|
10 |
|
11 |
== Description ==
|
12 |
|
28 |
* Use Ordered Lists (OL) for the top and/or sub levels instead of Unordered Lists (UL)
|
29 |
* *As of v1.1.0* : Select a branch based on the ultimate ancestor (root level) of the "current" item
|
30 |
* *As of v1.2.0* : Shortcode, [custom_menu_wizard], available to run the widget from within content
|
31 |
+
* *As of v2.0.0* : Make the output conditional upon the "current" item appearing in the selected/included items
|
32 |
+
* *As of v2.0.0* : Specify specific menu items
|
33 |
+
* *As of v2.0.0* : Use the widget's interactive "assist" to help with the widget settings or shortcode definition
|
34 |
|
35 |
+
Documentation for the Widget Options, and the associated Shortcode Parameters, can be found under
|
36 |
+
[Other Notes](http://wordpress.org/plugins/custom-menu-wizard/other_notes/).
|
37 |
|
38 |
+
== Widget Options ==
|
39 |
|
40 |
There are quite a few options, which makes the widget settings box very long. I have therefore grouped most of the options into
|
41 |
logical sections and made each section collapsible (with remembered state once saved). As of v1.2.1, only the Filter section is
|
81 |
|
82 |
If you change `Select Menu`, the options presented in this dropdown will change accordingly and the selected option will revert to the default.
|
83 |
|
84 |
+
* **Items** (radio & text input)* as of v2.0.0
|
85 |
+
|
86 |
+
Takes a comma- or space-delimited list of menu item ids, specifiying the specific menu items that are required. This is intended
|
87 |
+
for situations that it is not possible to handle using other option settings. The simplest way to determine the menu item ids is
|
88 |
+
to use the "assist" facility.
|
89 |
+
|
90 |
+
Note that the `Starting Level` and `Depth` options (including `Relative to "Current" Item`) have no effect if `Items` is set.
|
91 |
+
|
92 |
* **Starting Level** *(select, default: "1")*
|
93 |
|
94 |
This is the level within the chosen menu (from `Select Menu`) that the widget will start looking for items to keep. Obviously, level 1
|
95 |
is the root level (ie. those items that have no parent item); level 2 is all the immediate children of the root level items, and so on.
|
96 |
Note that for a `Children of` filter there is no difference between level 1 and level 2 (because there are no children at level 1).
|
97 |
+
Also note that this option does not apply if `Items` is set.
|
98 |
|
99 |
* **For Depth** *(select, default: "unlimited")*
|
100 |
|
101 |
This is the maximum depth of the eventual output structure after filtering, and in the case of `Flat` output being requested it is
|
102 |
still applied - as if the output were `Hierarchical` and then flattened at the very last moment.
|
103 |
|
104 |
+
You need to be aware that, by default, the
|
105 |
`For Depth` setting is applied relative to the level at which the first item to be kept is found. For example, say you were to set
|
106 |
`Children of` to "Current Item", `Starting Level` to "2", and `For Depth` to "2 levels" : if the current item was found at level 3,
|
107 |
then you would get the current item's immediate children (from level 4), plus *their* immediate children (from level 5).
|
108 |
+
Note that this option does not apply if `Items` is set.
|
109 |
+
|
110 |
+
* **Relative to "Current" Item** *(checkbox)* as of v2.0.0
|
111 |
+
|
112 |
+
This changes the `For Depth` option such that depth is applied relative to the current menu item, instead of relative to the
|
113 |
+
first item found that is to be kept. It only has any effect when `For Depth` is set to something other than "unlimited", and when
|
114 |
+
the current menu item is within the filtered items (before taking `For Depth` into account).
|
115 |
|
116 |
* **Fallbacks**
|
117 |
|
175 |
Output in a single list format, ignoring any parent-child relationship other than to maintain the same physical order as would be
|
176 |
presented in a `Hierarchical` output.
|
177 |
|
178 |
+
* **Must Contain "Current" Item** *(checkbox)* as of v2.0.0
|
179 |
+
|
180 |
+
If checked, the widget will not list any menu items unless the current menu item appears somewhere in the list.
|
181 |
+
|
182 |
* **Include Parent...** *(checkbox)*
|
183 |
|
184 |
If checked, include the parent item in the output. Only applies to a successful `Children of` filter.
|
273 |
|
274 |
Text or HTML that will be placed immediately after each menu item's link text.
|
275 |
|
276 |
+
== Shortcode Parameters ==
|
277 |
+
|
278 |
+
The shortcode is **`[custom_menu_wizard]`**. Most of the attributes reflect the options available to the widget, but some have been simplified for easier use in the shortcode format.
|
279 |
+
Please note that the `Hide Widget if Empty` option is not available to the shortcode : it is set to enabled, and if there are no menu items found then there will be no output from the shortcode.
|
280 |
|
281 |
+
The simplest way to build a shortcode is to use the widget's "assist" facility (new in v2.0.0). The facilty is available even when the widget is in
|
282 |
+
the Inactive Widgets area, so you don't have to add an unwanted instance of the widget to a sidebar.
|
|
|
|
|
283 |
|
284 |
* **title** *(string)*
|
285 |
|
292 |
|
293 |
* **children_of** *(string | integer)*
|
294 |
|
295 |
+
If not empty then it specifies a `Children of` filter. If neither `children_of` nor `items` are supplied (or are empty) then the
|
296 |
+
filter defaults back to `Show all` (see above). Note that `items`, if supplied, will take precedence over `children_of`.
|
297 |
|
298 |
* If numeric, it is taken as being the id of a menu item. The widget will look for the `Children of` that menu item (within `menu`).
|
299 |
(Hint : In Menus Admin, hover over the item's **Remove** link and note the number after *menu-item=* in the URL)
|
308 |
|
309 |
* If any other string, it is taken to be the title of a menu item. The widget will look for the `Children of` that menu item
|
310 |
(within `menu`). Please note that the code looks for a *caseless* title match, so specifying `children_of="my menu item"` will
|
311 |
+
match against a menu item with the title "My Menu Item". Also note that the first match found (hierarchically) is the one that
|
312 |
+
gets used (it is quite possible to have same-named items within a menu structure).
|
313 |
+
|
314 |
+
* **items** *(string)* See widget's `Items` option, under **Filter** above.
|
315 |
|
316 |
* **fallback_parent** *(string | integer)*
|
317 |
|
338 |
* **start_level** *(integer, default 1)* See widget's `Starting Level` option, under **Filter** above.
|
339 |
|
340 |
* **depth** *(integer, default 0)* See widget's `For Depth` option, under **Filter** above.
|
341 |
+
|
342 |
+
* **depth_rel_current** *(switch, off by default, 1 to enable)* See widget's `Relative to "Currrent" Item` option, under **Filter** above.
|
343 |
|
344 |
* **flat_output** *(switch, off by default, 1 to enable)* See widget's `Flat` option, under **Output** above.
|
345 |
|
346 |
+
* **contains_current** *(switch, off by default, 1 to enable)* See widget's `Must Contain "Current" Item` option, under **Output** above.
|
347 |
+
|
348 |
* **include** *(string)*
|
349 |
|
350 |
* *'parent'* : Enables widget's `Include Parent...` **Output** option
|
379 |
|
380 |
* **wrap_link** *(string)*
|
381 |
|
382 |
+
This is an optional tag name (eg. *'div'*, *'p'*, *'span'*) that, if provided, will be made into HTML start/end tags
|
383 |
and sent through to the widget as its `Before the Link` and `After the Link` options. Please note that the shortcode usage - a simple
|
384 |
tag name - is much more restrictive than the widget's options, which allow HTML.
|
385 |
|
386 |
* **wrap_link_text** *(string)*
|
387 |
|
388 |
+
This is an optional tag name (eg. *'span'*, *'em'*, *'strong'*) that, if provided, will be made into HTML start/end tags
|
389 |
and sent through to the widget as its `Before the Link Text` and `After the Link Text` options. Please note that the shortcode usage - a
|
390 |
simple tag name - is much more restrictive than the widget's options, which allow HTML.
|
391 |
|
393 |
|
394 |
* Show the entire "main" menu :
|
395 |
|
396 |
+
`
|
397 |
+
[custom_menu_wizard menu=main]
|
398 |
+
`
|
399 |
|
400 |
* Show the children of the Current Item within the "main" menu, for unlimited depth, and include the Current Item's parent :
|
401 |
|
402 |
+
`
|
403 |
+
[custom_menu_wizard menu=main children_of=current include=parent]
|
404 |
+
`
|
405 |
|
406 |
* From the "animals" menu, show all the items *immediately* below (depth=1) "Small Dogs", plus "Small Dogs" and its sibling items, as ordered lists :
|
407 |
|
408 |
+
`
|
409 |
+
[custom_menu_wizard menu="animals" children_of="small dogs" depth=1 include="siblings" ol_root=1 ol_sub=1]
|
410 |
+
`
|
411 |
|
412 |
== Installation ==
|
413 |
|
418 |
1. Activate the plugin through the 'Plugins' menu in your WP Admin
|
419 |
|
420 |
The widget will now be available in the 'Widgets' admin page.
|
421 |
+
As long as you already have at least one Menu defined, you can add the new widget to a sidebar and configure it however you want.
|
422 |
+
Alternatively, you can use the shortcode in your content.
|
423 |
|
424 |
== Frequently Asked Questions ==
|
425 |
|
426 |
+
If you have a question or problem that is not covered here, please use the integrated Support forum.
|
427 |
+
|
428 |
+
= Why isn't it working? Why is there no output? =
|
429 |
+
|
430 |
+
I don't know. With all due respect (and a certain amount of confidence in the widget) I would venture to suggest that it is probably due to
|
431 |
+
the option settings on the widget/shortcode. The quickest way to resolve any such issues is to use the widget's interactive "assist", and
|
432 |
+
ensure that you set the current menu item correctly for the page(s) that you are having problems with. However, I am well aware that I not
|
433 |
+
infallible, and if you still have problems then please let me have as much information as possible and I will endeavour to help. (Please
|
434 |
+
note that simply reporting "It doesn't work" is not the most useful of feedbacks, and is unlikely to get a response other than, possibly,
|
435 |
+
a request for more details).
|
436 |
+
|
437 |
+
= How do I use the "assist"? =
|
438 |
+
|
439 |
+
The widget's interactive "assist" is specific to each widget instance. It is a javascript-driven *emulator* that uses the widget instance's
|
440 |
+
option settings - including the menu selected - to build a pictorial representation of the menu and show you, in blue, which menu items will
|
441 |
+
be output according to the current option settings. It also shows a very basic output list of those menu items, although it will not apply
|
442 |
+
some of the more advanced HTML-modifying options such as can be found under the Container, Classes or Links sections.
|
443 |
+
Any of the displayed menu items can be designated as the "current menu item" simply by clicking on it (click again to deselect, or another
|
444 |
+
item to change). The "current menu item" is shaded red, with its parent shaded orange and ancestors shaded yellow. All changes in the
|
445 |
+
"current menu item" and the widget options are immediately reflected by the "assist" (text fields in the widget options simply need to lose
|
446 |
+
focus).
|
447 |
+
|
448 |
+
Once you are happy with the results, having tested all possible settings of "current menu item" (if it applies), then simply Save the widget.
|
449 |
+
Alternatively, simply copy-paste the shortcode code produced by the "assist" straight into your post (you do not need to Save the widget!).
|
450 |
+
The widget does not have to Saved to *test* any of the options.
|
451 |
+
|
452 |
+
= Is there an easy way to construct the shortcode to get the results that I want? =
|
453 |
+
|
454 |
+
Yes. Use the widget's interactive "assist" capability (see above). Note that you do not need to have the widget in a sidebar : the
|
455 |
+
"assist" also works off a widget that is in the Inactive Widgets area of the widget admin page.
|
456 |
+
|
457 |
+
= How do I get the menu item ids for the `Items` option? =
|
458 |
+
|
459 |
+
Use the widget's interactive "assist" (see above). Within the representation menu structure, each menu item's id is set in its title
|
460 |
+
attribute, so should be seen when the cursor is moved over the item. A simpler way is to check the `Items` option : the "assist" will
|
461 |
+
then show a checkbox beside each menu item and you simply [un]check the items as required. Each selection will be reflected back into the
|
462 |
+
widget's `Items` settings, and also in the shortcode code.
|
463 |
+
|
464 |
+
Alternatively, go to Appearance, Menus and select the relevant menu; hover over the edit, Remove, or Cancel link for an item and look in
|
465 |
+
the URL (the link's href) for `menu-item=NNN` ... the NNN is the menu item id.
|
466 |
+
|
467 |
+
= Why is the `Must Contain Current Item` option in the Output section and not in the Filter section? =
|
468 |
+
|
469 |
+
It was a close call, but since the Output options can extend the final list - and the check for "current menu item" is made against the
|
470 |
+
*entire* resultant list - I decided that `Must contain Current Item` was more of a "final output" check than an initial filter.
|
471 |
|
472 |
== Screenshots ==
|
473 |
|
477 |
|
478 |
3. Even more widget options
|
479 |
|
480 |
+
4. Widget's "assist"
|
481 |
|
482 |
== Changelog ==
|
483 |
|
484 |
+
= 2.0.0 =
|
485 |
+
|
486 |
+
* **! Possible Breaker !** The calculation of `Start Level` has been made consistent across the `Show all` and `Children of` filters : if you previously had a setup where you were filtering for the children of an item at level 2, with start level set to 4, there would have been no output because the immediate children (at level 3) were outside the start level. Now, there *will* be output, starting with the grand-children (at level 4).
|
487 |
+
|
488 |
+
* **! Possible Breaker !** There is now deemed to be an artificial "root" item above the level 1 items, which mean that a `Children of` filter set to "Current Parent Item" or "Current Root Item" will no longer fail for a top-level "current menu item". If you have the "no ancestor" fallback set then this change will have no impact (but you may now want to consider turning the fallback off?); if you *don't* currently use the "no ancestor" fallback, then where there was previously no output there will now be some!
|
489 |
+
|
490 |
+
* added new option : Items, a comma- or space-delimited list of menu item ids, as an alternative Filter
|
491 |
+
|
492 |
+
* added new option : Depth Relative to Current Item to the Filter section (depth_rel_current=1 in the shortcode)
|
493 |
+
|
494 |
+
* added new option : Must Contain Current Item to the Output section (contains_current=1 in the shortcode)
|
495 |
+
|
496 |
+
* changed the widget's "demo" facility to "assist" and brought it into WordPress admin, with full interactivity with the widget
|
497 |
+
|
498 |
+
* refactored code
|
499 |
+
|
500 |
= 1.2.2 =
|
501 |
|
502 |
* bugfix : fallback for Current Item with no children was failing because the parent's children weren't being picked out correctly
|
513 |
|
514 |
* in demo.html, added a link to the documentation page
|
515 |
|
516 |
+
* corrected 2 of the shortcode examples in the readme.txt, and made emulator (demo) available from the readme
|
517 |
|
518 |
= 1.2.0 =
|
519 |
|
533 |
|
534 |
* added 'Current Root Item' and 'Current Parent Item' to the `Children of` filter
|
535 |
|
536 |
+
* added `Fallback to Current Item` option, with subsidiary options for overriding a couple of Output options, as a means to enable Current Root & Current Parent to match a Current Item at root level
|
537 |
|
538 |
* added an Output option to include both the parent item **and** the parent's siblings (for a successful `Children of` filter)
|
539 |
|
555 |
|
556 |
== Upgrade Notice ==
|
557 |
|
558 |
+
= 2.0.0 =
|
559 |
+
|
560 |
+
**! Possible Breaker !** My apologies if this affects you, but there are 2 possible scenarios where settings that previously resulted in no output *might* now produce output :
|
561 |
+
+ if you have set a `Children of` filter, **and** you have changed the `Start Level` to a level greater than 2, or
|
562 |
+
+ if you have set the `Children of` filter to Current Parent/Root Item, and you have **not** set the "no ancestor" fallback.
|
563 |
+
*__If you think you may be impacted, please check the [Changelog](http://wordpress.org/plugins/custom-menu-wizard/changelog/) for a fuller explanation of what has changed.__*
|
564 |
+
|
565 |
+
New options :
|
566 |
+
+ `Items` allows specific menu item ids to be listed, as an alternative to the other filters
|
567 |
+
+ `Relative to "Current" Item` allows a limited Depth to be calculated relative to the current menu item
|
568 |
+
+ `Must Contain "Current" Item` requires that there be no output unless the resultant list contains the current menu item.
|
569 |
+
Rebuilt the "demo" facility as an "assist" wizard for the widget It is now fully interactive with the widget instance, and generates the entire shortcode according to the widget instance settings.
|
570 |
+
|
571 |
+
= 1.2.2 =
|
572 |
+
|
573 |
+
Bugfix : The fallback for Current Item with no children was failing because the parent's children weren't being picked out correctly
|
574 |
+
|
575 |
= 1.2.1 =
|
576 |
|
577 |
Added a few extra custom classes, and changed the defaults for new widgets such that only the Filter section is open by default.
|
580 |
|
581 |
= 1.2.0 =
|
582 |
|
583 |
+
Added custom_menu_wizard shortcode, to run the widget from within content.
|
584 |
+
Added a new fallback for Current Item having no children, and moved all fallbacks into a collapsible Fallbacks section.
|
585 |
+
Fixed a bug with optgroups/options made available for the 'Children of' selector after the widget has been saved (also affected disabled fields and styling).
|