Version Description
added custom_menu_wizard shortcode, to run the widget from within content
moved the 'no ancestor' fallback into new Fallback collapsible section, and added a fallback for Current Item with no children
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)
don't include menus with no items
updated demo.html
Download this release
Release Info
Developer | wizzud |
Plugin | Custom Menu Wizard Widget |
Version | 1.2.0 |
Comparing to | |
See all releases |
Code changes from version 1.1.0 to 1.2.0
- custom-menu-wizard.js +54 -28
- custom-menu-wizard.php +402 -72
- demo.html +119 -45
- readme.txt +211 -31
custom-menu-wizard.js
CHANGED
@@ -1,12 +1,11 @@
|
|
1 |
/* Plugin Name: Custom Menu Wizard
|
2 |
-
* Version: 1.
|
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 |
-
filterItems = $('select' + dotPrefix + '-listen');
|
10 |
$(document)
|
11 |
//fieldsets...
|
12 |
.on('click', dotPrefix + '-collapsible-fieldset', function(){
|
@@ -20,33 +19,60 @@ jQuery(function($){
|
|
20 |
this.blur();
|
21 |
return false;
|
22 |
})
|
23 |
-
//change of menu...
|
24 |
-
.on('change', dotPrefix + '-
|
25 |
-
var
|
26 |
-
|
|
|
|
|
|
|
|
|
27 |
groupClone;
|
28 |
-
if(
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
-
groupClone = from.eq( this.selectedIndex ).clone();
|
33 |
-
groupClone.find('option[selected]').removeAttr('selected').prop('selected', false);
|
34 |
-
select.find('optgroup').remove();
|
35 |
-
select.append(groupClone).trigger('change');
|
36 |
}
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
});
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
});
|
1 |
/* Plugin Name: Custom Menu Wizard
|
2 |
+
* Version: 1.2.0
|
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(){
|
19 |
this.blur();
|
20 |
return false;
|
21 |
})
|
22 |
+
//change of menu, and enableif / disableif...
|
23 |
+
.on('change', dotPrefix + '-listen', function(){
|
24 |
+
var listeners = $(dotPrefix + '-listen', this.form),
|
25 |
+
selectMenu = listeners.filter(dotPrefix + '-selectmenu'),
|
26 |
+
others = listeners.not(selectMenu),
|
27 |
+
showAll = others.eq(0).prop('checked'),
|
28 |
+
filterItem = others.filter('select').eq(0),
|
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;
|
35 |
+
if(!keep){
|
36 |
+
$(this).remove();
|
37 |
+
}
|
38 |
+
return keep;
|
39 |
+
}).length){
|
40 |
+
groupClone = $('#' + filterItem.attr('id') + '_ignore').find('optgroup').eq(selectMenu).clone();
|
41 |
+
if(groupClone.length){
|
42 |
+
if(fiVal > 0){
|
43 |
+
fiVal = 0;
|
44 |
+
filterItem.val(fiVal);
|
45 |
+
}
|
46 |
+
groupClone.find('option[selected]').removeAttr('selected').prop('selected', false);
|
47 |
+
filterItem.append(groupClone);
|
48 |
+
}
|
49 |
}
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
+
$.each(
|
52 |
+
{ '' : showAll,
|
53 |
+
'not-rp' : showAll || fiVal >= 0,
|
54 |
+
'not-ci' : showAll || !!fiVal
|
55 |
+
},
|
56 |
+
function(k, v){
|
57 |
+
$(dotPrefix + '-disableif' + k, this.form).css({color:v ? '#999999' : 'inherit'}).find('input,select').prop('disabled', v);
|
58 |
+
});
|
59 |
});
|
60 |
+
|
61 |
+
//when a widget is opened or saved, trigger change on the filter_item select...
|
62 |
+
//to do this I've elected to modify WP's window.wpWidgets object and intercept its fixLabels()
|
63 |
+
//method, which, handily, gets called whenever a widget is opened or saved!
|
64 |
+
if(window.wpWidgets && window.wpWidgets.fixLabels && !window.wpWidgets._cmw_fixLabels){
|
65 |
+
//save the original...
|
66 |
+
window.wpWidgets._cmw_fixLabels = window.wpWidgets.fixLabels;
|
67 |
+
//replace the original...
|
68 |
+
window.wpWidgets.fixLabels = function(widget){
|
69 |
+
//trigger change on selectmenu...
|
70 |
+
widget.find('.widget-custom-menu-wizard-selectmenu').trigger('change');
|
71 |
+
//run the original...
|
72 |
+
window.wpWidgets._cmw_fixLabels(widget);
|
73 |
+
};
|
74 |
+
}else{
|
75 |
+
//one-off fallback...
|
76 |
+
$(dotPrefix + '-selectmenu').trigger('change');
|
77 |
+
}
|
78 |
});
|
custom-menu-wizard.php
CHANGED
@@ -1,15 +1,22 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
* Plugin Name: Custom Menu Wizard
|
4 |
-
* Plugin URI: http://
|
5 |
* Description: Full control over the wp_nav_menu parameters for a custom menu, plus the ability to filter for specific level(s), or for children of a selected menu item or the current item
|
6 |
-
* Version: 1.
|
7 |
* Author: Roger Barrett
|
8 |
* Author URI: http://www.wizzud.com/
|
9 |
* License: GPL2+
|
10 |
*/
|
11 |
|
12 |
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
* v1.1.0 change log:
|
14 |
* - added 'Current Root Item' and 'Current Parent Item' to the 'Children of' filter
|
15 |
* - added an Output option to include both the parent item and the parent's siblings (for a successful 'Children of' filter)
|
@@ -21,13 +28,14 @@
|
|
21 |
* - moved the setting of 'disabled' attributes on INPUTs/SELECTs from PHP into javascript
|
22 |
*/
|
23 |
|
24 |
-
$Custom_Menu_Wizard_Widget_Version = '1.
|
25 |
|
26 |
/**
|
27 |
-
* registers the widget
|
28 |
*/
|
29 |
function custom_menu_wizard_register_widget() {
|
30 |
register_widget('Custom_Menu_Wizard_Widget');
|
|
|
31 |
}
|
32 |
add_action('widgets_init', 'custom_menu_wizard_register_widget');
|
33 |
|
@@ -73,6 +81,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
73 |
/**
|
74 |
* pre-filters elements then calls parent::walk()
|
75 |
*
|
|
|
|
|
76 |
* @param array $elements Menu items
|
77 |
* @param integer $max_depth
|
78 |
* @return string
|
@@ -92,27 +102,33 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
92 |
// include_parent : true = include the filter_item menu item
|
93 |
// include_parent_siblings : true = include the siblings (& parent) of the filter_item menu item
|
94 |
// include_ancestors : true = include the filter_item menu item plus all it's ancestors
|
95 |
-
// title_from_parent : true = widget wants parent's title
|
|
|
96 |
// start_level : integer, 1+
|
97 |
// depth : integer, replacement for max_depth and also applied to 'flat' output
|
98 |
// 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)
|
99 |
// fallback_include_parent : true = if fallback_no_ancestor comes into play then force include_parent to true (v1.1.0)
|
100 |
// fallback_include_parent_siblings : true = if fallback_no_ancestor comes into play then force include_parent_siblings to true (v1.1.0)
|
|
|
|
|
|
|
101 |
//$elements is an array of objects, indexed by position within the menu (menu_order),
|
102 |
//starting at 1 and incrementing sequentially regardless of parentage (ie. first item is [1],
|
103 |
//second item is [2] whether it's at root or subordinate to first item)
|
|
|
104 |
|
105 |
$find_kids_of = $cmw['filter'];
|
106 |
$find_current_item = $find_kids_of && empty( $cmw['filter_item'] );
|
107 |
$find_current_parent = $find_kids_of && $cmw['filter_item'] == -1; //v1.1.0
|
108 |
$find_current_root = $find_kids_of && $cmw['filter_item'] == -2; //v1.1.0
|
109 |
-
$
|
110 |
//these could change depending on whether a fallback comes into play (v1.1.0)
|
111 |
$include_parent = $cmw['include_parent'];
|
112 |
$include_parent_siblings = $cmw['include_parent_siblings'];
|
113 |
|
114 |
//are we looking for something in particular?...
|
115 |
if( $find_kids_of || $cmw['start_level'] > 1 ){
|
|
|
116 |
$id_field = $this->db_fields['id']; //eg. = 'db_id'
|
117 |
$parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
|
118 |
|
@@ -151,6 +167,10 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
151 |
//also note that orphans (in the original menu) are ignored by this widget!
|
152 |
|
153 |
if( isset( $temp[ $item->$id_field ] ) ){
|
|
|
|
|
|
|
|
|
154 |
//are we at or below the start level?...
|
155 |
if( $temp[ $item->$id_field ]['level'] >= $start_level ){
|
156 |
//are we still looking for a starting point?...
|
@@ -164,7 +184,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
164 |
//...we're looking for a current root ancestor, and this is one...
|
165 |
( $find_current_root && $item->current_item_ancestor ) ||
|
166 |
//...we've got a fallback for a top-level current item with no ancestor...
|
167 |
-
( $
|
168 |
//...we're looking for a particular menu item, and this is it...
|
169 |
( $cmw['filter_item'] == $item->$id_field )
|
170 |
){
|
@@ -173,8 +193,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
173 |
if( !$find_kids_of ){
|
174 |
$keep_items[] = $item;
|
175 |
}
|
176 |
-
//v1.1.0 if this was the
|
177 |
-
if( $
|
178 |
$include_parent = $include_parent || $cmw['fallback_include_parent'];
|
179 |
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_include_parent_siblings'];
|
180 |
}
|
@@ -193,7 +213,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
193 |
//having found at least one, any more have to be:
|
194 |
// - within max_depth of the first one found, and
|
195 |
// - either it's an unspecific search, or we have the parent already
|
196 |
-
}elseif( $temp[ $item->$id_field ]['level'] <= $max_level && (!$find_kids_of || in_array( $item->$parent_field, $keep_ids ) ) ){
|
197 |
$keep_ids[] = $item->$id_field;
|
198 |
$keep_items[] = $item;
|
199 |
}
|
@@ -201,6 +221,23 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
201 |
}
|
202 |
} //end foreach
|
203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
unset( $keep_ids );
|
205 |
if( !empty( $keep_items) ){
|
206 |
|
@@ -211,14 +248,23 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
211 |
//last element is now the parent (if there is one)
|
212 |
$i = $j = count( $breadcrumb );
|
213 |
|
214 |
-
//
|
215 |
if( $find_kids_of && $cmw['title_from_parent'] && $i > 0 ){
|
216 |
-
$cmw['
|
217 |
'the_title',
|
218 |
$elements[ $breadcrumb[ $i - 1 ] ]->title,
|
219 |
$elements[ $breadcrumb[ $i - 1 ] ]->ID
|
220 |
);
|
221 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
|
223 |
//if we have a parent and we also want all the parent siblings, then we need
|
224 |
//to pop the parent off the bottom of temp and either append or prepend the
|
@@ -324,16 +370,21 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
324 |
'fallback_no_ancestor', //v1.1.0 added
|
325 |
'fallback_include_parent', //v1.1.0 added
|
326 |
'fallback_include_parent_siblings', //v1.1.0 added
|
|
|
|
|
|
|
327 |
'flat_output',
|
328 |
'include_parent',
|
329 |
'include_parent_siblings', //v1.1.0 added
|
330 |
'include_ancestors',
|
331 |
'hide_empty', //v1.1.0: this now only has relevance prior to WP v3.6
|
332 |
'title_from_parent',
|
|
|
333 |
'ol_root',
|
334 |
'ol_sub',
|
335 |
//field section toggles...
|
336 |
'fs_filter',
|
|
|
337 |
'fs_output',
|
338 |
'fs_container',
|
339 |
'fs_classes',
|
@@ -370,24 +421,23 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
370 |
array(
|
371 |
'classname' => 'widget_custom_menu_wizard',
|
372 |
'description' => __('Add a custom menu, or part of one, as a widget')
|
373 |
-
// ),
|
374 |
-
// array(
|
375 |
-
// 'width'=>560
|
376 |
)
|
377 |
);
|
378 |
}
|
379 |
|
380 |
/**
|
381 |
-
* removes itself from the filters and, if available
|
382 |
*
|
383 |
* @param array $items Filtered menu items
|
384 |
* @param object $args
|
385 |
* @return array Menu items
|
386 |
*/
|
387 |
-
function
|
388 |
remove_filter('custom_menu_wizard_walker_items', array( $this, 'cmw_filter_retain_parent_title' ), 10, 2);
|
389 |
-
|
390 |
-
|
|
|
|
|
391 |
}
|
392 |
return $items;
|
393 |
}
|
@@ -434,6 +484,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
434 |
/**
|
435 |
* produces the widget HTML at the front end
|
436 |
*
|
|
|
|
|
437 |
* @param object $args Widget arguments
|
438 |
* @param array $instance Configuration for this widget instance
|
439 |
*/
|
@@ -460,7 +512,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
460 |
//v1.1.0 As of WP v3.6, wp_nav_menu() automatically prevents any HTML output if there are no items...
|
461 |
$instance['hide_empty'] = $instance['hide_empty'] && $this->_pre_3point6();
|
462 |
|
463 |
-
$this->
|
464 |
|
465 |
//fetch menu...
|
466 |
if( !empty($instance['menu'] ) ){
|
@@ -483,8 +535,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
483 |
$instance['container_class'] = "menu-{$menu->slug}-container {$instance['container_class']}";
|
484 |
}
|
485 |
|
486 |
-
if( $instance['title_from_parent'] ){
|
487 |
-
add_filter('custom_menu_wizard_walker_items', array( $this, '
|
488 |
}
|
489 |
|
490 |
if( $instance['hide_empty'] ){
|
@@ -512,10 +564,14 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
512 |
'fallback_no_ancestor' => $instance['fallback_no_ancestor'], //v1.1.0
|
513 |
'fallback_include_parent' => $instance['fallback_include_parent'], //v1.1.0
|
514 |
'fallback_include_parent_siblings' => $instance['fallback_include_parent_siblings'], //v1.1.0
|
|
|
|
|
|
|
515 |
'include_parent' => $instance['include_parent'],
|
516 |
'include_parent_siblings' => $instance['include_parent_siblings'], //v1.1.0
|
517 |
'include_ancestors' => $instance['include_ancestors'],
|
518 |
'title_from_parent' => $instance['title_from_parent'],
|
|
|
519 |
'ol_root' => $instance['ol_root'],
|
520 |
'ol_sub' => $instance['ol_sub'],
|
521 |
'flat_output' => $instance['flat_output'],
|
@@ -530,7 +586,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
530 |
$params['container_class'] = $instance['container_class'];
|
531 |
}
|
532 |
//NB: wp_nav_menu() is in wp-includes/nav-menu-template.php
|
533 |
-
$out = wp_nav_menu( $params );
|
534 |
|
535 |
if( $instance['hide_empty'] ){
|
536 |
remove_filter( "wp_nav_menu_{$menu->slug}_items", array( $this, 'cmw_filter_check_for_no_items' ), 65532, 2 );
|
@@ -539,8 +595,15 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
539 |
//only put something out if there is something to put out...
|
540 |
if( !empty( $out ) ){
|
541 |
|
542 |
-
|
543 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
544 |
}
|
545 |
if( empty( $title ) ){
|
546 |
$title = $instance['hide_title'] ? '' : $instance['title'];
|
@@ -605,11 +668,20 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
605 |
}
|
606 |
|
607 |
//get menus...
|
608 |
-
$menus =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
609 |
|
610 |
-
//if no menus exist, suggest the user go create one...
|
611 |
-
if(
|
612 |
-
echo '<p>'. sprintf( __('No menus have been created yet. <a href="%s">Create one</a>.'), admin_url('nav-menus.php') ) .'</p>';
|
613 |
return;
|
614 |
}
|
615 |
|
@@ -619,7 +691,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
619 |
?>
|
620 |
<p>
|
621 |
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
|
622 |
-
<label
|
623 |
<input id="<?php echo $this->get_field_id('hide_title'); ?>" name="<?php echo $this->get_field_name('hide_title'); ?>"
|
624 |
type="checkbox" value="1" <?php checked( $instance['hide_title'] ); ?> />
|
625 |
<?php _e('Hide'); ?></label>
|
@@ -630,14 +702,16 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
630 |
|
631 |
<p>
|
632 |
<label for="<?php echo $this->get_field_id('menu'); ?>"><?php _e('Select Menu:'); ?></label>
|
633 |
-
<select id="<?php echo $this->get_field_id('menu'); ?>"
|
|
|
634 |
name="<?php echo $this->get_field_name('menu'); ?>">
|
635 |
<?php
|
636 |
foreach( $menus as $i=>$menu ){
|
637 |
-
|
638 |
?>
|
639 |
<option <?php selected($instance['menu'], $menu->term_id); ?> value="<?php echo $menu->term_id; ?>"><?php echo $menu->name; ?></option>
|
640 |
<?php
|
|
|
641 |
}
|
642 |
?>
|
643 |
</select>
|
@@ -651,11 +725,11 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
651 |
?>
|
652 |
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
653 |
<p>
|
654 |
-
<label
|
655 |
<input id="<?php echo $this->get_field_id('filter'); ?>_0" class="widget-<?php echo $this->id_base; ?>-listen"
|
656 |
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="0" <?php checked(!$instance['filter']); ?> />
|
657 |
<?php _e('Show all'); ?></label>
|
658 |
-
<br /><label
|
659 |
<input id="<?php echo $this->get_field_id('filter'); ?>_1" class="widget-<?php echo $this->id_base; ?>-listen"
|
660 |
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="1" <?php checked($instance['filter']); ?> />
|
661 |
<?php _e('Children of:'); ?></label>
|
@@ -672,12 +746,11 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
672 |
|
673 |
$maxlevel = 1;
|
674 |
foreach( $menus as $i=>$menu ){
|
675 |
-
//v1.
|
676 |
-
$itemindents = array('0' => 0);
|
677 |
-
$activeOpts = ( $i == 0 && empty($instance['menu']) ) || $instance['menu'] == $menu->term_id;
|
678 |
-
$style = $activeOpts ? '' : ' style="display:none;"';
|
679 |
-
$menuOptions[] = '<optgroup label="' . $menu->name . '" data-cmw-active-menu="' . ($activeOpts ? 'true' : 'false') .'">';
|
680 |
if( !empty( $menu->_items ) ){
|
|
|
|
|
|
|
681 |
foreach( $menu->_items as $item ){
|
682 |
//exclude orpans!
|
683 |
if( isset($itemindents[ $item->menu_item_parent ])){
|
@@ -688,8 +761,8 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
688 |
str_repeat('- ', $itemindents[ $item->menu_item_parent ]) . $item->title . '</option>';
|
689 |
}
|
690 |
}
|
|
|
691 |
}
|
692 |
-
$menuOptions[] = '</optgroup>';
|
693 |
}
|
694 |
$menuOptions = implode("\n", $menuOptions);
|
695 |
echo $menuOptions;
|
@@ -702,25 +775,6 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
702 |
</select>
|
703 |
</p>
|
704 |
|
705 |
-
<p class="widget-<?php echo $this->id_base; ?>-enableif">
|
706 |
-
<label for="<?php echo $this->get_field_id('fallback_no_ancestor'); ?>">
|
707 |
-
<input id="<?php echo $this->get_field_id('fallback_no_ancestor'); ?>"
|
708 |
-
name="<?php echo $this->get_field_name('fallback_no_ancestor'); ?>" type="checkbox" value="1"
|
709 |
-
<?php checked($instance['fallback_no_ancestor']); ?> />
|
710 |
-
<?php _e('Fallback to Current Item, and'); ?></label>
|
711 |
-
<br /><label for="<?php echo $this->get_field_id('fallback_include_parent'); ?>" style="padding-left:1em;">
|
712 |
-
<input id="<?php echo $this->get_field_id('fallback_include_parent'); ?>"
|
713 |
-
name="<?php echo $this->get_field_name('fallback_include_parent'); ?>" type="checkbox" value="1"
|
714 |
-
<?php checked($instance['fallback_include_parent']); ?> />
|
715 |
-
<?php _e('Include Parent...'); ?> </label>
|
716 |
-
<label for="<?php echo $this->get_field_id('fallback_include_parent_siblings'); ?>">
|
717 |
-
<input id="<?php echo $this->get_field_id('fallback_include_parent_siblings'); ?>"
|
718 |
-
name="<?php echo $this->get_field_name('fallback_include_parent_siblings'); ?>" type="checkbox" value="1"
|
719 |
-
<?php checked($instance['fallback_include_parent_siblings']); ?> />
|
720 |
-
<?php _e('& its Siblings'); ?></label>
|
721 |
-
<br /><small><em><?php _e('If Current Root/Parent and no ancestor exists'); ?></em></small>
|
722 |
-
</p>
|
723 |
-
|
724 |
<p>
|
725 |
<label for="<?php echo $this->get_field_id('start_level'); ?>"><?php _e('Starting Level:'); ?></label>
|
726 |
<select id="<?php echo $this->get_field_id('start_level'); ?>" name="<?php echo $this->get_field_name('start_level'); ?>">
|
@@ -753,6 +807,54 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
753 |
</p>
|
754 |
<?php $this->_close_a_field_section(); ?>
|
755 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
756 |
<?php
|
757 |
/**
|
758 |
* start collapsible section : 'Output'
|
@@ -761,47 +863,56 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
761 |
?>
|
762 |
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
763 |
<p>
|
764 |
-
<label
|
765 |
<input id="<?php echo $this->get_field_id('flat_output'); ?>_0" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
766 |
type="radio" value="0" <?php checked(!$instance['flat_output']); ?> />
|
767 |
<?php _e('Hierarchical'); ?></label>
|
768 |
-
<label
|
769 |
<input id="<?php echo $this->get_field_id('flat_output'); ?>_1" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
770 |
type="radio" value="1" <?php checked($instance['flat_output']); ?> />
|
771 |
<?php _e('Flat'); ?></label>
|
772 |
</p>
|
773 |
|
774 |
<p class="widget-<?php echo $this->id_base; ?>-disableif">
|
775 |
-
<label
|
776 |
<input id="<?php echo $this->get_field_id('include_parent'); ?>"
|
777 |
name="<?php echo $this->get_field_name('include_parent'); ?>" type="checkbox"
|
778 |
value="1" <?php checked($instance['include_parent']); ?> />
|
779 |
<?php _e('Include Parent...'); ?> </label>
|
780 |
-
<label
|
781 |
<input id="<?php echo $this->get_field_id('include_parent_siblings'); ?>"
|
782 |
name="<?php echo $this->get_field_name('include_parent_siblings'); ?>" type="checkbox"
|
783 |
value="1" <?php checked($instance['include_parent_siblings']); ?> />
|
784 |
<?php _e('& its Siblings'); ?></label>
|
785 |
-
<br /><label
|
786 |
<input id="<?php echo $this->get_field_id('include_ancestors'); ?>"
|
787 |
name="<?php echo $this->get_field_name('include_ancestors'); ?>" type="checkbox"
|
788 |
value="1" <?php checked($instance['include_ancestors']); ?> />
|
789 |
<?php _e('Include Ancestors'); ?></label>
|
790 |
-
<br /><label
|
791 |
<input id="<?php echo $this->get_field_id('title_from_parent'); ?>"
|
792 |
name="<?php echo $this->get_field_name('title_from_parent'); ?>" type="checkbox"
|
793 |
value="1" <?php checked($instance['title_from_parent']); ?> />
|
794 |
-
<?php _e('Title from Parent
|
795 |
-
<br /><small><em><?php _e('Only if the "Children of
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
796 |
</p>
|
797 |
|
798 |
<p>
|
799 |
<?php _e('Change UL to OL:'); ?>
|
800 |
-
<br /><label
|
801 |
<input id="<?php echo $this->get_field_id('ol_root'); ?>" name="<?php echo $this->get_field_name('ol_root'); ?>"
|
802 |
type="checkbox" value="1" <?php checked($instance['ol_root']); ?> />
|
803 |
<?php _e('Top Level'); ?></label>
|
804 |
-
<label
|
805 |
<input id="<?php echo $this->get_field_id('ol_sub'); ?>" name="<?php echo $this->get_field_name('ol_sub'); ?>"
|
806 |
type="checkbox" value="1" <?php checked($instance['ol_sub']); ?> />
|
807 |
<?php _e('Sub-Levels'); ?></label>
|
@@ -814,7 +925,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
814 |
if( $this->_pre_3point6() ){
|
815 |
?>
|
816 |
<p>
|
817 |
-
<label
|
818 |
<input id="<?php echo $this->get_field_id('hide_empty'); ?>" name="<?php echo $this->get_field_name('hide_empty'); ?>"
|
819 |
type="checkbox" value="1" <?php checked($instance['hide_empty']); ?> />
|
820 |
<?php _e('Hide Widget if Empty'); ?></label>
|
@@ -923,7 +1034,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
923 |
<input id="<?php echo $this->get_field_id($fname); ?>" class="hidden-field" name="<?php echo $this->get_field_name($fname); ?>"
|
924 |
type="checkbox" value="1" <?php checked($collapsed); ?> />
|
925 |
<div style="background:transparent url(images/arrows.png) no-repeat 0 <?php echo $collapsed ? '0' : '-36px'; ?>;height:16px; width:16px;float:right;outline:0 none;"></div>
|
926 |
-
<h3 style="font-size:1em;margin:0;padding:2px 0.5em;"><?php
|
927 |
</div>
|
928 |
<div class="hide-if-js"<?php echo !$collapsed ? ' style="display:block;"' : ''; ?>>
|
929 |
<?php
|
@@ -947,4 +1058,223 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
|
947 |
return version_compare( strtolower( $wp_version ), '3.6a', '<' );
|
948 |
} //end _pre_3point6()
|
949 |
|
950 |
-
} //end of class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
/*
|
3 |
* Plugin Name: Custom Menu Wizard
|
4 |
+
* Plugin URI: http://wordpress.org/plugins/custom-menu-wizard/
|
5 |
* Description: Full control over the wp_nav_menu parameters for a custom menu, plus the ability to filter for specific level(s), or for children of a selected menu item or the current item
|
6 |
+
* Version: 1.2.0
|
7 |
* Author: Roger Barrett
|
8 |
* Author URI: http://www.wizzud.com/
|
9 |
* License: GPL2+
|
10 |
*/
|
11 |
|
12 |
/*
|
13 |
+
* v1.2.0 change log:
|
14 |
+
* - added custom_menu_wizard shortcode, to run the widget from within content
|
15 |
+
* - moved the 'no ancestor' fallback into new Fallback collapsible section, and added a fallback for Current Item with no children
|
16 |
+
* - fixed bug with optgroups/options made available for the 'Children of' selector after the widget has been saved (also affecting disabled fields & styling)
|
17 |
+
* - don't include menus with no items
|
18 |
+
* - updated demo.html
|
19 |
+
*
|
20 |
* v1.1.0 change log:
|
21 |
* - added 'Current Root Item' and 'Current Parent Item' to the 'Children of' filter
|
22 |
* - added an Output option to include both the parent item and the parent's siblings (for a successful 'Children of' filter)
|
28 |
* - moved the setting of 'disabled' attributes on INPUTs/SELECTs from PHP into javascript
|
29 |
*/
|
30 |
|
31 |
+
$Custom_Menu_Wizard_Widget_Version = '1.2.0';
|
32 |
|
33 |
/**
|
34 |
+
* registers the widget and adds the shortcode
|
35 |
*/
|
36 |
function custom_menu_wizard_register_widget() {
|
37 |
register_widget('Custom_Menu_Wizard_Widget');
|
38 |
+
add_shortcode('custom_menu_wizard', 'custom_menu_wizard_widget_shortcode');
|
39 |
}
|
40 |
add_action('widgets_init', 'custom_menu_wizard_register_widget');
|
41 |
|
81 |
/**
|
82 |
* pre-filters elements then calls parent::walk()
|
83 |
*
|
84 |
+
* @filters : custom_menu_wizard_walker_items array of filtered menu elements; array of args
|
85 |
+
*
|
86 |
* @param array $elements Menu items
|
87 |
* @param integer $max_depth
|
88 |
* @return string
|
102 |
// include_parent : true = include the filter_item menu item
|
103 |
// include_parent_siblings : true = include the siblings (& parent) of the filter_item menu item
|
104 |
// include_ancestors : true = include the filter_item menu item plus all it's ancestors
|
105 |
+
// title_from_parent : true = widget wants parent's title
|
106 |
+
// title_from_current : true = widget wants current item's title (v1.2.0)
|
107 |
// start_level : integer, 1+
|
108 |
// depth : integer, replacement for max_depth and also applied to 'flat' output
|
109 |
// 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)
|
110 |
// fallback_include_parent : true = if fallback_no_ancestor comes into play then force include_parent to true (v1.1.0)
|
111 |
// fallback_include_parent_siblings : true = if fallback_no_ancestor comes into play then force include_parent_siblings to true (v1.1.0)
|
112 |
+
// 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)
|
113 |
+
// fallback_nc_include_parent : true = if fallback_no_children comes into play then force include_parent to true (v1.2.0)
|
114 |
+
// fallback_nc_include_parent_siblings : true = if fallback_no_children comes into play then force include_parent_siblings to true (v1.2.0)
|
115 |
//$elements is an array of objects, indexed by position within the menu (menu_order),
|
116 |
//starting at 1 and incrementing sequentially regardless of parentage (ie. first item is [1],
|
117 |
//second item is [2] whether it's at root or subordinate to first item)
|
118 |
+
$cmw['_titles'] = array();
|
119 |
|
120 |
$find_kids_of = $cmw['filter'];
|
121 |
$find_current_item = $find_kids_of && empty( $cmw['filter_item'] );
|
122 |
$find_current_parent = $find_kids_of && $cmw['filter_item'] == -1; //v1.1.0
|
123 |
$find_current_root = $find_kids_of && $cmw['filter_item'] == -2; //v1.1.0
|
124 |
+
$fallback_to_current_item = $cmw['fallback_no_ancestor'] && ( $find_current_parent || $find_current_root ); //v1.1.0
|
125 |
//these could change depending on whether a fallback comes into play (v1.1.0)
|
126 |
$include_parent = $cmw['include_parent'];
|
127 |
$include_parent_siblings = $cmw['include_parent_siblings'];
|
128 |
|
129 |
//are we looking for something in particular?...
|
130 |
if( $find_kids_of || $cmw['start_level'] > 1 ){
|
131 |
+
|
132 |
$id_field = $this->db_fields['id']; //eg. = 'db_id'
|
133 |
$parent_field = $this->db_fields['parent']; //eg. = 'menu_item_parent'
|
134 |
|
167 |
//also note that orphans (in the original menu) are ignored by this widget!
|
168 |
|
169 |
if( isset( $temp[ $item->$id_field ] ) ){
|
170 |
+
//let's keep track of current menu item (as index into $elements)...
|
171 |
+
if( $item->current ){
|
172 |
+
$ci_index = $i;
|
173 |
+
}
|
174 |
//are we at or below the start level?...
|
175 |
if( $temp[ $item->$id_field ]['level'] >= $start_level ){
|
176 |
//are we still looking for a starting point?...
|
184 |
//...we're looking for a current root ancestor, and this is one...
|
185 |
( $find_current_root && $item->current_item_ancestor ) ||
|
186 |
//...we've got a fallback for a top-level current item with no ancestor...
|
187 |
+
( $fallback_to_current_item && $item->current && $temp[ $item->$id_field ]['level'] == 1 ) ||
|
188 |
//...we're looking for a particular menu item, and this is it...
|
189 |
( $cmw['filter_item'] == $item->$id_field )
|
190 |
){
|
193 |
if( !$find_kids_of ){
|
194 |
$keep_items[] = $item;
|
195 |
}
|
196 |
+
//v1.1.0 if this was the fallback_no_ancestor option, we may need to update $include_parent[_siblings]...
|
197 |
+
if( $fallback_to_current_item && $item->current && $temp[ $item->$id_field ]['level'] == 1 ){
|
198 |
$include_parent = $include_parent || $cmw['fallback_include_parent'];
|
199 |
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_include_parent_siblings'];
|
200 |
}
|
213 |
//having found at least one, any more have to be:
|
214 |
// - within max_depth of the first one found, and
|
215 |
// - either it's an unspecific search, or we have the parent already
|
216 |
+
}elseif( $temp[ $item->$id_field ]['level'] <= $max_level && ( !$find_kids_of || in_array( $item->$parent_field, $keep_ids ) ) ){
|
217 |
$keep_ids[] = $item->$id_field;
|
218 |
$keep_items[] = $item;
|
219 |
}
|
221 |
}
|
222 |
} //end foreach
|
223 |
|
224 |
+
//v1.2.0 do we need to invoke the fallback for a childless 'children of current item'?...
|
225 |
+
//note that this is slightly different to the no_ancestor fallback, in that we are treating it like a switch from current item
|
226 |
+
//to current parent, *except* that here the fallback for not having an ancestor is to pretend there's a level-0 ancestor (above
|
227 |
+
//root); obviously it (the level-0 ancestor) will no item of its own, which means the kids now have no (real) parent
|
228 |
+
if( $find_current_item && $cmw['fallback_no_children'] && empty( $keep_items ) && !empty( $keep_ids ) ){
|
229 |
+
//what are the options?
|
230 |
+
// - the current item & its siblings
|
231 |
+
// - ... optionally plus its parent (if there is one)
|
232 |
+
// - ... optionally plus its parent (if there is one) and the parent's siblings
|
233 |
+
//keep_ids[0] is the id of the current item; put the parent's kids into keep_items...
|
234 |
+
foreach( $temp[ $temp[ $keep_ids[0] ]['parent'] ]['kids'] as $item ){
|
235 |
+
$keep_items[] = $item;
|
236 |
+
}
|
237 |
+
$include_parent = $include_parent || $cmw['fallback_nc_include_parent'];
|
238 |
+
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_nc_include_parent_siblings'];
|
239 |
+
}
|
240 |
+
|
241 |
unset( $keep_ids );
|
242 |
if( !empty( $keep_items) ){
|
243 |
|
248 |
//last element is now the parent (if there is one)
|
249 |
$i = $j = count( $breadcrumb );
|
250 |
|
251 |
+
//might we want the parent's title as the widget title?...
|
252 |
if( $find_kids_of && $cmw['title_from_parent'] && $i > 0 ){
|
253 |
+
$cmw['_titles']['parent'] = apply_filters(
|
254 |
'the_title',
|
255 |
$elements[ $breadcrumb[ $i - 1 ] ]->title,
|
256 |
$elements[ $breadcrumb[ $i - 1 ] ]->ID
|
257 |
);
|
258 |
}
|
259 |
+
//v1.2.0 might we want the current item's title as the widget title?...
|
260 |
+
//NB: using $ci_index because it's quite possible that the current menu item is not in $keep_items
|
261 |
+
if( !empty( $ci_index ) && $cmw['title_from_current'] ){
|
262 |
+
$cmw['_titles']['current'] = apply_filters(
|
263 |
+
'the_title',
|
264 |
+
$elements[ $ci_index ]->title,
|
265 |
+
$elements[ $ci_index ]->ID
|
266 |
+
);
|
267 |
+
}
|
268 |
|
269 |
//if we have a parent and we also want all the parent siblings, then we need
|
270 |
//to pop the parent off the bottom of temp and either append or prepend the
|
370 |
'fallback_no_ancestor', //v1.1.0 added
|
371 |
'fallback_include_parent', //v1.1.0 added
|
372 |
'fallback_include_parent_siblings', //v1.1.0 added
|
373 |
+
'fallback_no_children', //v1.2.0 added
|
374 |
+
'fallback_nc_include_parent', //v1.2.0 added
|
375 |
+
'fallback_nc_include_parent_siblings', //v1.2.0 added
|
376 |
'flat_output',
|
377 |
'include_parent',
|
378 |
'include_parent_siblings', //v1.1.0 added
|
379 |
'include_ancestors',
|
380 |
'hide_empty', //v1.1.0: this now only has relevance prior to WP v3.6
|
381 |
'title_from_parent',
|
382 |
+
'title_from_current', //v1.2.0 added
|
383 |
'ol_root',
|
384 |
'ol_sub',
|
385 |
//field section toggles...
|
386 |
'fs_filter',
|
387 |
+
'fs_fallbacks', //v1.2.0 added
|
388 |
'fs_output',
|
389 |
'fs_container',
|
390 |
'fs_classes',
|
421 |
array(
|
422 |
'classname' => 'widget_custom_menu_wizard',
|
423 |
'description' => __('Add a custom menu, or part of one, as a widget')
|
|
|
|
|
|
|
424 |
)
|
425 |
);
|
426 |
}
|
427 |
|
428 |
/**
|
429 |
+
* removes itself from the filters and, if available, stores current|parent title in the widget instance
|
430 |
*
|
431 |
* @param array $items Filtered menu items
|
432 |
* @param object $args
|
433 |
* @return array Menu items
|
434 |
*/
|
435 |
+
function cmw_filter_retain_possible_titles($items, $args){
|
436 |
remove_filter('custom_menu_wizard_walker_items', array( $this, 'cmw_filter_retain_parent_title' ), 10, 2);
|
437 |
+
foreach(array('parent', 'current') as $n){
|
438 |
+
if( !empty( $args->_custom_menu_wizard['_titles'][ $n ] ) ){
|
439 |
+
$this->cmw_titles[ $n ] = $args->_custom_menu_wizard['_titles'][ $n ];
|
440 |
+
}
|
441 |
}
|
442 |
return $items;
|
443 |
}
|
484 |
/**
|
485 |
* produces the widget HTML at the front end
|
486 |
*
|
487 |
+
* @filters : custom_menu_wizard_nav_params array of params that will be sent to wp_nav_menu()
|
488 |
+
*
|
489 |
* @param object $args Widget arguments
|
490 |
* @param array $instance Configuration for this widget instance
|
491 |
*/
|
512 |
//v1.1.0 As of WP v3.6, wp_nav_menu() automatically prevents any HTML output if there are no items...
|
513 |
$instance['hide_empty'] = $instance['hide_empty'] && $this->_pre_3point6();
|
514 |
|
515 |
+
$this->cmw_titles = array();
|
516 |
|
517 |
//fetch menu...
|
518 |
if( !empty($instance['menu'] ) ){
|
535 |
$instance['container_class'] = "menu-{$menu->slug}-container {$instance['container_class']}";
|
536 |
}
|
537 |
|
538 |
+
if( $instance['title_from_parent'] || $instance['title_from_current'] ){
|
539 |
+
add_filter('custom_menu_wizard_walker_items', array( $this, 'cmw_filter_retain_possible_titles' ), 10, 2);
|
540 |
}
|
541 |
|
542 |
if( $instance['hide_empty'] ){
|
564 |
'fallback_no_ancestor' => $instance['fallback_no_ancestor'], //v1.1.0
|
565 |
'fallback_include_parent' => $instance['fallback_include_parent'], //v1.1.0
|
566 |
'fallback_include_parent_siblings' => $instance['fallback_include_parent_siblings'], //v1.1.0
|
567 |
+
'fallback_no_children' => $instance['fallback_no_children'], //v1.2.0
|
568 |
+
'fallback_nc_include_parent' => $instance['fallback_nc_include_parent'], //v1.2.0
|
569 |
+
'fallback_nc_include_parent_siblings' => $instance['fallback_nc_include_parent_siblings'], //v1.2.0
|
570 |
'include_parent' => $instance['include_parent'],
|
571 |
'include_parent_siblings' => $instance['include_parent_siblings'], //v1.1.0
|
572 |
'include_ancestors' => $instance['include_ancestors'],
|
573 |
'title_from_parent' => $instance['title_from_parent'],
|
574 |
+
'title_from_current' => $instance['title_from_current'], //v1.2.0
|
575 |
'ol_root' => $instance['ol_root'],
|
576 |
'ol_sub' => $instance['ol_sub'],
|
577 |
'flat_output' => $instance['flat_output'],
|
586 |
$params['container_class'] = $instance['container_class'];
|
587 |
}
|
588 |
//NB: wp_nav_menu() is in wp-includes/nav-menu-template.php
|
589 |
+
$out = wp_nav_menu( apply_filters( 'custom_menu_wizard_nav_params', $params ) );
|
590 |
|
591 |
if( $instance['hide_empty'] ){
|
592 |
remove_filter( "wp_nav_menu_{$menu->slug}_items", array( $this, 'cmw_filter_check_for_no_items' ), 65532, 2 );
|
595 |
//only put something out if there is something to put out...
|
596 |
if( !empty( $out ) ){
|
597 |
|
598 |
+
//title from : 'from parent' has priority over 'from current'...
|
599 |
+
//note that 'parent' is whatever you are getting the children of and therefore doesn't apply to a ShowAll, whereas
|
600 |
+
//'current' is the current menu item (as determined by WP); also note that neither parent nor current actually has
|
601 |
+
//to be present in the results
|
602 |
+
if( $instance['title_from_parent'] && !empty( $this->cmw_titles['parent'] ) ){
|
603 |
+
$title = $this->cmw_titles['parent'];
|
604 |
+
}
|
605 |
+
if( empty( $title ) && $instance['title_from_current'] && !empty( $this->cmw_titles['current'] ) ){
|
606 |
+
$title = $this->cmw_titles['current'];
|
607 |
}
|
608 |
if( empty( $title ) ){
|
609 |
$title = $instance['hide_title'] ? '' : $instance['title'];
|
668 |
}
|
669 |
|
670 |
//get menus...
|
671 |
+
$menus = wp_get_nav_menus( array( 'orderby' => 'name' ) );
|
672 |
+
$noitems = true;
|
673 |
+
if( !empty( $menus ) ){
|
674 |
+
foreach( $menus as $i=>$menu ){
|
675 |
+
$menus[ $i ]->_items = wp_get_nav_menu_items( $menu->term_id );
|
676 |
+
if( !empty( $menus[ $i ]->_items ) ){
|
677 |
+
$noitems = false;
|
678 |
+
}
|
679 |
+
}
|
680 |
+
}
|
681 |
|
682 |
+
//if no populated menus exist, suggest the user go create one...
|
683 |
+
if( $noitems ){
|
684 |
+
echo '<p>'. sprintf( __('No populated menus have been created yet. <a href="%s">Create one</a>.'), admin_url('nav-menus.php') ) .'</p>';
|
685 |
return;
|
686 |
}
|
687 |
|
691 |
?>
|
692 |
<p>
|
693 |
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
|
694 |
+
<label class="alignright">
|
695 |
<input id="<?php echo $this->get_field_id('hide_title'); ?>" name="<?php echo $this->get_field_name('hide_title'); ?>"
|
696 |
type="checkbox" value="1" <?php checked( $instance['hide_title'] ); ?> />
|
697 |
<?php _e('Hide'); ?></label>
|
702 |
|
703 |
<p>
|
704 |
<label for="<?php echo $this->get_field_id('menu'); ?>"><?php _e('Select Menu:'); ?></label>
|
705 |
+
<select id="<?php echo $this->get_field_id('menu'); ?>"
|
706 |
+
class="widget-<?php echo $this->id_base; ?>-selectmenu widget-<?php echo $this->id_base; ?>-listen"
|
707 |
name="<?php echo $this->get_field_name('menu'); ?>">
|
708 |
<?php
|
709 |
foreach( $menus as $i=>$menu ){
|
710 |
+
if( !empty( $menu->_items ) ){
|
711 |
?>
|
712 |
<option <?php selected($instance['menu'], $menu->term_id); ?> value="<?php echo $menu->term_id; ?>"><?php echo $menu->name; ?></option>
|
713 |
<?php
|
714 |
+
}
|
715 |
}
|
716 |
?>
|
717 |
</select>
|
725 |
?>
|
726 |
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
727 |
<p>
|
728 |
+
<label>
|
729 |
<input id="<?php echo $this->get_field_id('filter'); ?>_0" class="widget-<?php echo $this->id_base; ?>-listen"
|
730 |
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="0" <?php checked(!$instance['filter']); ?> />
|
731 |
<?php _e('Show all'); ?></label>
|
732 |
+
<br /><label>
|
733 |
<input id="<?php echo $this->get_field_id('filter'); ?>_1" class="widget-<?php echo $this->id_base; ?>-listen"
|
734 |
name="<?php echo $this->get_field_name('filter'); ?>" type="radio" value="1" <?php checked($instance['filter']); ?> />
|
735 |
<?php _e('Children of:'); ?></label>
|
746 |
|
747 |
$maxlevel = 1;
|
748 |
foreach( $menus as $i=>$menu ){
|
749 |
+
//as of v1.2.0 : no items, no optgroup!
|
|
|
|
|
|
|
|
|
750 |
if( !empty( $menu->_items ) ){
|
751 |
+
//v1.1.0 changed the indents from padding to hyphen-space (for IE!!!! grrrr...)
|
752 |
+
$itemindents = array('0' => 0);
|
753 |
+
$menuOptions[] = '<optgroup label="' . $menu->name . '" data-cmw-optgroup-index="' . $i . '">';
|
754 |
foreach( $menu->_items as $item ){
|
755 |
//exclude orpans!
|
756 |
if( isset($itemindents[ $item->menu_item_parent ])){
|
761 |
str_repeat('- ', $itemindents[ $item->menu_item_parent ]) . $item->title . '</option>';
|
762 |
}
|
763 |
}
|
764 |
+
$menuOptions[] = '</optgroup>';
|
765 |
}
|
|
|
766 |
}
|
767 |
$menuOptions = implode("\n", $menuOptions);
|
768 |
echo $menuOptions;
|
775 |
</select>
|
776 |
</p>
|
777 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
778 |
<p>
|
779 |
<label for="<?php echo $this->get_field_id('start_level'); ?>"><?php _e('Starting Level:'); ?></label>
|
780 |
<select id="<?php echo $this->get_field_id('start_level'); ?>" name="<?php echo $this->get_field_name('start_level'); ?>">
|
807 |
</p>
|
808 |
<?php $this->_close_a_field_section(); ?>
|
809 |
|
810 |
+
<?php
|
811 |
+
/**
|
812 |
+
* v1.2.0 start collapsible section : 'Fallbacks'
|
813 |
+
*/
|
814 |
+
$this->_open_a_field_section($instance, 'Fallbacks', 'fs_fallbacks');
|
815 |
+
?>
|
816 |
+
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
817 |
+
<p class="clear widget-<?php echo $this->id_base; ?>-disableifnot-rp" style="line-height:1.3333;">
|
818 |
+
<small><strong><?php _e( 'If "Children of" is <em>Current Root / Parent Item</em>, and no ancestor exists' ); ?> :</strong></small>
|
819 |
+
<br /><label>
|
820 |
+
<input id="<?php echo $this->get_field_id('fallback_no_ancestor'); ?>"
|
821 |
+
name="<?php echo $this->get_field_name('fallback_no_ancestor'); ?>" type="checkbox" value="1"
|
822 |
+
<?php checked($instance['fallback_no_ancestor']); ?> />
|
823 |
+
<?php _e('Switch to Current Item, and'); ?></label>
|
824 |
+
<br /><label style="padding-left:1em;">
|
825 |
+
<input id="<?php echo $this->get_field_id('fallback_include_parent'); ?>"
|
826 |
+
name="<?php echo $this->get_field_name('fallback_include_parent'); ?>" type="checkbox" value="1"
|
827 |
+
<?php checked($instance['fallback_include_parent']); ?> />
|
828 |
+
<?php _e('Include Parent...'); ?> </label>
|
829 |
+
<label>
|
830 |
+
<input id="<?php echo $this->get_field_id('fallback_include_parent_siblings'); ?>"
|
831 |
+
name="<?php echo $this->get_field_name('fallback_include_parent_siblings'); ?>" type="checkbox" value="1"
|
832 |
+
<?php checked($instance['fallback_include_parent_siblings']); ?> />
|
833 |
+
<?php _e('& its Siblings'); ?></label>
|
834 |
+
</p>
|
835 |
+
|
836 |
+
<p class="widget-<?php echo $this->id_base; ?>-disableifnot-ci" style="line-height:1.3333;">
|
837 |
+
<small><strong><?php _e( 'If "Children of" is <em>Current Item</em>, and current item has no children' ); ?> :</strong></small>
|
838 |
+
<br /><label>
|
839 |
+
<input id="<?php echo $this->get_field_id('fallback_no_children'); ?>"
|
840 |
+
name="<?php echo $this->get_field_name('fallback_no_children'); ?>" type="checkbox" value="1"
|
841 |
+
<?php checked($instance['fallback_no_children']); ?> />
|
842 |
+
<?php _e('Switch to Current Parent Item, and'); ?></label>
|
843 |
+
<br /><label style="padding-left:1em;">
|
844 |
+
<input id="<?php echo $this->get_field_id('fallback_nc_include_parent'); ?>"
|
845 |
+
name="<?php echo $this->get_field_name('fallback_nc_include_parent'); ?>" type="checkbox" value="1"
|
846 |
+
<?php checked($instance['fallback_nc_include_parent']); ?> />
|
847 |
+
<?php _e('Include Parent...'); ?> </label>
|
848 |
+
<label>
|
849 |
+
<input id="<?php echo $this->get_field_id('fallback_nc_include_parent_siblings'); ?>"
|
850 |
+
name="<?php echo $this->get_field_name('fallback_nc_include_parent_siblings'); ?>" type="checkbox" value="1"
|
851 |
+
<?php checked($instance['fallback_nc_include_parent_siblings']); ?> />
|
852 |
+
<?php _e('& its Siblings'); ?></label>
|
853 |
+
</p>
|
854 |
+
|
855 |
+
|
856 |
+
<?php $this->_close_a_field_section(); ?>
|
857 |
+
|
858 |
<?php
|
859 |
/**
|
860 |
* start collapsible section : 'Output'
|
863 |
?>
|
864 |
<small class="alignright" style="line-height:1;"><a href="<?php echo plugins_url('/demo.html', __FILE__); ?>" target="_blank"><?php _e(' demo' ); ?></a></small>
|
865 |
<p>
|
866 |
+
<label>
|
867 |
<input id="<?php echo $this->get_field_id('flat_output'); ?>_0" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
868 |
type="radio" value="0" <?php checked(!$instance['flat_output']); ?> />
|
869 |
<?php _e('Hierarchical'); ?></label>
|
870 |
+
<label>
|
871 |
<input id="<?php echo $this->get_field_id('flat_output'); ?>_1" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
872 |
type="radio" value="1" <?php checked($instance['flat_output']); ?> />
|
873 |
<?php _e('Flat'); ?></label>
|
874 |
</p>
|
875 |
|
876 |
<p class="widget-<?php echo $this->id_base; ?>-disableif">
|
877 |
+
<label>
|
878 |
<input id="<?php echo $this->get_field_id('include_parent'); ?>"
|
879 |
name="<?php echo $this->get_field_name('include_parent'); ?>" type="checkbox"
|
880 |
value="1" <?php checked($instance['include_parent']); ?> />
|
881 |
<?php _e('Include Parent...'); ?> </label>
|
882 |
+
<label>
|
883 |
<input id="<?php echo $this->get_field_id('include_parent_siblings'); ?>"
|
884 |
name="<?php echo $this->get_field_name('include_parent_siblings'); ?>" type="checkbox"
|
885 |
value="1" <?php checked($instance['include_parent_siblings']); ?> />
|
886 |
<?php _e('& its Siblings'); ?></label>
|
887 |
+
<br /><label>
|
888 |
<input id="<?php echo $this->get_field_id('include_ancestors'); ?>"
|
889 |
name="<?php echo $this->get_field_name('include_ancestors'); ?>" type="checkbox"
|
890 |
value="1" <?php checked($instance['include_ancestors']); ?> />
|
891 |
<?php _e('Include Ancestors'); ?></label>
|
892 |
+
<br /><label>
|
893 |
<input id="<?php echo $this->get_field_id('title_from_parent'); ?>"
|
894 |
name="<?php echo $this->get_field_name('title_from_parent'); ?>" type="checkbox"
|
895 |
value="1" <?php checked($instance['title_from_parent']); ?> />
|
896 |
+
<?php _e('Title from Parent'); ?></label>
|
897 |
+
<br /><small><em><?php _e('Only if the "Children of" Filter returns items'); ?></em></small>
|
898 |
+
</p>
|
899 |
+
|
900 |
+
<p>
|
901 |
+
<label>
|
902 |
+
<input id="<?php echo $this->get_field_id('title_from_current'); ?>"
|
903 |
+
name="<?php echo $this->get_field_name('title_from_current'); ?>" type="checkbox"
|
904 |
+
value="1" <?php checked($instance['title_from_current']); ?> />
|
905 |
+
<?php _e('Title from "Current" Item'); ?></label>
|
906 |
+
<br /><small><em><?php _e('Lower priority than "Title from Parent"'); ?></em></small>
|
907 |
</p>
|
908 |
|
909 |
<p>
|
910 |
<?php _e('Change UL to OL:'); ?>
|
911 |
+
<br /><label>
|
912 |
<input id="<?php echo $this->get_field_id('ol_root'); ?>" name="<?php echo $this->get_field_name('ol_root'); ?>"
|
913 |
type="checkbox" value="1" <?php checked($instance['ol_root']); ?> />
|
914 |
<?php _e('Top Level'); ?></label>
|
915 |
+
<label>
|
916 |
<input id="<?php echo $this->get_field_id('ol_sub'); ?>" name="<?php echo $this->get_field_name('ol_sub'); ?>"
|
917 |
type="checkbox" value="1" <?php checked($instance['ol_sub']); ?> />
|
918 |
<?php _e('Sub-Levels'); ?></label>
|
925 |
if( $this->_pre_3point6() ){
|
926 |
?>
|
927 |
<p>
|
928 |
+
<label>
|
929 |
<input id="<?php echo $this->get_field_id('hide_empty'); ?>" name="<?php echo $this->get_field_name('hide_empty'); ?>"
|
930 |
type="checkbox" value="1" <?php checked($instance['hide_empty']); ?> />
|
931 |
<?php _e('Hide Widget if Empty'); ?></label>
|
1034 |
<input id="<?php echo $this->get_field_id($fname); ?>" class="hidden-field" name="<?php echo $this->get_field_name($fname); ?>"
|
1035 |
type="checkbox" value="1" <?php checked($collapsed); ?> />
|
1036 |
<div style="background:transparent url(images/arrows.png) no-repeat 0 <?php echo $collapsed ? '0' : '-36px'; ?>;height:16px; width:16px;float:right;outline:0 none;"></div>
|
1037 |
+
<h3 style="font-size:1em;margin:0;padding:2px 0.5em;"><?php _e( $text ); ?></h3>
|
1038 |
</div>
|
1039 |
<div class="hide-if-js"<?php echo !$collapsed ? ' style="display:block;"' : ''; ?>>
|
1040 |
<?php
|
1058 |
return version_compare( strtolower( $wp_version ), '3.6a', '<' );
|
1059 |
} //end _pre_3point6()
|
1060 |
|
1061 |
+
} //end of class
|
1062 |
+
|
1063 |
+
/**
|
1064 |
+
* as of v1.2.0
|
1065 |
+
* shortcode processing for [custom_menu_wizard option="" option="" ...]
|
1066 |
+
* see wp-includes/widgets.php for the_widget() code
|
1067 |
+
* Note that hide_empty is set to ON and can not be overridden!
|
1068 |
+
*
|
1069 |
+
* default (ie. no options) is:
|
1070 |
+
* - show all
|
1071 |
+
* - of first populated menu found (alphabetically)
|
1072 |
+
* - from root, for unlimited depth
|
1073 |
+
* - as hierarchical nested ULs inside a DIV.widget_custom_menu_wizard.shortcode_custom_menu_wizard
|
1074 |
+
*
|
1075 |
+
* @filters : custom_menu_wizard_shortcode_attributes array of attributes supplied to the shortcode
|
1076 |
+
* custom_menu_wizard_shortcode_settings array of widget settings derived from the attributes
|
1077 |
+
* custom_menu_wizard_shortcode_widget_args array of the sidebar args used to wrap widgets and their titles (before|after_widget, before|after_title)
|
1078 |
+
*
|
1079 |
+
* @param array $atts options supplied to the shortcode
|
1080 |
+
* @param string $content Within start-end shortcode tags
|
1081 |
+
* @param string $tag Shortcode tag
|
1082 |
+
* @return string HTML
|
1083 |
+
*/
|
1084 |
+
function custom_menu_wizard_widget_shortcode($atts, $content, $tag){
|
1085 |
+
$html = '';
|
1086 |
+
$ok = false;
|
1087 |
+
$instance = shortcode_atts( array(
|
1088 |
+
'title' => '',
|
1089 |
+
'menu' => 0, // menu id, slug or name
|
1090 |
+
//determines filter & filter_item...
|
1091 |
+
'children_of' => '', // empty = show all; menu item id or title (caseless), or current|current-item|parent|current-parent|root|current-ancestor
|
1092 |
+
'start_level' => 1,
|
1093 |
+
'depth' => 0, // 0 = unlimited
|
1094 |
+
//only if children_of is (parent|current-parent|root|current-ancestor); determines fallback_no_ancestor, fallback_include_parent & fallback_include_parent_siblings...
|
1095 |
+
'fallback_parent' => 0, // 1 = use current-item; 'parent' = *and* include parent, 'siblings' = *and* include both parent and its siblings
|
1096 |
+
//only if children_of is (current|current-item); determines fallback_no_children, fallback_nc_include_parent & fallback_nc_include_parent_siblings...
|
1097 |
+
'fallback_current' => 0, // 1 = use current-parent; 'parent' = *and* include parent (if available), 'siblings' = *and* include both parent (if available) and its siblings
|
1098 |
+
//switches...
|
1099 |
+
'flat_output' => 0,
|
1100 |
+
//determines include_parent, include_parent_siblings & include_ancestors...
|
1101 |
+
'include' =>'', //comma|space|hyphen separated list of 'parent', 'siblings', 'ancestors'
|
1102 |
+
'ol_root' => 0,
|
1103 |
+
'ol_sub' => 0,
|
1104 |
+
//determines title_from_parent & title_from_current...
|
1105 |
+
'title_from' => '', //comma|space|hyphen separated list of 'parent', 'current'
|
1106 |
+
//strings...
|
1107 |
+
'container' => 'div', // a tag : div|nav are WP restrictions, not the widget's; '' = no container
|
1108 |
+
'container_id' => '',
|
1109 |
+
'container_class' => '',
|
1110 |
+
'menu_class' => 'menu-widget',
|
1111 |
+
'widget_class' => '',
|
1112 |
+
//determines before & after...
|
1113 |
+
'wrap_link' => '', // a tag name (eg. div, p, span, etc)
|
1114 |
+
//determines link_before & link_after...
|
1115 |
+
'wrap_link_text' => '' // a tag name (eg. span, em, strong)
|
1116 |
+
), $atts );
|
1117 |
+
|
1118 |
+
$instance = apply_filters( 'custom_menu_wizard_shortcode_attributes', $instance );
|
1119 |
+
|
1120 |
+
if( empty( $instance['menu'] ) ){
|
1121 |
+
//gonna find the first menu (alphabetically) that has items...
|
1122 |
+
$menus = wp_get_nav_menus( array( 'orderby' => 'name' ) );
|
1123 |
+
}else{
|
1124 |
+
//allow for menu being something other than an id (eg. slug or name), but we need the id for the widget...
|
1125 |
+
$menus = wp_get_nav_menu_object( $instance['menu'] );
|
1126 |
+
if( !empty( $menus) ){
|
1127 |
+
$menus = array( $menus );
|
1128 |
+
}
|
1129 |
+
}
|
1130 |
+
if( !empty( $menus ) ){
|
1131 |
+
foreach( $menus as $i=>$menu ){
|
1132 |
+
$items = wp_get_nav_menu_items( $menu->term_id );
|
1133 |
+
$ok = !empty( $items );
|
1134 |
+
if( $ok ){
|
1135 |
+
$instance['menu'] = $menu->term_id;
|
1136 |
+
break;
|
1137 |
+
}
|
1138 |
+
}
|
1139 |
+
}
|
1140 |
+
unset( $menus );
|
1141 |
+
|
1142 |
+
if( $ok ){
|
1143 |
+
//children_of => filter & filter_item...
|
1144 |
+
if( empty( $instance['children_of'] ) ){
|
1145 |
+
$instance['children_of'] = '';
|
1146 |
+
}
|
1147 |
+
$instance['filter'] = $instance['filter_item'] = 0;
|
1148 |
+
switch( $instance['children_of'] ){
|
1149 |
+
case '':
|
1150 |
+
break;
|
1151 |
+
case 'root': case 'current-ancestor':
|
1152 |
+
--$instance['filter_item']; //ends up as -2
|
1153 |
+
case 'parent': case 'current-parent':
|
1154 |
+
--$instance['filter_item']; //ends up as -1
|
1155 |
+
case 'current': case 'current-item':
|
1156 |
+
$instance['filter'] = 1;
|
1157 |
+
break;
|
1158 |
+
default:
|
1159 |
+
$instance['filter'] = 1;
|
1160 |
+
$instance['filter_item'] = strtolower( $instance['children_of'] );
|
1161 |
+
}
|
1162 |
+
unset( $instance['children_of'] );
|
1163 |
+
//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...
|
1164 |
+
if( !is_numeric( $instance['filter_item'] ) ){
|
1165 |
+
foreach( $items as $item ){
|
1166 |
+
$ok = strtolower( $item->title ) == $instance['filter_item'];
|
1167 |
+
if( $ok ){
|
1168 |
+
$instance['filter_item'] = $item->ID;
|
1169 |
+
break;
|
1170 |
+
}
|
1171 |
+
}
|
1172 |
+
}
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
if( $ok ){
|
1176 |
+
//fallback_parent => fallback_no_ancestor switch (and extension switches)...
|
1177 |
+
$instance['fallback_no_ancestor'] = $instance['fallback_include_parent'] = $instance['fallback_include_parent_siblings'] = 0;
|
1178 |
+
if( $instance['filter_item'] < 0 && !empty( $instance['fallback_parent'] ) ){
|
1179 |
+
$instance['fallback_no_ancestor'] = 1;
|
1180 |
+
$i = preg_split( '/[\s,-]+/', strtolower( $instance['fallback_parent'] ), -1, PREG_SPLIT_NO_EMPTY );
|
1181 |
+
foreach( $i as $j ){
|
1182 |
+
if( $j == 'parent' ){
|
1183 |
+
$instance['fallback_include_parent'] = 1;
|
1184 |
+
}elseif( $j == 'siblings' ){
|
1185 |
+
$instance['fallback_include_parent_siblings'] = 1;
|
1186 |
+
}
|
1187 |
+
}
|
1188 |
+
}
|
1189 |
+
//fallback_current => fallback_no_children switch (and extension switches)...
|
1190 |
+
$instance['fallback_no_children'] = $instance['fallback_nc_include_parent'] = $instance['fallback_nc_include_parent_siblings'] = 0;
|
1191 |
+
if( $instance['filter'] == 1 && $instance['filter_item'] == 0 && !empty( $instance['fallback_current'] ) ){
|
1192 |
+
$instance['fallback_no_children'] = 1;
|
1193 |
+
$i = preg_split( '/[\s,-]+/', strtolower( $instance['fallback_current'] ), -1, PREG_SPLIT_NO_EMPTY );
|
1194 |
+
foreach( $i as $j ){
|
1195 |
+
if( $j == 'parent' ){
|
1196 |
+
$instance['fallback_nc_include_parent'] = 1;
|
1197 |
+
}elseif( $j == 'siblings' ){
|
1198 |
+
$instance['fallback_nc_include_parent_siblings'] = 1;
|
1199 |
+
}
|
1200 |
+
}
|
1201 |
+
}
|
1202 |
+
unset( $instance['fallback_parent'], $instance['fallback_current'] );
|
1203 |
+
//include => include_* ...
|
1204 |
+
$instance['include_parent'] = $instance['include_parent_siblings'] = $instance['include_ancestors'] = 0;
|
1205 |
+
if( $instance['filter'] == 1 && !empty( $instance['include'] ) ){
|
1206 |
+
$i = preg_split( '/[\s,-]+/', strtolower( $instance['include'] ), -1, PREG_SPLIT_NO_EMPTY );
|
1207 |
+
foreach( $i as $j ){
|
1208 |
+
if( $j == 'parent' ){
|
1209 |
+
$instance['include_parent'] = 1;
|
1210 |
+
}elseif( $j == 'siblings' ){
|
1211 |
+
$instance['include_parent_siblings'] = 1;
|
1212 |
+
}elseif( $j == 'ancestors' ){
|
1213 |
+
$instance['include_ancestors'] = 1;
|
1214 |
+
}
|
1215 |
+
}
|
1216 |
+
}
|
1217 |
+
unset( $instance['include'] );
|
1218 |
+
//title_from => title_from_parent, title_from_current ...
|
1219 |
+
$instance['title_from_parent'] = $instance['title_from_current'] = 0;
|
1220 |
+
if( !empty( $instance['title_from'] ) ){
|
1221 |
+
$i = preg_split( '/[\s,-]+/', strtolower( $instance['title_from'] ), -1, PREG_SPLIT_NO_EMPTY );
|
1222 |
+
foreach( $i as $j ){
|
1223 |
+
if( $j == 'parent' ){
|
1224 |
+
$instance['title_from_parent'] = 1;
|
1225 |
+
}elseif( $j == 'current' ){
|
1226 |
+
$instance['title_from_current'] = 1;
|
1227 |
+
}
|
1228 |
+
}
|
1229 |
+
}
|
1230 |
+
unset( $instance['title_from'] );
|
1231 |
+
//wrap_link => before & after...
|
1232 |
+
$instance['before'] = $instance['after'] = '';
|
1233 |
+
$instance['wrap_link'] = esc_attr( trim( $instance['wrap_link'] ) );
|
1234 |
+
if( !empty( $instance['wrap_link'] ) ){
|
1235 |
+
$instance['before'] = '<' . $instance['wrap_link'] . '>';
|
1236 |
+
$instance['after'] = '</' . $instance['wrap_link'] . '>';
|
1237 |
+
}
|
1238 |
+
//wrap_link_text => link_before & link_after...
|
1239 |
+
$instance['link_before'] = $instance['link_after'] = '';
|
1240 |
+
$instance['wrap_link_text'] = esc_attr( trim( $instance['wrap_link_text'] ) );
|
1241 |
+
if( !empty( $instance['wrap_link_text'] ) ){
|
1242 |
+
$instance['link_before'] = '<' . $instance['wrap_link_text'] . '>';
|
1243 |
+
$instance['link_after'] = '</' . $instance['wrap_link_text'] . '>';
|
1244 |
+
}
|
1245 |
+
//handle widget_class here because we have full control over $before_widget...
|
1246 |
+
$before_widget_class = array(
|
1247 |
+
'widget_custom_menu_wizard',
|
1248 |
+
'shortcode_custom_menu_wizard'
|
1249 |
+
);
|
1250 |
+
$instance['widget_class'] = empty( $instance['widget_class'] ) ? '' : esc_attr( trim ( $instance['widget_class'] ) );
|
1251 |
+
if( !empty( $instance['widget_class'] ) ){
|
1252 |
+
foreach( explode(' ', $instance['widget_class'] ) as $i ){
|
1253 |
+
if( !empty( $i ) && !in_array( $i, $before_widget_class ) ){
|
1254 |
+
$before_widget_class[] = $i;
|
1255 |
+
}
|
1256 |
+
}
|
1257 |
+
}
|
1258 |
+
$instance['widget_class'] = '';
|
1259 |
+
//turn on hide_empty...
|
1260 |
+
$instance['hide_empty'] = 1;
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
if( $ok ){
|
1264 |
+
//apart from before_title, these are lifted from the_widget()...
|
1265 |
+
$sidebar_args = array(
|
1266 |
+
'before_widget' => '<div class="' . implode( ' ', $before_widget_class ) . '">',
|
1267 |
+
'after_widget' => '</div>',
|
1268 |
+
'before_title' => '<h2 class="widgettitle">',
|
1269 |
+
'after_title' => '</h2>'
|
1270 |
+
);
|
1271 |
+
ob_start();
|
1272 |
+
the_widget(
|
1273 |
+
'Custom_Menu_Wizard_Widget',
|
1274 |
+
apply_filters('custom_menu_wizard_shortcode_settings', $instance ),
|
1275 |
+
apply_filters('custom_menu_wizard_shortcode_widget_args', $sidebar_args )
|
1276 |
+
);
|
1277 |
+
$html = ob_get_clean();
|
1278 |
+
}
|
1279 |
+
return empty($html) ? '' : $html;
|
1280 |
+
}
|
demo.html
CHANGED
@@ -21,20 +21,21 @@
|
|
21 |
#formheader {background-color:#666666; border-radius:0.4em 0.4em 0 0; color:#FFFFFF; margin:0 -1em -0.5em; padding:0.25em 1em; text-align:center;}
|
22 |
#theform {margin:1em; padding:0 1em; border:1px solid #999999; border-radius:0.5em;}
|
23 |
#theoutput {margin:1em;}
|
24 |
-
#
|
25 |
-
#
|
26 |
-
#
|
27 |
-
#
|
28 |
-
#
|
29 |
-
#
|
30 |
-
#
|
31 |
-
#
|
32 |
-
#
|
33 |
-
#
|
34 |
-
#
|
35 |
-
#
|
36 |
-
#
|
37 |
-
#
|
|
|
38 |
#themenu {margin:1em;}
|
39 |
#themenu ul {font-size:12px; list-style-type:none; margin:1em 0; padding:0;}
|
40 |
#themenu ul ul {margin:0 0 0 5em;}
|
@@ -45,9 +46,14 @@
|
|
45 |
#thefooter div {font-size:12px;}
|
46 |
.alignleft {float:left;}
|
47 |
.alignright {float:right;}
|
48 |
-
.
|
49 |
-
.
|
50 |
-
.
|
|
|
|
|
|
|
|
|
|
|
51 |
.grey {color:#999999;}
|
52 |
.picked > a {background-color:#000066; color:#ffffff; font-weight:bold;}
|
53 |
.tryit {margin-left:1em; text-shadow:1px 1px 1px #ff0000;}
|
@@ -60,7 +66,7 @@
|
|
60 |
<form>
|
61 |
<div id="formheader">
|
62 |
<strong>Custom Menu Wizard</strong> Interactive Demo
|
63 |
-
<br /><small>v1.
|
64 |
</div>
|
65 |
|
66 |
<p>
|
@@ -72,6 +78,8 @@
|
|
72 |
<small><em>Title can be set, but need not be displayed</em></small>
|
73 |
</p>
|
74 |
|
|
|
|
|
75 |
<p>
|
76 |
<label>
|
77 |
<input type="radio" checked="checked" value="0" name="filter" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_0">
|
@@ -83,23 +91,10 @@
|
|
83 |
<option selected="selected" value="0">Current Item</option>
|
84 |
<option value="-2">Current Root Item</option>
|
85 |
<option value="-1">Current Parent Item</option>
|
86 |
-
<optgroup label="the-menu"
|
87 |
</select>
|
88 |
</p>
|
89 |
|
90 |
-
<p class="widget-custom-menu-wizard-enableif">
|
91 |
-
<label>
|
92 |
-
<input type="checkbox" value="1" name="fallback_no_ancestor" id="widget-custom-menu-wizard-2-fallback_no_ancestor">
|
93 |
-
Fallback to Current Item, and</label>
|
94 |
-
<br /><label style="padding-left:1em;">
|
95 |
-
<input type="checkbox" value="1" name="fallback_include_parent" id="widget-custom-menu-wizard-2-fallback_include_parent">
|
96 |
-
Include Parent... </label>
|
97 |
-
<label>
|
98 |
-
<input type="checkbox" value="1" name="fallback_include_parent_siblings" id="widget-custom-menu-wizard-2-fallback_include_parent_siblings">
|
99 |
-
& its Siblings</label>
|
100 |
-
<br /><small><em>If Current Root/Parent and no ancestor exists</em></small>
|
101 |
-
</p>
|
102 |
-
|
103 |
<p>
|
104 |
<label for="widget-custom-menu-wizard-2-start_level">Starting Level:</label>
|
105 |
<select name="start_level" id="widget-custom-menu-wizard-2-start_level">
|
@@ -115,6 +110,37 @@
|
|
115 |
<br /><small><em>Relative to the first Filtered item found</em></small>
|
116 |
</p>
|
117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
<p>
|
119 |
<label>
|
120 |
<input type="radio" checked="checked" value="0" name="flat_output" id="widget-custom-menu-wizard-2-flat_output_0">
|
@@ -136,8 +162,15 @@
|
|
136 |
Include Ancestors</label>
|
137 |
<br /><label>
|
138 |
<input type="checkbox" value="1" name="title_from_parent" id="widget-custom-menu-wizard-2-title_from_parent">
|
139 |
-
Title from Parent
|
140 |
-
<br /><small><em>Only if the "Children of
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
</p>
|
142 |
|
143 |
<p>
|
@@ -150,7 +183,7 @@
|
|
150 |
Sub-Levels</label>
|
151 |
</p>
|
152 |
|
153 |
-
<p class="grey">
|
154 |
<small><em>Note that since WP v3.6 does it automatically,
|
155 |
<br />"Hide Widget if Empty" is ON for this demo.</em></small>
|
156 |
</p>
|
@@ -162,6 +195,7 @@
|
|
162 |
<div id='theoutput' class='alignright'>
|
163 |
<strong>Basic Output</strong> …
|
164 |
<div id='widget-output'></div>
|
|
|
165 |
</div>
|
166 |
|
167 |
<div id='themenu' class='alignleft'>
|
@@ -228,6 +262,9 @@
|
|
228 |
</li>
|
229 |
</ul>
|
230 |
</li>
|
|
|
|
|
|
|
231 |
</ul>
|
232 |
</div>
|
233 |
|
@@ -242,7 +279,7 @@
|
|
242 |
<script type='text/javascript'>
|
243 |
jQuery(function($){
|
244 |
var maxlevel = 0,
|
245 |
-
switches = {hide_title:1, filter:1, fallback_no_ancestor:1, fallback_include_parent:1, fallback_include_parent_siblings:1, flat_output:1, include_parent:1, include_parent_siblings:1, include_ancestors:1, title_from_parent:1, ol_root:1, ol_sub:1},
|
246 |
integers = {filter_item:1, start_level:1, depth:1},
|
247 |
getSettings = function(){
|
248 |
var settings = {};
|
@@ -262,16 +299,23 @@ jQuery(function($){
|
|
262 |
var output = $('#widget-output').empty(),
|
263 |
items = $('.picked'),
|
264 |
html = '',
|
|
|
265 |
currLevel = 0,
|
266 |
-
startLevel
|
267 |
settings = settings || getSettings();
|
268 |
if(items.length){
|
269 |
-
title = settings.hide_title ? '' : settings.title;
|
270 |
if(settings.filter && settings.title_from_parent){
|
271 |
title = $('.picked-parent').children('a').text() || '';
|
272 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
items.each(function(){
|
274 |
-
var level = settings.flat_output ? 1 : parseInt(this.className.match(/level-(\d+)/)[1], 10)
|
|
|
275 |
if(currLevel){
|
276 |
if(level === currLevel){
|
277 |
html += '</li>';
|
@@ -285,7 +329,7 @@ jQuery(function($){
|
|
285 |
}else{
|
286 |
startLevel = level;
|
287 |
}
|
288 |
-
html += '<li><a href="#
|
289 |
currLevel = level;
|
290 |
});
|
291 |
while(currLevel-- > startLevel){
|
@@ -296,6 +340,9 @@ jQuery(function($){
|
|
296 |
if(title){
|
297 |
output.prepend('<h3>' + title + '</h3>');
|
298 |
}
|
|
|
|
|
|
|
299 |
}
|
300 |
},
|
301 |
walk = function(e){
|
@@ -306,6 +353,7 @@ jQuery(function($){
|
|
306 |
picked = items.filter('.picked'),
|
307 |
cls = [],
|
308 |
firstParent = true,
|
|
|
309 |
parent, i;
|
310 |
if(!settings.filter){
|
311 |
//show all...
|
@@ -334,6 +382,7 @@ jQuery(function($){
|
|
334 |
parent = $('.current-item').closest('li');
|
335 |
includeParent = includeParent || settings.fallback_include_parent;
|
336 |
includeParentSiblings = includeParentSiblings || settings.fallback_include_parent_siblings;
|
|
|
337 |
}
|
338 |
}
|
339 |
//could be multiple - only want first one that matches start_level...
|
@@ -351,6 +400,14 @@ jQuery(function($){
|
|
351 |
});
|
352 |
//kids...
|
353 |
items = parent.find('li').filter( cls.join(',') );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
if(items.length){
|
355 |
if(includeParentSiblings){
|
356 |
items = items.add( parent.siblings('li') ).add( parent );
|
@@ -366,12 +423,12 @@ jQuery(function($){
|
|
366 |
parent.addClass('picked-parent');
|
367 |
}
|
368 |
}
|
|
|
369 |
picked.not(items).removeClass('picked');
|
370 |
items.not('.picked').addClass('picked');
|
371 |
show.call(this, e, settings);
|
372 |
},
|
373 |
flds = $('input,select');
|
374 |
-
$('#widget-output').on('click', 'a', false);
|
375 |
$('#themenu a').on('click', function(){
|
376 |
//click on a #themenu item to [un]make it the current item...
|
377 |
var cls = ['current-item', 'current-parent', 'current-ancestor'],
|
@@ -389,12 +446,18 @@ jQuery(function($){
|
|
389 |
return false;
|
390 |
}).map(function(i){
|
391 |
//create filter_item's optgroup options...
|
392 |
-
var el = $(this),
|
393 |
level = el.parentsUntil('#themenu', 'li').length;
|
394 |
maxlevel = Math.max(maxlevel, level);
|
395 |
el.parent().addClass('level-' + level);
|
396 |
return $('<option/>', {value:i + 1}).text( hyphenIndent(el.text(), level) ).get(0);
|
397 |
}).appendTo('optgroup');
|
|
|
|
|
|
|
|
|
|
|
|
|
398 |
//populate starting-level and depth options...
|
399 |
for(i = 1; i < maxlevel + 1; i++){
|
400 |
var levels = i < 2 ? ' level' : ' levels',
|
@@ -405,13 +468,24 @@ jQuery(function($){
|
|
405 |
}
|
406 |
$('<option/>', att).text(i).appendTo('#widget-custom-menu-wizard-2-start_level');
|
407 |
}
|
|
|
|
|
|
|
|
|
408 |
$('button').on('click', function(){
|
409 |
$(this).parent().get(0).reset();
|
410 |
$('#widget-custom-menu-wizard-2-filter_item').trigger('change');
|
411 |
return false;
|
412 |
-
});
|
413 |
-
|
414 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
});
|
416 |
</script>
|
417 |
</body>
|
21 |
#formheader {background-color:#666666; border-radius:0.4em 0.4em 0 0; color:#FFFFFF; margin:0 -1em -0.5em; padding:0.25em 1em; text-align:center;}
|
22 |
#theform {margin:1em; padding:0 1em; border:1px solid #999999; border-radius:0.5em;}
|
23 |
#theoutput {margin:1em;}
|
24 |
+
#widget-output {margin:0.5em 0; padding:0 1em; border:1px solid #cccccc; border-radius:0.5em; min-height:2em; min-width:9em;}
|
25 |
+
#widget-output ul, #widget-output ol {margin:0.5em 0 0.5em 1.5em; padding:0;}
|
26 |
+
#widget-output li ul {margin:0 0 0 1em;}
|
27 |
+
#widget-output li ol {margin:0 0 0 1.5em;}
|
28 |
+
#widget-output ul {list-style-type:disc;}
|
29 |
+
#widget-output ul ul {list-style-type:circle;}
|
30 |
+
#widget-output ul ul ul {list-style-type:square;}
|
31 |
+
#widget-output ul ul ul ul {list-style-type:disc;}
|
32 |
+
#widget-output ul ul ul ul ul {list-style-type:circle;}
|
33 |
+
#widget-output ol {list-style-type:decimal;}
|
34 |
+
#widget-output ol ol {list-style-type:upper-alpha;}
|
35 |
+
#widget-output ol ol ol {list-style-type:lower-alpha;}
|
36 |
+
#widget-output ol ol ol ol {list-style-type:lower-roman;}
|
37 |
+
#widget-output ol ol ol ol ol {list-style-type:decimal;}
|
38 |
+
#fallback {display:none; text-align:right; color:#006600;}
|
39 |
#themenu {margin:1em;}
|
40 |
#themenu ul {font-size:12px; list-style-type:none; margin:1em 0; padding:0;}
|
41 |
#themenu ul ul {margin:0 0 0 5em;}
|
46 |
#thefooter div {font-size:12px;}
|
47 |
.alignleft {float:left;}
|
48 |
.alignright {float:right;}
|
49 |
+
.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;}
|
50 |
+
.collapsible span {display:none; position:relative; float:right; color:#999999;}
|
51 |
+
.collapsible:hover span {color:#333333;}
|
52 |
+
.collapsible span:first-child, .collapsible.closed span:last-child {display:inline;}
|
53 |
+
.collapsible.closed span:first-child {display:none;}
|
54 |
+
.current-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)";}
|
55 |
+
.current-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)";}
|
56 |
+
.current-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)";}
|
57 |
.grey {color:#999999;}
|
58 |
.picked > a {background-color:#000066; color:#ffffff; font-weight:bold;}
|
59 |
.tryit {margin-left:1em; text-shadow:1px 1px 1px #ff0000;}
|
66 |
<form>
|
67 |
<div id="formheader">
|
68 |
<strong>Custom Menu Wizard</strong> Interactive Demo
|
69 |
+
<br /><small>v1.2.0 <em>(subset of admin options)</em></small><strong class="tryit"><em>Try it out…</em></strong>
|
70 |
</div>
|
71 |
|
72 |
<p>
|
78 |
<small><em>Title can be set, but need not be displayed</em></small>
|
79 |
</p>
|
80 |
|
81 |
+
<p class='collapsible'>Filter<span>▲</span><span>▼</span></p>
|
82 |
+
|
83 |
<p>
|
84 |
<label>
|
85 |
<input type="radio" checked="checked" value="0" name="filter" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_0">
|
91 |
<option selected="selected" value="0">Current Item</option>
|
92 |
<option value="-2">Current Root Item</option>
|
93 |
<option value="-1">Current Parent Item</option>
|
94 |
+
<optgroup label="the-menu"></optgroup>
|
95 |
</select>
|
96 |
</p>
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
<p>
|
99 |
<label for="widget-custom-menu-wizard-2-start_level">Starting Level:</label>
|
100 |
<select name="start_level" id="widget-custom-menu-wizard-2-start_level">
|
110 |
<br /><small><em>Relative to the first Filtered item found</em></small>
|
111 |
</p>
|
112 |
|
113 |
+
<p class='collapsible end-collapsible'>Fallbacks<span>▲</span><span>▼</span></p>
|
114 |
+
|
115 |
+
<p class="widget-custom-menu-wizard-disableifnot-rp">
|
116 |
+
<small><strong>If "Children of" is <em>Current Root / Parent Item</em>, and no ancestor exists :</strong></small>
|
117 |
+
<br /><label>
|
118 |
+
<input type="checkbox" value="1" name="fallback_no_ancestor" id="widget-custom-menu-wizard-2-fallback_no_ancestor">
|
119 |
+
Switch to Current Item, and</label>
|
120 |
+
<br /><label style="padding-left:1em;">
|
121 |
+
<input type="checkbox" value="1" name="fallback_include_parent" id="widget-custom-menu-wizard-2-fallback_include_parent">
|
122 |
+
Include Parent... </label>
|
123 |
+
<label>
|
124 |
+
<input type="checkbox" value="1" name="fallback_include_parent_siblings" id="widget-custom-menu-wizard-2-fallback_include_parent_siblings">
|
125 |
+
& its Siblings</label>
|
126 |
+
<br /><small><em>If Current Root/Parent and no ancestor exists</em></small>
|
127 |
+
</p>
|
128 |
+
|
129 |
+
<p class="widget-custom-menu-wizard-disableifnot-ci">
|
130 |
+
<small><strong>If "Children of" is <em>Current Item</em>, and current item has no children :</strong></small>
|
131 |
+
<br /><label>
|
132 |
+
<input type="checkbox" value="1" name="fallback_no_children" id="widget-custom-menu-wizard-2-fallback_no_children">
|
133 |
+
Switch to Current Parent Item, and</label>
|
134 |
+
<br /><label style="padding-left:1em;">
|
135 |
+
<input type="checkbox" value="1" name="fallback_nc_include_parent" id="widget-custom-menu-wizard-2-fallback_nc_include_parent">
|
136 |
+
Include Parent... </label>
|
137 |
+
<label>
|
138 |
+
<input type="checkbox" value="1" name="fallback_nc_include_parent_siblings" id="widget-custom-menu-wizard-2-fallback_nc_include_parent_siblings">
|
139 |
+
& its Siblings</label>
|
140 |
+
</p>
|
141 |
+
|
142 |
+
<p class='collapsible end-collapsible'>Output<span>▲</span><span>▼</span></p>
|
143 |
+
|
144 |
<p>
|
145 |
<label>
|
146 |
<input type="radio" checked="checked" value="0" name="flat_output" id="widget-custom-menu-wizard-2-flat_output_0">
|
162 |
Include Ancestors</label>
|
163 |
<br /><label>
|
164 |
<input type="checkbox" value="1" name="title_from_parent" id="widget-custom-menu-wizard-2-title_from_parent">
|
165 |
+
Title from Parent</label>
|
166 |
+
<br /><small><em>Only if the "Children of" Filter returns items</em></small>
|
167 |
+
</p>
|
168 |
+
|
169 |
+
<p>
|
170 |
+
<label>
|
171 |
+
<input type="checkbox" value="1" name="title_from_current" id="widget-custom-menu-wizard-2-title_from_current">
|
172 |
+
Title from "Current" Item</label>
|
173 |
+
<br /><small><em>Lower priority than "Title from Parent"</em></small>
|
174 |
</p>
|
175 |
|
176 |
<p>
|
183 |
Sub-Levels</label>
|
184 |
</p>
|
185 |
|
186 |
+
<p class="grey end-collapsible">
|
187 |
<small><em>Note that since WP v3.6 does it automatically,
|
188 |
<br />"Hide Widget if Empty" is ON for this demo.</em></small>
|
189 |
</p>
|
195 |
<div id='theoutput' class='alignright'>
|
196 |
<strong>Basic Output</strong> …
|
197 |
<div id='widget-output'></div>
|
198 |
+
<div id='fallback'><small>Fallback invoked</small></div>
|
199 |
</div>
|
200 |
|
201 |
<div id='themenu' class='alignleft'>
|
262 |
</li>
|
263 |
</ul>
|
264 |
</li>
|
265 |
+
<li>
|
266 |
+
<a href='#'><span>oscar</span></a>
|
267 |
+
</li>
|
268 |
</ul>
|
269 |
</div>
|
270 |
|
279 |
<script type='text/javascript'>
|
280 |
jQuery(function($){
|
281 |
var maxlevel = 0,
|
282 |
+
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, ol_root:1, ol_sub:1},
|
283 |
integers = {filter_item:1, start_level:1, depth:1},
|
284 |
getSettings = function(){
|
285 |
var settings = {};
|
299 |
var output = $('#widget-output').empty(),
|
300 |
items = $('.picked'),
|
301 |
html = '',
|
302 |
+
title = '',
|
303 |
currLevel = 0,
|
304 |
+
startLevel;
|
305 |
settings = settings || getSettings();
|
306 |
if(items.length){
|
|
|
307 |
if(settings.filter && settings.title_from_parent){
|
308 |
title = $('.picked-parent').children('a').text() || '';
|
309 |
}
|
310 |
+
if(!title && settings.title_from_current){
|
311 |
+
title = $('.current-item').text() || '';
|
312 |
+
}
|
313 |
+
if(!title && !settings.hide_title){
|
314 |
+
title = settings.title || '';
|
315 |
+
}
|
316 |
items.each(function(){
|
317 |
+
var level = settings.flat_output ? 1 : parseInt(this.className.match(/level-(\d+)/)[1], 10),
|
318 |
+
anchor = $(this).children('a');
|
319 |
if(currLevel){
|
320 |
if(level === currLevel){
|
321 |
html += '</li>';
|
329 |
}else{
|
330 |
startLevel = level;
|
331 |
}
|
332 |
+
html += '<li class="cmw-level-' + level + '"><a href="#' + anchor.data('indx') + '">' + anchor.text() + '</a>';
|
333 |
currLevel = level;
|
334 |
});
|
335 |
while(currLevel-- > startLevel){
|
340 |
if(title){
|
341 |
output.prepend('<h3>' + title + '</h3>');
|
342 |
}
|
343 |
+
output.find('li').filter(function(){
|
344 |
+
return !!$(this).children('ul').length;
|
345 |
+
}).addClass('cmw-has-submenu');
|
346 |
}
|
347 |
},
|
348 |
walk = function(e){
|
353 |
picked = items.filter('.picked'),
|
354 |
cls = [],
|
355 |
firstParent = true,
|
356 |
+
fallback = false,
|
357 |
parent, i;
|
358 |
if(!settings.filter){
|
359 |
//show all...
|
382 |
parent = $('.current-item').closest('li');
|
383 |
includeParent = includeParent || settings.fallback_include_parent;
|
384 |
includeParentSiblings = includeParentSiblings || settings.fallback_include_parent_siblings;
|
385 |
+
fallback = !!parent.length;
|
386 |
}
|
387 |
}
|
388 |
//could be multiple - only want first one that matches start_level...
|
400 |
});
|
401 |
//kids...
|
402 |
items = parent.find('li').filter( cls.join(',') );
|
403 |
+
//...if current item is looked for and found, but has no kids, and fallback is set...
|
404 |
+
if(parent.length && !settings.filter_item && !items.length && settings.fallback_no_children){
|
405 |
+
items = parent.siblings('li').add( parent );
|
406 |
+
includeParent = includeParent || settings.fallback_nc_include_parent;
|
407 |
+
includeParentSiblings = includeParentSiblings || settings.fallback_nc_include_parent_siblings;
|
408 |
+
parent = parent.parents('li').eq(0);
|
409 |
+
fallback = !!parent.length;
|
410 |
+
}
|
411 |
if(items.length){
|
412 |
if(includeParentSiblings){
|
413 |
items = items.add( parent.siblings('li') ).add( parent );
|
423 |
parent.addClass('picked-parent');
|
424 |
}
|
425 |
}
|
426 |
+
$('#fallback')[fallback && items.length ? 'show' : 'hide']();
|
427 |
picked.not(items).removeClass('picked');
|
428 |
items.not('.picked').addClass('picked');
|
429 |
show.call(this, e, settings);
|
430 |
},
|
431 |
flds = $('input,select');
|
|
|
432 |
$('#themenu a').on('click', function(){
|
433 |
//click on a #themenu item to [un]make it the current item...
|
434 |
var cls = ['current-item', 'current-parent', 'current-ancestor'],
|
446 |
return false;
|
447 |
}).map(function(i){
|
448 |
//create filter_item's optgroup options...
|
449 |
+
var el = $(this).data('indx', i),
|
450 |
level = el.parentsUntil('#themenu', 'li').length;
|
451 |
maxlevel = Math.max(maxlevel, level);
|
452 |
el.parent().addClass('level-' + level);
|
453 |
return $('<option/>', {value:i + 1}).text( hyphenIndent(el.text(), level) ).get(0);
|
454 |
}).appendTo('optgroup');
|
455 |
+
//allow setting current from widget output (only setting, not un-setting!)...
|
456 |
+
$('#widget-output').on('click', 'a', function(){
|
457 |
+
var indx = this.href.split('#')[1];
|
458 |
+
$('#themenu a').eq(indx).not(':has(.current-item)').trigger('click');
|
459 |
+
return false;
|
460 |
+
});
|
461 |
//populate starting-level and depth options...
|
462 |
for(i = 1; i < maxlevel + 1; i++){
|
463 |
var levels = i < 2 ? ' level' : ' levels',
|
468 |
}
|
469 |
$('<option/>', att).text(i).appendTo('#widget-custom-menu-wizard-2-start_level');
|
470 |
}
|
471 |
+
//interactivity (need to ensure that any delegated handlers from the included script get run first)...
|
472 |
+
flds.not( flds.filter('[type="text"]').on('blur', show) ).addClass('demo-change');
|
473 |
+
$(document).on('change', '.demo-change', walk);
|
474 |
+
//reset...
|
475 |
$('button').on('click', function(){
|
476 |
$(this).parent().get(0).reset();
|
477 |
$('#widget-custom-menu-wizard-2-filter_item').trigger('change');
|
478 |
return false;
|
479 |
+
}).trigger('click');
|
480 |
+
//collapsibles...
|
481 |
+
$('.collapsible').on('click', function(){
|
482 |
+
var Self = $(this)
|
483 |
+
data = Self.data();
|
484 |
+
Self.toggleClass('closed', !data.closed).nextUntil('.end-collapsible')[data.closed ? 'slideDown' : 'slideUp']();
|
485 |
+
data.closed = !data.closed;
|
486 |
+
this.blur();
|
487 |
+
return false;
|
488 |
+
}).slice(1).trigger('click');
|
489 |
});
|
490 |
</script>
|
491 |
</body>
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ 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: 1.
|
7 |
License: GPLv2 or Later
|
8 |
|
9 |
Custom Menu Wizard Widget : Show branches or levels of your menu in a widget, with full customisation.
|
@@ -11,7 +11,7 @@ Custom Menu Wizard Widget : Show branches or levels of your menu in a widget, wi
|
|
11 |
== Description ==
|
12 |
|
13 |
This plugin is a boosted version of the WordPress "Custom Menu" widget.
|
14 |
-
It provides full control over most of the parameters available when calling WP's [wp_nav_menu()](http://codex.wordpress.org/Function_Reference/wp_nav_menu) function, as well as providing pre-filtering of the menu items in order to be able to select a specific portion of the custom menu. It also automatically adds a couple of custom classes.
|
15 |
|
16 |
Features include:
|
17 |
|
@@ -26,7 +26,8 @@ Features include:
|
|
26 |
* Add/specify custom class(es) for the widget block, the menu container, and the menu itself
|
27 |
* Modify the link's output with additional HTML around the link's text and/or the link element itself
|
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 |
|
31 |
**Widget Options**
|
32 |
|
@@ -61,36 +62,17 @@ logical sections and made each section collapsible (with remembered state, open
|
|
61 |
The dropdown list will present a "Current Item" option (default), a "Current Root Item" (v1.1.0)
|
62 |
and "Current Parent Item" (v1.1.0) option, followed by all the available items from the menu chosen in `Select Menu`.
|
63 |
The widget will output the *children* of the selected item, always assuming that they lie within the bounds of any other parameters set.
|
64 |
-
|
65 |
-
"Current Item" is the menu item that WordPress recognises as being currently on display;
|
66 |
-
"Current Parent Item" (v1.1.0) is the *immediate* ancestor (within `Select Menu`) of that same menu item;
|
67 |
-
and "Current Root Item" (v1.1.0) is the *ultimate* ancestor (within `Select Menu`) of that same menu item.
|
68 |
-
Obviously, if the menu item currently on display (as determined by WordPress) does not
|
69 |
-
appear in the `Select Menu` then there is going to be no output for any of these options.
|
70 |
-
|
71 |
-
If you change `Select Menu`, the options presented in this dropdown will change accordingly and the selected option will revert to the default.
|
72 |
|
73 |
-
|
74 |
|
75 |
-
|
76 |
-
it provides a fallback of effectively switching the filter to "Current Item" **if, and only if**, the current menu item
|
77 |
-
(as determined by WordPress) is at Level 1
|
78 |
-
(top level) of the selected menu. For example, say you were to set `Children of` to "Current Parent Item", with `Starting Level`
|
79 |
-
at "1" and `For Depth` at "unlimited" : if the current menu item was found at level 1 (root level of the menu) then ordinarily
|
80 |
-
there would be no output because the current item has no parent! If you were to enable `Fallback to Current Item` then you
|
81 |
-
*would* have some output - the entire branch below the current item.
|
82 |
-
|
83 |
-
* **Include Parent...** *(checkbox)* as of v1.1.0
|
84 |
-
|
85 |
-
This option extends the `Fallback to Current Item` option (above). If the enabled fallback is actually used, this option can
|
86 |
-
temporarily override the equivalent **Output** option to ON. Note that if the **Output** options are already set to include
|
87 |
-
the parent item (with or without siblings), this option has absolutely no effect.
|
88 |
|
89 |
-
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
|
|
94 |
|
95 |
* **Starting Level** *(select, default: "1")*
|
96 |
|
@@ -108,6 +90,57 @@ logical sections and made each section collapsible (with remembered state, open
|
|
108 |
`Children of` to "Current Item", `Starting Level` to "2", and `For Depth` to "2 levels" : if the current item was found at level 3,
|
109 |
then you would get the current item's immediate children (from level 4), plus *their* immediate children (from level 5).
|
110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
* **Output**
|
112 |
|
113 |
* **Hierarchical** *(radio, default)*
|
@@ -132,11 +165,19 @@ logical sections and made each section collapsible (with remembered state, open
|
|
132 |
Same as `Include Parent` except that all ancestors, right back to root level, are included. Only applies to a successful
|
133 |
`Children of` filter.
|
134 |
|
135 |
-
* **Title from Parent
|
136 |
|
137 |
Again, this only applies to a successful `Children of` filter. If checked, use the title of the parent item as the widget's
|
138 |
title when displaying the output. This will override (ie. ignore) the `Hide` checkbox setting!
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
* **Change UL to OL**
|
141 |
|
142 |
The standard for menus is to use UL (unordered list) elements to display the output. These settings give you the option to swap
|
@@ -177,7 +218,7 @@ logical sections and made each section collapsible (with remembered state, open
|
|
177 |
|
178 |
* **Classes**
|
179 |
|
180 |
-
* **Menu Class** *(default: "menu-widget")
|
181 |
|
182 |
This is the class that will be applied to the list element that holds the entire menu.
|
183 |
|
@@ -203,6 +244,127 @@ logical sections and made each section collapsible (with remembered state, open
|
|
203 |
|
204 |
Text or HTML that will be placed immediately after each menu item's link text.
|
205 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
== Installation ==
|
207 |
|
208 |
1. EITHER Upload the zip package via 'Plugins > Add New > Upload' in your WP Admin
|
@@ -230,6 +392,18 @@ If you have a question or problem, please use the integrated Support forum.
|
|
230 |
|
231 |
== Changelog ==
|
232 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
= 1.1.0 =
|
234 |
|
235 |
* added 'Current Root Item' and 'Current Parent Item' to the `Children of` filter
|
@@ -256,6 +430,12 @@ Initial release
|
|
256 |
|
257 |
== Upgrade Notice ==
|
258 |
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
= 1.1.0 =
|
260 |
|
261 |
`Children of` has 2 extra options, for filtering using the Current Item's parent (immediate ancestor) or root (ultimate ancestor) item,
|
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: 1.2.0
|
7 |
License: GPLv2 or Later
|
8 |
|
9 |
Custom Menu Wizard Widget : Show branches or levels of your menu in a widget, with full customisation.
|
11 |
== Description ==
|
12 |
|
13 |
This plugin is a boosted version of the WordPress "Custom Menu" widget.
|
14 |
+
It provides full control over most of the parameters available when calling WP's [wp_nav_menu()](http://codex.wordpress.org/Function_Reference/wp_nav_menu) function, as well as providing pre-filtering of the menu items in order to be able to select a specific portion of the custom menu. It also automatically adds a couple of custom classes. And there is now (v1.2.0) a shortcode that enables you to include the widget's output in your content.
|
15 |
|
16 |
Features include:
|
17 |
|
26 |
* Add/specify custom class(es) for the widget block, the menu container, and the menu itself
|
27 |
* Modify the link's output with additional HTML around the link's text and/or the link element itself
|
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 |
**Widget Options**
|
33 |
|
62 |
The dropdown list will present a "Current Item" option (default), a "Current Root Item" (v1.1.0)
|
63 |
and "Current Parent Item" (v1.1.0) option, followed by all the available items from the menu chosen in `Select Menu`.
|
64 |
The widget will output the *children* of the selected item, always assuming that they lie within the bounds of any other parameters set.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
+
* "Current Item" is the menu item that WordPress recognises as being currently on display (current menu item)
|
67 |
|
68 |
+
* "Current Parent Item" (v1.1.0) is the *immediate* ancestor (within `Select Menu`) of the current menu item
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
+
* "Current Root Item" (v1.1.0) is the *ultimate* ancestor (within `Select Menu`) of the current menu item.
|
71 |
|
72 |
+
Obviously, if the current menu item (as determined by WordPress) does not
|
73 |
+
appear in the `Select Menu` then there is going to be no output for any of these options.
|
74 |
+
|
75 |
+
If you change `Select Menu`, the options presented in this dropdown will change accordingly and the selected option will revert to the default.
|
76 |
|
77 |
* **Starting Level** *(select, default: "1")*
|
78 |
|
90 |
`Children of` to "Current Item", `Starting Level` to "2", and `For Depth` to "2 levels" : if the current item was found at level 3,
|
91 |
then you would get the current item's immediate children (from level 4), plus *their* immediate children (from level 5).
|
92 |
|
93 |
+
* **Fallbacks**
|
94 |
+
|
95 |
+
Fallback for `Children of` being set to either *Current Root Item* or *Current Parent Item*, and current item not having an ancestor:
|
96 |
+
|
97 |
+
* **Switch to Current Item** *(checkbox)* as of v1.1.0
|
98 |
+
|
99 |
+
If enabled,
|
100 |
+
it provides a fallback of effectively switching the filter to "Current Item" if the current menu item
|
101 |
+
(as determined by WordPress) is at Level 1
|
102 |
+
(top level) of the selected menu. For example, say you were to set `Children of` to "Current Parent Item", with `Starting Level`
|
103 |
+
at "1" and `For Depth` at "unlimited" : if the current menu item was found at level 1 (root level of the menu) then ordinarily
|
104 |
+
there would be no output because the current item has no parent! If you were to enable the `Switch to Current Item` fallback then you
|
105 |
+
*would* have some output - the entire branch below the current item.
|
106 |
+
|
107 |
+
* **Include Parent...** *(checkbox)* as of v1.1.0
|
108 |
+
|
109 |
+
This option extends the `Switch to Current Item` option (above). If the enabled fallback is actually used, this option can
|
110 |
+
temporarily override the equivalent **Output** option to ON. Note that if the **Output** options are already set to include
|
111 |
+
the parent item (with or without siblings), this option has absolutely no effect.
|
112 |
+
|
113 |
+
* **& its Siblings** *(checkbox)* as of v1.1.0
|
114 |
+
|
115 |
+
This option extends the `Switch to Current Item` option (above). If the enabled fallback is actually used, this option can
|
116 |
+
temporarily override the equivalent **Output** option to ON. Note that if the equivalent **Output** option is already enabled,
|
117 |
+
this option has absolutely no effect.
|
118 |
+
|
119 |
+
Fallback for `Children of` being set to *Current Item*, and current item not having any children:
|
120 |
+
|
121 |
+
* **Switch to Current Parent Item** *(checkbox)* as of v1.2.0
|
122 |
+
|
123 |
+
If enabled, it provides a fallback of effectively switching the filter to "Current Parent Item" if looking for children
|
124 |
+
of Current Item and there aren't any. For example, say you were to set `Children of` to "Current Item", with `Starting Level`
|
125 |
+
at "1" and `For Depth` at "unlimited" : if the current menu item has no children then ordinarily
|
126 |
+
there would be no output! If you were to enable the `Switch to Current Item` fallback then you
|
127 |
+
*would* have some output - the current item and its siblings.
|
128 |
+
|
129 |
+
Please note that there is one difference between this fallback and the normal "Current Parent Item" filter : if the current item
|
130 |
+
has no ancestor (as well as no children) then you will always get the current item and its siblings, regardless of any other settings!
|
131 |
+
|
132 |
+
* **Include Parent...** *(checkbox)* as of v1.2.0
|
133 |
+
|
134 |
+
This option extends the `Switch to Current Parent Item` option (above). If the enabled fallback is actually used, this option can
|
135 |
+
temporarily override the equivalent **Output** option to ON. Note that if the **Output** options are already set to include
|
136 |
+
the parent item (with or without siblings), this option has absolutely no effect.
|
137 |
+
|
138 |
+
* **& its Siblings** *(checkbox)* as of v1.2.0
|
139 |
+
|
140 |
+
This option extends the `Switch to Current Parent Item` option (above). If the enabled fallback is actually used, this option can
|
141 |
+
temporarily override the equivalent **Output** option to ON. Note that if the equivalent **Output** option is already enabled,
|
142 |
+
this option has absolutely no effect.
|
143 |
+
|
144 |
* **Output**
|
145 |
|
146 |
* **Hierarchical** *(radio, default)*
|
165 |
Same as `Include Parent` except that all ancestors, right back to root level, are included. Only applies to a successful
|
166 |
`Children of` filter.
|
167 |
|
168 |
+
* **Title from Parent** *(checkbox)*
|
169 |
|
170 |
Again, this only applies to a successful `Children of` filter. If checked, use the title of the parent item as the widget's
|
171 |
title when displaying the output. This will override (ie. ignore) the `Hide` checkbox setting!
|
172 |
|
173 |
+
* **Title from "Current" Item** *(checkbox)*
|
174 |
+
|
175 |
+
If checked, use the title of the current menu item (as determined by WordPress) as the widget's
|
176 |
+
title when displaying the output. This will override (ie. ignore) the `Hide` checkbox setting!
|
177 |
+
|
178 |
+
Note that the current menu item is not required to be within the resultant output, merely within the `Select Menu`.
|
179 |
+
Also, `Title from Parent` (if applicable, and if available) takes priority over this option.
|
180 |
+
|
181 |
* **Change UL to OL**
|
182 |
|
183 |
The standard for menus is to use UL (unordered list) elements to display the output. These settings give you the option to swap
|
218 |
|
219 |
* **Classes**
|
220 |
|
221 |
+
* **Menu Class** *(default: "menu-widget")*
|
222 |
|
223 |
This is the class that will be applied to the list element that holds the entire menu.
|
224 |
|
244 |
|
245 |
Text or HTML that will be placed immediately after each menu item's link text.
|
246 |
|
247 |
+
**Shortcode**
|
248 |
+
|
249 |
+
The shortcode is **`[custom_menu_wizard]`**. Most of the attributes reflect the options available to the widget, but some have been simplified for
|
250 |
+
easier use in the shortcode format.
|
251 |
+
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
|
252 |
+
found then there will be no output from the shortcode.
|
253 |
+
|
254 |
+
* **title** *(string)*
|
255 |
+
|
256 |
+
The output's `Title`, which may be overridden by `title_from`. Note that there is no shortcode equivalent of the widget's `Hide` option for the title.
|
257 |
+
|
258 |
+
* **menu** *(string | integer)*
|
259 |
+
|
260 |
+
Accepts a menu name (most likely usage) or id. If not provided, the shortcode will attempt to find the first menu (ordered by name)
|
261 |
+
that has menu items attached to it, and use that.
|
262 |
+
|
263 |
+
* **children_of** *(string | integer)*
|
264 |
+
|
265 |
+
If empty, or not provided, this is the same as enabling `Show All` (see above) for the widget. Anything else is a `Children of` filter :
|
266 |
+
|
267 |
+
* 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`).
|
268 |
+
(Hint : In Menus Admin, hover over the item's **Remove** link and note the number after *menu-item=* in the URL)
|
269 |
+
|
270 |
+
* Certain specific strings have the following meanings:
|
271 |
+
|
272 |
+
* *'current'* or *'current-item'* : a `Children of` "Current Item" filter
|
273 |
+
|
274 |
+
* *'parent'* or *'current-parent'* : a `Children of` "Current Parent Item" filter
|
275 |
+
|
276 |
+
* *'root'* or *'current-ancestor'* : a `Children of` "Current Root Item" filter
|
277 |
+
|
278 |
+
* 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
|
279 |
+
(within `menu`). Please note that the code looks for a *caseless* title match, so specifying `children_of="my menu item"` will
|
280 |
+
match against a menu item with the title "My Menu Item".
|
281 |
+
|
282 |
+
* **fallback_parent** *(string | integer)*
|
283 |
+
|
284 |
+
This is the fallback option for when `Children of` is set to either *Current Root Item* or *Current Parent Item*, and
|
285 |
+
the current item has no ancestors (see `Switch to Current Item` under **Fallbacks** above).
|
286 |
+
|
287 |
+
* Any "truthy" value (eg. 1, *'true'*, *'on'*, *'parent'*, *'siblings'*) : Enables widget's `Switch to Current Item` **Fallbacks** option
|
288 |
+
|
289 |
+
* *'parent'* : Enables widget's `Include Parent...` **Fallbacks** extension option (in addition to the above)
|
290 |
+
|
291 |
+
* *'siblings'* : Enables widget's `& its Siblings` **Fallbacks** extension option (in addition to the above)
|
292 |
+
|
293 |
+
* **fallback_current** *(string | integer)*
|
294 |
+
|
295 |
+
This is the fallback option for when `Children of` is set to *Current Item*, and
|
296 |
+
the current item has no children (see `Switch to Current Parent Item` under **Fallbacks** above).
|
297 |
+
|
298 |
+
* Any "truthy" value (eg. 1, *'true'*, *'on'*, *'parent'*, *'siblings'*) : Enables widget's `Switch to Current Parent Item` **Fallbacks** option
|
299 |
+
|
300 |
+
* *'parent'* : Enables widget's `Include Parent...` **Fallbacks** extension option (in addition to the above)
|
301 |
+
|
302 |
+
* *'siblings'* : Enables widget's `& its Siblings` **Fallbacks** extension option (in addition to the above)
|
303 |
+
|
304 |
+
* **start_level** *(integer, default 1)* See widget's `Starting Level` option, under **Filter** above.
|
305 |
+
|
306 |
+
* **depth** *(integer, default 0)* See widget's `For Depth` option, under **Filter** above.
|
307 |
+
|
308 |
+
* **flat_output** *(switch, off by default, 1 to enable)* See widget's `Flat` option, under **Output** above.
|
309 |
+
|
310 |
+
* **include** *(string)*
|
311 |
+
|
312 |
+
* *'parent'* : Enables widget's `Include Parent...` **Output** option
|
313 |
+
|
314 |
+
* *'siblings'* : Enables widget's `& its Siblings` **Output** option
|
315 |
+
|
316 |
+
* *'ancestors'* : Enables widget's `Include Ancestors` **Output** option
|
317 |
+
|
318 |
+
Supply more than one by separating them with a comma, space or hyphen, eg. `include="siblings ancestors"`.
|
319 |
+
|
320 |
+
* **title_from** *(string)*
|
321 |
+
|
322 |
+
* *'parent'* : Enables widget's `Title from Parent` **Output** option
|
323 |
+
|
324 |
+
* *'current'* : Enables widget's `Title from "Current" Item` **Output** option
|
325 |
+
|
326 |
+
Supply more than one by separating them with a comma, space or hyphen, eg. `title_from="parent,current"`.
|
327 |
+
|
328 |
+
* **ol_root** *(switch, off by default, 1 to enable)* See widget's `Top Level` option, under **Output** above.
|
329 |
+
|
330 |
+
* **ol_sub** *(switch, off by default, 1 to enable)* See widget's `Sub-Levels` option, under **Output** above.
|
331 |
+
|
332 |
+
* **container** *(string)* See widget's `Element` option, under **Container** above.
|
333 |
+
|
334 |
+
* **container_id** *(string)* See widget's `Unique ID` option, under **Container** above.
|
335 |
+
|
336 |
+
* **container_class** *(string)* See widget's `Class` option, under **Container** above.
|
337 |
+
|
338 |
+
* **menu_class** *(string)* See widget's `Menu Class` option, under **Classes** above.
|
339 |
+
|
340 |
+
* **widget_class** *(string)* See widget's `Widget Class` option, under **Classes** above.
|
341 |
+
|
342 |
+
* **wrap_link** *(string)*
|
343 |
+
|
344 |
+
This is an optional tag name (eg. *'div'*, *'p'*, *'span*') that, if provided, will be made into HTML start/end tags
|
345 |
+
and sent through to the widget as its `Before the Link` and `After the Link` options. Please note that the shortcode usage - a simple
|
346 |
+
tag name - is much more restrictive than the widget's options, which allow HTML.
|
347 |
+
|
348 |
+
* **wrap_link_text** *(string)*
|
349 |
+
|
350 |
+
This is an optional tag name (eg. *'span*', *'em'*, '*strong*') that, if provided, will be made into HTML start/end tags
|
351 |
+
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
|
352 |
+
simple tag name - is much more restrictive than the widget's options, which allow HTML.
|
353 |
+
|
354 |
+
**Shortcode Examples**
|
355 |
+
|
356 |
+
* Show the entire "main" menu :
|
357 |
+
|
358 |
+
`[custom_menu_wizard menu=main]`
|
359 |
+
|
360 |
+
* Show the children of the Current Item within the "main" menu, for unlimited depth, and include the Current Item's parent :
|
361 |
+
|
362 |
+
`[custom_menu_wizard menu=main children_of=current include_parent=1]`
|
363 |
+
|
364 |
+
* From the "animals" menu, show all the items *immediately* below (depth=1) "Small Dogs", plus "Small Dogs" and its sibling items, as ordered lists :
|
365 |
+
|
366 |
+
`[custom_menu_wizard menu="animals" children_of="small dogs" depth=1 include_parent_siblings=1 ol_root=1 ol_sub=1]`
|
367 |
+
|
368 |
== Installation ==
|
369 |
|
370 |
1. EITHER Upload the zip package via 'Plugins > Add New > Upload' in your WP Admin
|
392 |
|
393 |
== Changelog ==
|
394 |
|
395 |
+
= 1.2.0 =
|
396 |
+
|
397 |
+
* added custom_menu_wizard shortcode, to run the widget from within content
|
398 |
+
|
399 |
+
* moved the 'no ancestor' fallback into new Fallback collapsible section, and added a fallback for Current Item with no children
|
400 |
+
|
401 |
+
* 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)
|
402 |
+
|
403 |
+
* don't include menus with no items
|
404 |
+
|
405 |
+
* updated demo.html
|
406 |
+
|
407 |
= 1.1.0 =
|
408 |
|
409 |
* added 'Current Root Item' and 'Current Parent Item' to the `Children of` filter
|
430 |
|
431 |
== Upgrade Notice ==
|
432 |
|
433 |
+
= 1.2.0 =
|
434 |
+
|
435 |
+
Added custom_menu_wizard shortcode, to run the widget from within content. Also added a new fallback for Current Item having no children, and
|
436 |
+
moved all fallbacks into a collapsible Fallbacks section. Fixed a bug with optgroups/options made available for the 'Children of' selector
|
437 |
+
after the widget has been saved (also affected disabled fields and styling).
|
438 |
+
|
439 |
= 1.1.0 =
|
440 |
|
441 |
`Children of` has 2 extra options, for filtering using the Current Item's parent (immediate ancestor) or root (ultimate ancestor) item,
|