Version Description
added 'Current Root Item' and 'Current Parent Item' to the
Children of
filteradded
Fallback to Current Item
option, with subsibiary options for overriding a couple of Output options, as a means to enable Current Root & Current Parent to match a Current Item at root leveladded an Output option to include both the parent item and the parent's siblings (for a successful
Children of
filter)added max-width style (100%) to the
Children of
SELECT in the widget optionsadded widget version to the admin js enqueuer
ignore/disable Hide Empty option for WP >
Download this release
Release Info
Developer | wizzud |
Plugin | Custom Menu Wizard Widget |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.0 to 1.1.0
- custom-menu-wizard.js +45 -21
- custom-menu-wizard.php +304 -94
- demo.html +418 -0
- readme.txt +86 -14
custom-menu-wizard.js
CHANGED
@@ -1,28 +1,52 @@
|
|
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 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
chkbox
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
});
|
1 |
/* Plugin Name: Custom Menu Wizard
|
2 |
+
* Version: 1.1.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 |
+
filterItems = $('select' + dotPrefix + '-listen');
|
10 |
+
$(document)
|
11 |
+
//fieldsets...
|
12 |
+
.on('click', dotPrefix + '-collapsible-fieldset', function(){
|
13 |
+
var chkbox = $('input', this).eq(0),
|
14 |
+
collapse = !chkbox.prop('checked');
|
15 |
+
if(chkbox.length){
|
16 |
+
chkbox.prop('checked', collapse);
|
17 |
+
$('div', this).css({backgroundPosition:collapse?'0 0':'0 -36px'});
|
18 |
+
$(this).next('div')[collapse?'slideUp':'slideDown']();
|
19 |
+
}
|
20 |
+
this.blur();
|
21 |
+
return false;
|
22 |
+
})
|
23 |
+
//change of menu...
|
24 |
+
.on('change', dotPrefix + '-selectmenu', function(){
|
25 |
+
var select = $('select' + dotPrefix + '-listen', this.form),
|
26 |
+
from = $('#' + select.attr('id') + '_ignore').find('optgroup'),
|
27 |
+
groupClone;
|
28 |
+
if(from.length > this.selectedIndex){
|
29 |
+
if(select.val() > 0){
|
30 |
+
select.val(0);
|
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 |
+
//enableif and disableif...
|
39 |
+
.on('change', dotPrefix + '-listen', function(){
|
40 |
+
var listeners = $(dotPrefix + '-listen', this.form),
|
41 |
+
showAll = listeners.eq(0).prop('checked'),
|
42 |
+
rootParent = !showAll && listeners.filter('select').val() < 0;
|
43 |
+
$(dotPrefix + '-disableif', this.form).css({color:showAll ? '#999999' : 'inherit'}).find('input,select').prop('disabled', showAll);
|
44 |
+
$(dotPrefix + '-enableif', this.form).css({color:!rootParent ? '#999999' : 'inherit'}).find('input,select').prop('disabled', !rootParent);
|
45 |
+
});
|
46 |
+
//remove non-active optgroups...
|
47 |
+
filterItems.find('optgroup').filter(function(){
|
48 |
+
return !$(this).data('cmwActiveMenu');
|
49 |
+
}).remove();
|
50 |
+
//trigger change...
|
51 |
+
filterItems.trigger('change');
|
52 |
});
|
custom-menu-wizard.php
CHANGED
@@ -3,12 +3,26 @@
|
|
3 |
* Plugin Name: Custom Menu Wizard
|
4 |
* Plugin URI: http://www.wizzud.com/
|
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 |
* registers the widget
|
14 |
*/
|
@@ -21,14 +35,16 @@ add_action('widgets_init', 'custom_menu_wizard_register_widget');
|
|
21 |
* enqueues script file for the widget admin
|
22 |
*/
|
23 |
function custom_menu_wizard_widget_admin_script(){
|
24 |
-
wp_enqueue_script('custom-menu-wizard-plugin-script', plugins_url('/custom-menu-wizard.js', __FILE__), array('jquery'));
|
25 |
}
|
26 |
add_action('admin_print_scripts-widgets.php', 'custom_menu_wizard_widget_admin_script');
|
27 |
|
28 |
/*
|
29 |
* Custom Menu Wizard Walker class
|
|
|
|
|
30 |
*/
|
31 |
-
class Custom_Menu_Wizard_Walker extends
|
32 |
|
33 |
/**
|
34 |
* opens a sub-level with a UL or OL start-tag
|
@@ -70,51 +86,65 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
70 |
|
71 |
$cmw =& $args->_custom_menu_wizard;
|
72 |
//in $cmw (array) :
|
73 |
-
// filter :
|
74 |
-
// filter_item : current
|
75 |
// flat_output : true = equivalent of $max_depth == -1
|
76 |
// include_parent : true = include the filter_item menu item
|
|
|
77 |
// include_ancestors : true = include the filter_item menu item plus all it's ancestors
|
78 |
// title_from_parent : true = widget wants parent's title as title
|
79 |
// start_level : integer, 1+
|
80 |
// depth : integer, replacement for max_depth and also applied to 'flat' output
|
|
|
|
|
|
|
81 |
//$elements is an array of objects, indexed by position within the menu (menu_order),
|
82 |
//starting at 1 and incrementing sequentially regardless of parentage (ie. first item is [1],
|
83 |
//second item is [2] whether it's at root or subordinate to first item)
|
84 |
|
85 |
-
$
|
86 |
-
$find_kids_of = $cmw['filter'] == 1;
|
87 |
$find_current_item = $find_kids_of && empty( $cmw['filter_item'] );
|
88 |
-
$
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
//are we looking for something in particular?...
|
91 |
if( $find_kids_of || $cmw['start_level'] > 1 ){
|
92 |
-
$id_field = $this->db_fields['id'];
|
93 |
-
$parent_field = $this->db_fields['parent'];
|
94 |
|
95 |
//start level applies to the *kids* of a find_kids_of search, not to the parent, so while we
|
96 |
//are still looking for the parent, the start_level for a find_kids_of search is actually one
|
97 |
-
//up from
|
98 |
$start_level = $find_kids_of ? $cmw['start_level'] - 1 : $cmw['start_level'];
|
99 |
|
100 |
$keep_ids = array();
|
101 |
$keep_items = array();
|
102 |
-
$temp = array();
|
103 |
foreach( $elements as $i=>$item ){
|
104 |
if( empty( $item->$parent_field ) ){
|
105 |
//set root level of menu, and no ancestors...
|
106 |
$temp[ $item->$id_field ] = array(
|
107 |
'level' => 1,
|
108 |
//this is an array of indexes into $elements...
|
109 |
-
'breadcrumb' => array( $i )
|
|
|
|
|
110 |
);
|
|
|
111 |
}elseif( isset( $temp[ $item->$parent_field ] ) ){
|
112 |
//set one greater than parent's level, and ancestors are parent's ancestors plus the parent...
|
113 |
$temp[ $item->$id_field ] = array(
|
114 |
'level' => $temp[ $item->$parent_field ]['level'] + 1,
|
115 |
-
'breadcrumb' => $temp[ $item->$parent_field ]['breadcrumb']
|
|
|
|
|
116 |
);
|
117 |
$temp[ $item->$id_field ]['breadcrumb'][] = $i;
|
|
|
118 |
}
|
119 |
//if $temp[] hasn't been set then it's an orphan; in order to keep orphans, max_depth must be 0 (ie. unlimited)
|
120 |
//note that if a child is an orphan then all descendants of that child are also considered to be orphans!
|
@@ -126,19 +156,28 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
126 |
//are we still looking for a starting point?...
|
127 |
if( empty( $keep_ids ) ){
|
128 |
if( //...we're looking for unspecific items starting at this level...
|
129 |
-
|
130 |
//...we're looking for current item, and this is it...
|
131 |
( $find_current_item && $item->current ) ||
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
//...we're looking for a particular menu item, and this is it...
|
133 |
-
( $
|
134 |
-
//...we're looking for current path, and this is on it...
|
135 |
-
( $find_current_path && ( $item->current || $item->current_item_parent || $item->current_item_ancestor ) )
|
136 |
){
|
137 |
//NOTE : at this point I'm *keeping* the id of the parent of a find_kids_of search, but not the actual item!
|
138 |
$keep_ids[] = $item->$id_field;
|
139 |
if( !$find_kids_of ){
|
140 |
$keep_items[] = $item;
|
141 |
}
|
|
|
|
|
|
|
|
|
|
|
142 |
//depth, if set, kicks in at this point :
|
143 |
// if doing a find_kids_of search then this level counts as 0, and the next level (the kids) counts as 1
|
144 |
// otherwise, the current level counts as 1
|
@@ -154,7 +193,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
154 |
//having found at least one, any more have to be:
|
155 |
// - within max_depth of the first one found, and
|
156 |
// - either it's an unspecific search, or we have the parent already
|
157 |
-
}elseif( $temp[ $item->$id_field ]['level'] <= $max_level && (
|
158 |
$keep_ids[] = $item->$id_field;
|
159 |
$keep_items[] = $item;
|
160 |
}
|
@@ -166,28 +205,65 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
166 |
if( !empty( $keep_items) ){
|
167 |
|
168 |
//do we need to prepend parent or ancestors?...
|
169 |
-
$
|
170 |
-
//remove the last element, which is the item's own index...
|
171 |
-
array_pop( $
|
172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
if( $find_kids_of && $i > 0 ){
|
174 |
if( $cmw['include_ancestors'] ){
|
175 |
$j = 0;
|
176 |
-
}elseif( $
|
177 |
--$j;
|
178 |
}
|
179 |
while( $i > $j ){
|
180 |
-
array_unshift( $keep_items, $elements[ $
|
181 |
}
|
182 |
}
|
183 |
-
|
184 |
-
if( $find_kids_of && $cmw['title_from_parent'] && count( $temp ) > 0){
|
185 |
-
$cmw['parent_title'] = apply_filters(
|
186 |
-
'the_title',
|
187 |
-
$elements[ $temp[ count( $temp ) - 1 ] ]->title,
|
188 |
-
$elements[ $temp[ count( $temp ) - 1 ] ]->ID
|
189 |
-
);
|
190 |
-
}
|
191 |
}
|
192 |
|
193 |
//for each item we're keeping, use the temp array to hold:
|
@@ -244,10 +320,15 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
244 |
|
245 |
var $_cmw_switches = array(
|
246 |
'hide_title',
|
|
|
|
|
|
|
|
|
247 |
'flat_output',
|
248 |
'include_parent',
|
|
|
249 |
'include_ancestors',
|
250 |
-
'hide_empty',
|
251 |
'title_from_parent',
|
252 |
'ol_root',
|
253 |
'ol_sub',
|
@@ -274,8 +355,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
274 |
);
|
275 |
var $_cmw_integers = array(
|
276 |
'depth' => 0,
|
277 |
-
'
|
278 |
-
'filter_item' => 0,
|
279 |
'menu' => 0,
|
280 |
'start_level' => 1
|
281 |
);
|
@@ -313,10 +393,14 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
313 |
}
|
314 |
|
315 |
/**
|
316 |
-
* this merely removes itself from the filters and returns an empty string
|
317 |
-
* it gets added by the
|
318 |
* ever gets run when hide_empty is set on the widget instance
|
319 |
*
|
|
|
|
|
|
|
|
|
320 |
* @param string $nav_menu HTML for the menu
|
321 |
* @param object $args
|
322 |
* @return string HTML for the menu
|
@@ -327,11 +411,15 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
327 |
}
|
328 |
|
329 |
/**
|
330 |
-
* this gets run if hide_empty is set
|
331 |
* if $items is empty then add a wp_nav_menu filter to do the actual return of an empty string
|
332 |
* it gets run before the wp_nav_menu filter, but it gets the $items array whereas the wp_nav_menu filter does not
|
333 |
* it gets added by $this->widget() before wp_nav_menu() is called, and removed immediately after wp_nav_menu() returns
|
334 |
*
|
|
|
|
|
|
|
|
|
335 |
* @param array $items Menu items
|
336 |
* @param object $args
|
337 |
* @return array Menu items
|
@@ -369,6 +457,9 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
369 |
$instance[ $k ] = empty( $instance[ $k ] ) ? $v : trim( $instance[ $k ] );
|
370 |
}
|
371 |
|
|
|
|
|
|
|
372 |
$this->cmw_title_from_parent = '';
|
373 |
|
374 |
//fetch menu...
|
@@ -418,7 +509,11 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
418 |
'_custom_menu_wizard' => array(
|
419 |
'filter' => $instance['filter'],
|
420 |
'filter_item' => $instance['filter_item'],
|
|
|
|
|
|
|
421 |
'include_parent' => $instance['include_parent'],
|
|
|
422 |
'include_ancestors' => $instance['include_ancestors'],
|
423 |
'title_from_parent' => $instance['title_from_parent'],
|
424 |
'ol_root' => $instance['ol_root'],
|
@@ -434,6 +529,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
434 |
if( !empty( $instance['container_class'] ) ){
|
435 |
$params['container_class'] = $instance['container_class'];
|
436 |
}
|
|
|
437 |
$out = wp_nav_menu( $params );
|
438 |
|
439 |
if( $instance['hide_empty'] ){
|
@@ -497,7 +593,7 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
497 |
}
|
498 |
//integers...
|
499 |
foreach( $this->_cmw_integers as $k=>$v ){
|
500 |
-
$instance[ $k ] = isset( $instance[ $k ]) ? max( $v, intval( $instance[ $k ] ) ) : $v;
|
501 |
}
|
502 |
//strings...
|
503 |
foreach( $this->_cmw_strings as $k=>$v ){
|
@@ -516,66 +612,113 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
516 |
echo '<p>'. sprintf( __('No menus have been created yet. <a href="%s">Create one</a>.'), admin_url('nav-menus.php') ) .'</p>';
|
517 |
return;
|
518 |
}
|
|
|
|
|
|
|
|
|
519 |
?>
|
520 |
<p>
|
521 |
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
|
522 |
<label for="<?php echo $this->get_field_id('hide_title'); ?>" class="alignright">
|
523 |
-
<input id="<?php echo $this->get_field_id('hide_title'); ?>" name="<?php echo $this->get_field_name('hide_title'); ?>"
|
|
|
524 |
<?php _e('Hide'); ?></label>
|
525 |
-
<input id="<?php echo $this->get_field_id('title'); ?>" class="widefat" name="<?php echo $this->get_field_name('title'); ?>"
|
|
|
526 |
<small><em><?php _e('Title can be set, but need not be displayed'); ?></em></small>
|
527 |
</p>
|
528 |
|
529 |
<p>
|
530 |
<label for="<?php echo $this->get_field_id('menu'); ?>"><?php _e('Select Menu:'); ?></label>
|
531 |
-
<select id="<?php echo $this->get_field_id('menu'); ?>" class="widget-<?php echo $this->id_base; ?>-
|
|
|
532 |
<?php
|
533 |
foreach( $menus as $i=>$menu ){
|
534 |
$menus[ $i ]->_items = wp_get_nav_menu_items( $menu->term_id );
|
535 |
?>
|
536 |
<option <?php selected($instance['menu'], $menu->term_id); ?> value="<?php echo $menu->term_id; ?>"><?php echo $menu->name; ?></option>
|
537 |
<?php
|
538 |
-
|
539 |
-
|
540 |
</select>
|
541 |
</p>
|
542 |
|
543 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
544 |
<p>
|
545 |
<label for="<?php echo $this->get_field_id('filter'); ?>_0">
|
546 |
-
<input id="<?php echo $this->get_field_id('filter'); ?>_0" class="widget-<?php echo $this->id_base; ?>-
|
|
|
547 |
<?php _e('Show all'); ?></label>
|
548 |
<br /><label for="<?php echo $this->get_field_id('filter'); ?>_1">
|
549 |
-
<input id="<?php echo $this->get_field_id('filter'); ?>_1" class="widget-<?php echo $this->id_base; ?>-
|
|
|
550 |
<?php _e('Children of:'); ?></label>
|
551 |
-
<select id="<?php echo $this->get_field_id('filter_item'); ?>" class="widget-<?php echo $this->id_base; ?>-
|
|
|
552 |
<option value="0" <?php selected( $instance['filter_item'], 0 ); ?>><?php _e('Current Item'); ?></option>
|
|
|
|
|
553 |
<?php
|
|
|
|
|
|
|
|
|
|
|
554 |
$maxlevel = 1;
|
555 |
foreach( $menus as $i=>$menu ){
|
556 |
-
|
557 |
-
$
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
if( !empty( $menu->_items ) ){
|
562 |
foreach( $menu->_items as $item ){
|
563 |
//exclude orpans!
|
564 |
if( isset($itemindents[ $item->menu_item_parent ])){
|
565 |
-
$
|
566 |
-
$
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
}
|
571 |
}
|
572 |
}
|
573 |
-
|
574 |
-
</optgroup>
|
575 |
-
<?php
|
576 |
}
|
577 |
-
|
|
|
|
|
578 |
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
579 |
</p>
|
580 |
|
581 |
<p>
|
@@ -610,25 +753,44 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
610 |
</p>
|
611 |
<?php $this->_close_a_field_section(); ?>
|
612 |
|
613 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
614 |
<p>
|
615 |
<label for="<?php echo $this->get_field_id('flat_output'); ?>_0">
|
616 |
-
<input id="<?php echo $this->get_field_id('flat_output'); ?>_0" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
|
|
617 |
<?php _e('Hierarchical'); ?></label>
|
618 |
<label for="<?php echo $this->get_field_id('flat_output'); ?>_1">
|
619 |
-
<input id="<?php echo $this->get_field_id('flat_output'); ?>_1" name="<?php echo $this->get_field_name('flat_output'); ?>"
|
|
|
620 |
<?php _e('Flat'); ?></label>
|
621 |
</p>
|
622 |
|
623 |
-
<p>
|
624 |
<label for="<?php echo $this->get_field_id('include_parent'); ?>">
|
625 |
-
<input id="<?php echo $this->get_field_id('include_parent'); ?>"
|
626 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
627 |
<br /><label for="<?php echo $this->get_field_id('include_ancestors'); ?>">
|
628 |
-
<input id="<?php echo $this->get_field_id('include_ancestors'); ?>"
|
|
|
|
|
629 |
<?php _e('Include Ancestors'); ?></label>
|
630 |
<br /><label for="<?php echo $this->get_field_id('title_from_parent'); ?>">
|
631 |
-
<input id="<?php echo $this->get_field_id('title_from_parent'); ?>"
|
|
|
|
|
632 |
<?php _e('Title from Parent Item'); ?></label>
|
633 |
<br /><small><em><?php _e('Only if the "Children of:" Filter returns items'); ?></em></small>
|
634 |
</p>
|
@@ -636,71 +798,109 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
636 |
<p>
|
637 |
<?php _e('Change UL to OL:'); ?>
|
638 |
<br /><label for="<?php echo $this->get_field_id('ol_root'); ?>">
|
639 |
-
<input id="<?php echo $this->get_field_id('ol_root'); ?>" name="<?php echo $this->get_field_name('ol_root'); ?>"
|
|
|
640 |
<?php _e('Top Level'); ?></label>
|
641 |
<label for="<?php echo $this->get_field_id('ol_sub'); ?>">
|
642 |
-
<input id="<?php echo $this->get_field_id('ol_sub'); ?>" name="<?php echo $this->get_field_name('ol_sub'); ?>"
|
|
|
643 |
<?php _e('Sub-Levels'); ?></label>
|
644 |
</p>
|
645 |
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
<p>
|
647 |
<label for="<?php echo $this->get_field_id('hide_empty'); ?>">
|
648 |
-
<input id="<?php echo $this->get_field_id('hide_empty'); ?>" name="<?php echo $this->get_field_name('hide_empty'); ?>"
|
|
|
649 |
<?php _e('Hide Widget if Empty'); ?></label>
|
650 |
<br /><small><em><?php _e('Prevents any output when no items are found'); ?></em></small>
|
651 |
</p>
|
|
|
|
|
|
|
|
|
|
|
652 |
<?php $this->_close_a_field_section(); ?>
|
653 |
|
654 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
655 |
<p>
|
656 |
<label for="<?php echo $this->get_field_id('container'); ?>"><?php _e('Element:') ?></label>
|
657 |
-
<input id="<?php echo $this->get_field_id('container'); ?>" name="<?php echo $this->get_field_name('container'); ?>"
|
658 |
-
|
|
|
659 |
</p>
|
660 |
<p>
|
661 |
<label for="<?php echo $this->get_field_id('container_id'); ?>"><?php _e('Unique ID:') ?></label>
|
662 |
-
<input id="<?php echo $this->get_field_id('container_id'); ?>" name="<?php echo $this->get_field_name('container_id'); ?>"
|
663 |
-
|
|
|
664 |
</p>
|
665 |
<p>
|
666 |
<label for="<?php echo $this->get_field_id('container_class'); ?>"><?php _e('Class:') ?></label>
|
667 |
-
<input id="<?php echo $this->get_field_id('container_class'); ?>" name="<?php echo $this->get_field_name('container_class'); ?>"
|
668 |
-
|
|
|
669 |
</p>
|
670 |
<?php $this->_close_a_field_section(); ?>
|
671 |
|
672 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
673 |
<p>
|
674 |
<label for="<?php echo $this->get_field_id('menu_class'); ?>"><?php _e('Menu Class:') ?></label>
|
675 |
-
<input id="<?php echo $this->get_field_id('menu_class'); ?>" name="<?php echo $this->get_field_name('menu_class'); ?>"
|
676 |
-
|
|
|
677 |
</p>
|
678 |
<p>
|
679 |
<label for="<?php echo $this->get_field_id('widget_class'); ?>"><?php _e('Widget Class:') ?></label>
|
680 |
-
<input id="<?php echo $this->get_field_id('widget_class'); ?>" name="<?php echo $this->get_field_name('widget_class'); ?>"
|
681 |
-
|
|
|
682 |
</p>
|
683 |
<?php $this->_close_a_field_section(); ?>
|
684 |
|
685 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
686 |
<p>
|
687 |
<label for="<?php echo $this->get_field_id('before'); ?>"><?php _e('Before the Link:') ?></label>
|
688 |
-
<input id="<?php echo $this->get_field_id('before'); ?>" class="widefat" name="<?php echo $this->get_field_name('before'); ?>"
|
|
|
689 |
<small><em><?php _e( htmlspecialchars('Text/HTML to go before the <a> of the link') ); ?></em></small>
|
690 |
</p>
|
691 |
<p>
|
692 |
<label for="<?php echo $this->get_field_id('after'); ?>"><?php _e('After the Link:') ?></label>
|
693 |
-
<input id="<?php echo $this->get_field_id('after'); ?>" class="widefat" name="<?php echo $this->get_field_name('after'); ?>"
|
|
|
694 |
<small><em><?php _e( htmlspecialchars('Text/HTML to go after the </a> of the link') ); ?></em></small>
|
695 |
</p>
|
696 |
<p>
|
697 |
<label for="<?php echo $this->get_field_id('link_before'); ?>"><?php _e('Before the Link Text:') ?></label>
|
698 |
-
<input id="<?php echo $this->get_field_id('link_before'); ?>" class="widefat" name="<?php echo $this->get_field_name('link_before'); ?>"
|
|
|
699 |
<small><em><?php _e( 'Text/HTML to go before the link text' ); ?></em></small>
|
700 |
</p>
|
701 |
<p>
|
702 |
<label for="<?php echo $this->get_field_id('link_after'); ?>"><?php _e('After the Link Text:') ?></label>
|
703 |
-
<input id="<?php echo $this->get_field_id('link_after'); ?>" class="widefat" name="<?php echo $this->get_field_name('link_after'); ?>"
|
|
|
704 |
<small><em><?php _e( 'Text/HTML to go after the link text' ); ?></em></small>
|
705 |
</p>
|
706 |
<?php $this->_close_a_field_section(); ?>
|
@@ -719,8 +919,9 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
719 |
// the default is *not* collapsed (field $fname == 0)
|
720 |
$collapsed = !empty($instance[$fname]);
|
721 |
?>
|
722 |
-
<div class="stuffbox widget-<?php echo $this->id_base; ?>-collapsible-fieldset" style="margin:0 0 0.5em;cursor:pointer;">
|
723 |
-
<input id="<?php echo $this->get_field_id($fname); ?>" class="hidden-field" name="<?php echo $this->get_field_name($fname); ?>"
|
|
|
724 |
<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>
|
725 |
<h3 style="font-size:1em;margin:0;padding:2px 0.5em;"><?php echo $text; ?></h3>
|
726 |
</div>
|
@@ -736,5 +937,14 @@ class Custom_Menu_Wizard_Walker extends Walker_Nav_menu{
|
|
736 |
</div>
|
737 |
<?php
|
738 |
} //end _close_a_field_section()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
739 |
|
740 |
-
}
|
3 |
* Plugin Name: Custom Menu Wizard
|
4 |
* Plugin URI: http://www.wizzud.com/
|
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.1.0
|
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)
|
16 |
+
* - added Fallback to Current Item option, and subsidiary Output option overrides, to enable Current Root & Current Parent to match a Current Item at root level
|
17 |
+
* - added max-width style (100%) to the 'Children of' SELECT in the widget options
|
18 |
+
* - added widget version to the admin js enqueuer
|
19 |
+
* - ignore/disable hide_empty for WP >= v3.6 (wp_nav_menu() does it automatically)
|
20 |
+
* - rebuilt 'Children of' SELECT to account for IE's lack of OPTGROUP/OPTION styling
|
21 |
+
* - moved the setting of 'disabled' attributes on INPUTs/SELECTs from PHP into javascript
|
22 |
+
*/
|
23 |
+
|
24 |
+
$Custom_Menu_Wizard_Widget_Version = '1.1.0';
|
25 |
+
|
26 |
/**
|
27 |
* registers the widget
|
28 |
*/
|
35 |
* enqueues script file for the widget admin
|
36 |
*/
|
37 |
function custom_menu_wizard_widget_admin_script(){
|
38 |
+
wp_enqueue_script('custom-menu-wizard-plugin-script', plugins_url('/custom-menu-wizard.js', __FILE__), array('jquery'), $Custom_Menu_Wizard_Widget_Version);
|
39 |
}
|
40 |
add_action('admin_print_scripts-widgets.php', 'custom_menu_wizard_widget_admin_script');
|
41 |
|
42 |
/*
|
43 |
* Custom Menu Wizard Walker class
|
44 |
+
* NB: Walker_Nav_Menu class is in wp-includes/nav-menu-template.php, and is itself an
|
45 |
+
* extension of the Walker class (wp-includes/class-wp-walker.php)
|
46 |
*/
|
47 |
+
class Custom_Menu_Wizard_Walker extends Walker_Nav_Menu {
|
48 |
|
49 |
/**
|
50 |
* opens a sub-level with a UL or OL start-tag
|
86 |
|
87 |
$cmw =& $args->_custom_menu_wizard;
|
88 |
//in $cmw (array) :
|
89 |
+
// filter : true = kids of (current [root|parent] item or specific item)
|
90 |
+
// filter_item : 0 = current item, -1 = parent of current (v1.1.0), -2 = root ancestor of current (v1.1.0); else a menu item id
|
91 |
// flat_output : true = equivalent of $max_depth == -1
|
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 as 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 |
+
$fallback_current_item = $cmw['fallback_no_ancestor'] && ( $find_current_parent || $find_current_root ); //v1.1.0
|
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 |
|
119 |
//start level applies to the *kids* of a find_kids_of search, not to the parent, so while we
|
120 |
//are still looking for the parent, the start_level for a find_kids_of search is actually one
|
121 |
+
//up from cmw['start_level']...
|
122 |
$start_level = $find_kids_of ? $cmw['start_level'] - 1 : $cmw['start_level'];
|
123 |
|
124 |
$keep_ids = array();
|
125 |
$keep_items = array();
|
126 |
+
$temp = array(0 => array('kids' => array()));
|
127 |
foreach( $elements as $i=>$item ){
|
128 |
if( empty( $item->$parent_field ) ){
|
129 |
//set root level of menu, and no ancestors...
|
130 |
$temp[ $item->$id_field ] = array(
|
131 |
'level' => 1,
|
132 |
//this is an array of indexes into $elements...
|
133 |
+
'breadcrumb' => array( $i ),
|
134 |
+
'parent' => 0,
|
135 |
+
'kids' => array()
|
136 |
);
|
137 |
+
$temp[0]['kids'][] = $i;
|
138 |
}elseif( isset( $temp[ $item->$parent_field ] ) ){
|
139 |
//set one greater than parent's level, and ancestors are parent's ancestors plus the parent...
|
140 |
$temp[ $item->$id_field ] = array(
|
141 |
'level' => $temp[ $item->$parent_field ]['level'] + 1,
|
142 |
+
'breadcrumb' => $temp[ $item->$parent_field ]['breadcrumb'],
|
143 |
+
'parent' => $item->$parent_field,
|
144 |
+
'kids' => array()
|
145 |
);
|
146 |
$temp[ $item->$id_field ]['breadcrumb'][] = $i;
|
147 |
+
$temp[ $item->$parent_field ]['kids'][] = $i;
|
148 |
}
|
149 |
//if $temp[] hasn't been set then it's an orphan; in order to keep orphans, max_depth must be 0 (ie. unlimited)
|
150 |
//note that if a child is an orphan then all descendants of that child are also considered to be orphans!
|
156 |
//are we still looking for a starting point?...
|
157 |
if( empty( $keep_ids ) ){
|
158 |
if( //...we're looking for unspecific items starting at this level...
|
159 |
+
!$find_kids_of ||
|
160 |
//...we're looking for current item, and this is it...
|
161 |
( $find_current_item && $item->current ) ||
|
162 |
+
//...we're looking for current parent, and this is it...
|
163 |
+
( $find_current_parent && $item->current_item_parent ) ||
|
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 |
+
( $fallback_current_item && $item->current && $temp[ $item->$id_field ]['level'] == 1 ) ||
|
168 |
//...we're looking for a particular menu item, and this is it...
|
169 |
+
( $cmw['filter_item'] == $item->$id_field )
|
|
|
|
|
170 |
){
|
171 |
//NOTE : at this point I'm *keeping* the id of the parent of a find_kids_of search, but not the actual item!
|
172 |
$keep_ids[] = $item->$id_field;
|
173 |
if( !$find_kids_of ){
|
174 |
$keep_items[] = $item;
|
175 |
}
|
176 |
+
//v1.1.0 if this was the fallback option, we may need to update $include_parent[_siblings]...
|
177 |
+
if( $fallback_current_item && $item->current && $temp[ $item->$id_field ]['level'] == 1 ){
|
178 |
+
$include_parent = $include_parent || $cmw['fallback_include_parent'];
|
179 |
+
$include_parent_siblings = $include_parent_siblings || $cmw['fallback_include_parent_siblings'];
|
180 |
+
}
|
181 |
//depth, if set, kicks in at this point :
|
182 |
// if doing a find_kids_of search then this level counts as 0, and the next level (the kids) counts as 1
|
183 |
// otherwise, the current level counts as 1
|
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 |
}
|
205 |
if( !empty( $keep_items) ){
|
206 |
|
207 |
//do we need to prepend parent or ancestors?...
|
208 |
+
$breadcrumb = $temp[ $keep_items[0]->$id_field ]['breadcrumb'];
|
209 |
+
//remove the last breadcrumb element, which is the item's own index...
|
210 |
+
array_pop( $breadcrumb );
|
211 |
+
//last element is now the parent (if there is one)
|
212 |
+
$i = $j = count( $breadcrumb );
|
213 |
+
|
214 |
+
//do we want the parent's title as the widget title?...
|
215 |
+
if( $find_kids_of && $cmw['title_from_parent'] && $i > 0 ){
|
216 |
+
$cmw['parent_title'] = apply_filters(
|
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
|
225 |
+
//kids of the parent's parent onto keep_items...
|
226 |
+
if( $find_kids_of && $i > 0 && $include_parent_siblings ){
|
227 |
+
$siblings = $temp[ $keep_items[0]->$id_field ]['parent'];
|
228 |
+
if( !empty( $siblings ) ){
|
229 |
+
$siblings = $temp[ $temp[ $siblings ]['parent'] ]['kids'];
|
230 |
+
}
|
231 |
+
if( !empty( $siblings ) ){
|
232 |
+
//remove (and store) parent...
|
233 |
+
$j = array_pop( $breadcrumb );
|
234 |
+
$parentAt = -1;
|
235 |
+
//going backwards thru the array, prepend the parent and anything higher in the array than it...
|
236 |
+
for($i = count($siblings) - 1; $i > -1; $i--){
|
237 |
+
if( $parentAt < 0 && $siblings[ $i ] == $j ){
|
238 |
+
$parentAt = $i;
|
239 |
+
}
|
240 |
+
if( $parentAt > -1 ){
|
241 |
+
array_unshift( $keep_items, $elements[ $siblings[ $i ] ]);
|
242 |
+
}
|
243 |
+
}
|
244 |
+
//going forwards thru the array, append anything lower in the array than the parent...
|
245 |
+
for($i = $parentAt + 1; $i < count($siblings); $i++){
|
246 |
+
//anything after parent gets appended; parent and before get prepended...
|
247 |
+
array_push( $keep_items, $elements[ $siblings[ $i ] ]);
|
248 |
+
}
|
249 |
+
$i = $j = count( $breadcrumb );
|
250 |
+
//don't include_parent now because we just have...
|
251 |
+
$include_parent = false;
|
252 |
+
}
|
253 |
+
unset( $siblings );
|
254 |
+
}
|
255 |
+
|
256 |
if( $find_kids_of && $i > 0 ){
|
257 |
if( $cmw['include_ancestors'] ){
|
258 |
$j = 0;
|
259 |
+
}elseif( $include_parent ){
|
260 |
--$j;
|
261 |
}
|
262 |
while( $i > $j ){
|
263 |
+
array_unshift( $keep_items, $elements[ $breadcrumb[ --$i ] ]);
|
264 |
}
|
265 |
}
|
266 |
+
unset( $breadcrumb );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
}
|
268 |
|
269 |
//for each item we're keeping, use the temp array to hold:
|
320 |
|
321 |
var $_cmw_switches = array(
|
322 |
'hide_title',
|
323 |
+
'filter', //v1.1.0 changed from integer
|
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',
|
355 |
);
|
356 |
var $_cmw_integers = array(
|
357 |
'depth' => 0,
|
358 |
+
'filter_item' => -2, //v1.1.0 changed from 0
|
|
|
359 |
'menu' => 0,
|
360 |
'start_level' => 1
|
361 |
);
|
393 |
}
|
394 |
|
395 |
/**
|
396 |
+
* this (filter: wp_nav_menu) merely removes itself from the filters and returns an empty string
|
397 |
+
* it gets added by the cmw_filter_check_for_no_items method below, and only
|
398 |
* ever gets run when hide_empty is set on the widget instance
|
399 |
*
|
400 |
+
* v1.1.0 As of WP v3.6 this method becomes superfluous because wp_nav_menu() has had code added to immediately
|
401 |
+
* cop out (return false) if the output from wp_nav_menu_{$menu->slug}_items filter(s) is empty.
|
402 |
+
* However, it stays in so as to cope with versions < 3.6
|
403 |
+
*
|
404 |
* @param string $nav_menu HTML for the menu
|
405 |
* @param object $args
|
406 |
* @return string HTML for the menu
|
411 |
}
|
412 |
|
413 |
/**
|
414 |
+
* this gets run (filter: wp_nav_menu_{$menu->slug}_items) if hide_empty is set
|
415 |
* if $items is empty then add a wp_nav_menu filter to do the actual return of an empty string
|
416 |
* it gets run before the wp_nav_menu filter, but it gets the $items array whereas the wp_nav_menu filter does not
|
417 |
* it gets added by $this->widget() before wp_nav_menu() is called, and removed immediately after wp_nav_menu() returns
|
418 |
*
|
419 |
+
* v1.1.0 As of WP v3.6 this method becomes superfluous because wp_nav_menu() has had code added to immediately
|
420 |
+
* cop out (return false) if the output from wp_nav_menu_{$menu->slug}_items filter(s) is empty.
|
421 |
+
* However, it stays in so as to cope with versions < 3.6
|
422 |
+
*
|
423 |
* @param array $items Menu items
|
424 |
* @param object $args
|
425 |
* @return array Menu items
|
457 |
$instance[ $k ] = empty( $instance[ $k ] ) ? $v : trim( $instance[ $k ] );
|
458 |
}
|
459 |
|
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->cmw_title_from_parent = '';
|
464 |
|
465 |
//fetch menu...
|
509 |
'_custom_menu_wizard' => array(
|
510 |
'filter' => $instance['filter'],
|
511 |
'filter_item' => $instance['filter_item'],
|
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'],
|
529 |
if( !empty( $instance['container_class'] ) ){
|
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'] ){
|
593 |
}
|
594 |
//integers...
|
595 |
foreach( $this->_cmw_integers as $k=>$v ){
|
596 |
+
$instance[ $k ] = isset( $instance[ $k ]) ? max( $v, intval( $instance[ $k ] ) ) : max($v, 0);
|
597 |
}
|
598 |
//strings...
|
599 |
foreach( $this->_cmw_strings as $k=>$v ){
|
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 |
+
|
616 |
+
/**
|
617 |
+
* permanently visible section : Title (with Hide) and Menu
|
618 |
+
*/
|
619 |
?>
|
620 |
<p>
|
621 |
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
|
622 |
<label for="<?php echo $this->get_field_id('hide_title'); ?>" class="alignright">
|
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>
|
626 |
+
<input id="<?php echo $this->get_field_id('title'); ?>" class="widefat" name="<?php echo $this->get_field_name('title'); ?>"
|
627 |
+
type="text" value="<?php echo $instance['title']; ?>" />
|
628 |
<small><em><?php _e('Title can be set, but need not be displayed'); ?></em></small>
|
629 |
</p>
|
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'); ?>" class="widget-<?php echo $this->id_base; ?>-selectmenu"
|
634 |
+
name="<?php echo $this->get_field_name('menu'); ?>">
|
635 |
<?php
|
636 |
foreach( $menus as $i=>$menu ){
|
637 |
$menus[ $i ]->_items = wp_get_nav_menu_items( $menu->term_id );
|
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>
|
644 |
</p>
|
645 |
|
646 |
+
<?php
|
647 |
+
/**
|
648 |
+
* start collapsible section : 'Filter'
|
649 |
+
*/
|
650 |
+
$this->_open_a_field_section($instance, 'Filter', 'fs_filter');
|
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 for="<?php echo $this->get_field_id('filter'); ?>_0">
|
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 for="<?php echo $this->get_field_id('filter'); ?>_1">
|
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>
|
662 |
+
<select id="<?php echo $this->get_field_id('filter_item'); ?>" class="widget-<?php echo $this->id_base; ?>-listen"
|
663 |
+
style="max-width:100%;" name="<?php echo $this->get_field_name('filter_item'); ?>">
|
664 |
<option value="0" <?php selected( $instance['filter_item'], 0 ); ?>><?php _e('Current Item'); ?></option>
|
665 |
+
<option value="-2" <?php selected( $instance['filter_item'], -2 ); ?>><?php _e('Current Root Item'); ?></option>
|
666 |
+
<option value="-1" <?php selected( $instance['filter_item'], -1 ); ?>><?php _e('Current Parent Item'); ?></option>
|
667 |
<?php
|
668 |
+
//v1.1.0
|
669 |
+
// IE is a pita when it comes to SELECTs because it ignores any styling on OPTGROUPs and OPTIONs, so I'm changing the way
|
670 |
+
// that this SELECT works by introducing a copy from which the javascript can pick the relevant OPTGROUP
|
671 |
+
$menuOptions = array();
|
672 |
+
|
673 |
$maxlevel = 1;
|
674 |
foreach( $menus as $i=>$menu ){
|
675 |
+
//v1.1.0 changed the indents from padding to hyphen-space (for IE!!!! grrrr...)
|
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 ])){
|
684 |
+
$itemindents[ $item->ID ] = $itemindents[ $item->menu_item_parent ] + 1;
|
685 |
+
$maxlevel = max( $maxlevel, $itemindents[ $item->ID ] );
|
686 |
+
$menuOptions[] = '<option style="padding-left:0.75em;" value="' . $item->ID . '" ' .
|
687 |
+
selected( $instance['filter_item'], $item->ID, false ) . '>' .
|
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;
|
696 |
+
?>
|
697 |
</select>
|
698 |
+
<select id="<?php echo $this->get_field_id('filter_item_ignore'); ?>" disabled="disabled"
|
699 |
+
style="display:none;position:absolute;left:-5000px;top:-5000px;"
|
700 |
+
name="<?php echo $this->get_field_name('filter_item_ignore'); ?>">
|
701 |
+
<?php echo $menuOptions; ?>
|
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>
|
753 |
</p>
|
754 |
<?php $this->_close_a_field_section(); ?>
|
755 |
|
756 |
+
<?php
|
757 |
+
/**
|
758 |
+
* start collapsible section : 'Output'
|
759 |
+
*/
|
760 |
+
$this->_open_a_field_section($instance, 'Output', 'fs_output');
|
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 for="<?php echo $this->get_field_id('flat_output'); ?>_0">
|
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 for="<?php echo $this->get_field_id('flat_output'); ?>_1">
|
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 for="<?php echo $this->get_field_id('include_parent'); ?>">
|
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 for="<?php echo $this->get_field_id('include_parent_siblings'); ?>">
|
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 for="<?php echo $this->get_field_id('include_ancestors'); ?>">
|
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 for="<?php echo $this->get_field_id('title_from_parent'); ?>">
|
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 Item'); ?></label>
|
795 |
<br /><small><em><?php _e('Only if the "Children of:" Filter returns items'); ?></em></small>
|
796 |
</p>
|
798 |
<p>
|
799 |
<?php _e('Change UL to OL:'); ?>
|
800 |
<br /><label for="<?php echo $this->get_field_id('ol_root'); ?>">
|
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 for="<?php echo $this->get_field_id('ol_sub'); ?>">
|
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>
|
808 |
</p>
|
809 |
|
810 |
+
<?php
|
811 |
+
//v1.1.0 As of WP v3.6, wp_nav_menu() automatically cops out (without outputting any HTML) if there are no items,
|
812 |
+
// so the hide_empty option becomes superfluous; however, I'll keep the previous setting (if there was one)
|
813 |
+
// in case of reversion to an earlier version of WP...
|
814 |
+
if( $this->_pre_3point6() ){
|
815 |
+
?>
|
816 |
<p>
|
817 |
<label for="<?php echo $this->get_field_id('hide_empty'); ?>">
|
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>
|
821 |
<br /><small><em><?php _e('Prevents any output when no items are found'); ?></em></small>
|
822 |
</p>
|
823 |
+
<?php }else{ ?>
|
824 |
+
<input id="<?php echo $this->get_field_id('hide_empty'); ?>" name="<?php echo $this->get_field_name('hide_empty'); ?>"
|
825 |
+
type="hidden" value="<?php echo $instance['hide_empty'] ? '1' : ''; ?>" />
|
826 |
+
<?php } ?>
|
827 |
+
|
828 |
<?php $this->_close_a_field_section(); ?>
|
829 |
|
830 |
+
<?php
|
831 |
+
/**
|
832 |
+
* start collapsible section : 'Container'
|
833 |
+
*/
|
834 |
+
$this->_open_a_field_section($instance, 'Container', 'fs_container');
|
835 |
+
?>
|
836 |
<p>
|
837 |
<label for="<?php echo $this->get_field_id('container'); ?>"><?php _e('Element:') ?></label>
|
838 |
+
<input id="<?php echo $this->get_field_id('container'); ?>" name="<?php echo $this->get_field_name('container'); ?>"
|
839 |
+
type="text" value="<?php echo $instance['container']; ?>" />
|
840 |
+
<br /><small><em><?php _e( 'Eg. div or nav; leave empty for no container' ); ?></em></small>
|
841 |
</p>
|
842 |
<p>
|
843 |
<label for="<?php echo $this->get_field_id('container_id'); ?>"><?php _e('Unique ID:') ?></label>
|
844 |
+
<input id="<?php echo $this->get_field_id('container_id'); ?>" name="<?php echo $this->get_field_name('container_id'); ?>"
|
845 |
+
type="text" value="<?php echo $instance['container_id']; ?>" />
|
846 |
+
<br /><small><em><?php _e( 'An optional ID for the container' ); ?></em></small>
|
847 |
</p>
|
848 |
<p>
|
849 |
<label for="<?php echo $this->get_field_id('container_class'); ?>"><?php _e('Class:') ?></label>
|
850 |
+
<input id="<?php echo $this->get_field_id('container_class'); ?>" name="<?php echo $this->get_field_name('container_class'); ?>"
|
851 |
+
type="text" value="<?php echo $instance['container_class']; ?>" />
|
852 |
+
<br /><small><em><?php _e( 'Extra class for the container' ); ?></em></small>
|
853 |
</p>
|
854 |
<?php $this->_close_a_field_section(); ?>
|
855 |
|
856 |
+
<?php
|
857 |
+
/**
|
858 |
+
* start collapsible section : 'Classes'
|
859 |
+
*/
|
860 |
+
$this->_open_a_field_section($instance, 'Classes', 'fs_classes');
|
861 |
+
?>
|
862 |
<p>
|
863 |
<label for="<?php echo $this->get_field_id('menu_class'); ?>"><?php _e('Menu Class:') ?></label>
|
864 |
+
<input id="<?php echo $this->get_field_id('menu_class'); ?>" name="<?php echo $this->get_field_name('menu_class'); ?>"
|
865 |
+
type="text" value="<?php echo $instance['menu_class']; ?>" />
|
866 |
+
<br /><small><em><?php _e( 'Class for the list element forming the menu' ); ?></em></small>
|
867 |
</p>
|
868 |
<p>
|
869 |
<label for="<?php echo $this->get_field_id('widget_class'); ?>"><?php _e('Widget Class:') ?></label>
|
870 |
+
<input id="<?php echo $this->get_field_id('widget_class'); ?>" name="<?php echo $this->get_field_name('widget_class'); ?>"
|
871 |
+
type="text" value="<?php echo $instance['widget_class']; ?>" />
|
872 |
+
<br /><small><em><?php _e( 'Extra class for the widget itself' ); ?></em></small>
|
873 |
</p>
|
874 |
<?php $this->_close_a_field_section(); ?>
|
875 |
|
876 |
+
<?php
|
877 |
+
/**
|
878 |
+
* start collapsible section : 'Links'
|
879 |
+
*/
|
880 |
+
$this->_open_a_field_section($instance, 'Links', 'fs_links');
|
881 |
+
?>
|
882 |
<p>
|
883 |
<label for="<?php echo $this->get_field_id('before'); ?>"><?php _e('Before the Link:') ?></label>
|
884 |
+
<input id="<?php echo $this->get_field_id('before'); ?>" class="widefat" name="<?php echo $this->get_field_name('before'); ?>"
|
885 |
+
type="text" value="<?php echo $instance['before']; ?>" />
|
886 |
<small><em><?php _e( htmlspecialchars('Text/HTML to go before the <a> of the link') ); ?></em></small>
|
887 |
</p>
|
888 |
<p>
|
889 |
<label for="<?php echo $this->get_field_id('after'); ?>"><?php _e('After the Link:') ?></label>
|
890 |
+
<input id="<?php echo $this->get_field_id('after'); ?>" class="widefat" name="<?php echo $this->get_field_name('after'); ?>"
|
891 |
+
type="text" value="<?php echo $instance['after']; ?>" />
|
892 |
<small><em><?php _e( htmlspecialchars('Text/HTML to go after the </a> of the link') ); ?></em></small>
|
893 |
</p>
|
894 |
<p>
|
895 |
<label for="<?php echo $this->get_field_id('link_before'); ?>"><?php _e('Before the Link Text:') ?></label>
|
896 |
+
<input id="<?php echo $this->get_field_id('link_before'); ?>" class="widefat" name="<?php echo $this->get_field_name('link_before'); ?>"
|
897 |
+
type="text" value="<?php echo $instance['link_before']; ?>" />
|
898 |
<small><em><?php _e( 'Text/HTML to go before the link text' ); ?></em></small>
|
899 |
</p>
|
900 |
<p>
|
901 |
<label for="<?php echo $this->get_field_id('link_after'); ?>"><?php _e('After the Link Text:') ?></label>
|
902 |
+
<input id="<?php echo $this->get_field_id('link_after'); ?>" class="widefat" name="<?php echo $this->get_field_name('link_after'); ?>"
|
903 |
+
type="text" value="<?php echo $instance['link_after']; ?>" />
|
904 |
<small><em><?php _e( 'Text/HTML to go after the link text' ); ?></em></small>
|
905 |
</p>
|
906 |
<?php $this->_close_a_field_section(); ?>
|
919 |
// the default is *not* collapsed (field $fname == 0)
|
920 |
$collapsed = !empty($instance[$fname]);
|
921 |
?>
|
922 |
+
<div class="stuffbox widget-<?php echo $this->id_base; ?>-collapsible-fieldset" title="<?php _e( 'Click to show/hide' ); ?>" style="margin:0 0 0.5em;cursor:pointer;">
|
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 echo $text; ?></h3>
|
927 |
</div>
|
937 |
</div>
|
938 |
<?php
|
939 |
} //end _close_a_field_section()
|
940 |
+
|
941 |
+
/**
|
942 |
+
* returns true if the version of WP is lower than 3.6 (ie. 3.5* or below)
|
943 |
+
*/
|
944 |
+
function _pre_3point6(){
|
945 |
+
global $wp_version;
|
946 |
+
|
947 |
+
return version_compare( strtolower( $wp_version ), '3.6a', '<' );
|
948 |
+
} //end _pre_3point6()
|
949 |
|
950 |
+
} //end of class
|
demo.html
ADDED
@@ -0,0 +1,418 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en-GB">
|
3 |
+
<head>
|
4 |
+
<title>Custom Menu Wizard : Interactive Demo</title>
|
5 |
+
<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
|
6 |
+
<script type='text/javascript' src='custom-menu-wizard.js'></script>
|
7 |
+
<style type='text/css'>
|
8 |
+
html, body {width:100%; border:0 none; margin:0; padding:0;}
|
9 |
+
body {font-family:arial,sans-serif; font-size:14px; font-weight:normal; line-height:1.25; color:#333333; background-color:#ffffff;}
|
10 |
+
div, p, h3, ul, ol, li, form, input, select, label, a {position:relative;}
|
11 |
+
a {color:#333333; text-decoration:none;}
|
12 |
+
p {margin: 1em 0;}
|
13 |
+
input, select {font-family:inherit; font-size:inherit; font-weight:inherit; color:inherit;}
|
14 |
+
select {max-width:100%;}
|
15 |
+
label {vertical-align:middle;}
|
16 |
+
form {display:block; width:270px;}
|
17 |
+
h3 {border-bottom:1px solid #cccccc;margin:0 0 0.25em; padding: 0.5em 0 0.25em;}
|
18 |
+
button {background-color:#cccccc; border-color:#999999; border-radius:0.5em 0 0.5em 0; border-style:solid; border-width:1px 0 0 1px; bottom:-1em; cursor:pointer; font-size:inherit; margin:0; padding:0 0.2em; position:absolute; right:-1em;}
|
19 |
+
button:hover {background-color:#666666; color:#ffffff;}
|
20 |
+
optgroup option {padding-left:0.75em;}
|
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 |
+
#theoutput div {margin:0.5em 0; padding:0 1em; border:1px solid #cccccc; border-radius:0.5em; min-height:2em; min-width:8em;}
|
25 |
+
#theoutput ul, #theoutput ol {margin:0.5em 0 0.5em 1.5em; padding:0;}
|
26 |
+
#theoutput li ul {margin:0 0 0 1em;}
|
27 |
+
#theoutput li ol {margin:0 0 0 1.5em;}
|
28 |
+
#theoutput ul {list-style-type:disc;}
|
29 |
+
#theoutput ul ul {list-style-type:circle;}
|
30 |
+
#theoutput ul ul ul {list-style-type:square;}
|
31 |
+
#theoutput ul ul ul ul {list-style-type:disc;}
|
32 |
+
#theoutput ul ul ul ul ul {list-style-type:circle;}
|
33 |
+
#theoutput ol {list-style-type:decimal;}
|
34 |
+
#theoutput ol ol {list-style-type:upper-alpha;}
|
35 |
+
#theoutput ol ol ol {list-style-type:lower-alpha;}
|
36 |
+
#theoutput ol ol ol ol {list-style-type:lower-roman;}
|
37 |
+
#theoutput ol ol ol ol ol {list-style-type:decimal;}
|
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;}
|
41 |
+
#themenu li {display:block; margin:0; padding:0;}
|
42 |
+
#themenu a {display:inline-block; text-align:center; padding:0.3333em; margin:0.1667em; border-radius:0.3333em;}
|
43 |
+
#themenu span {display:block; width:6em; height:1.75em; line-height:1.75; border:1px solid #999999; border-radius:0.25em; box-shadow:2px 2px 2px 0px #666666;}
|
44 |
+
#thefooter {float:left; clear:left; margin:0 1em; color:#808080;}
|
45 |
+
#thefooter div {font-size:12px;}
|
46 |
+
.alignleft {float:left;}
|
47 |
+
.alignright {float:right;}
|
48 |
+
.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)";}
|
49 |
+
.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)";}
|
50 |
+
.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)";}
|
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;}
|
54 |
+
.widefat {width:100%;}
|
55 |
+
</style>
|
56 |
+
</head>
|
57 |
+
<body>
|
58 |
+
<div>
|
59 |
+
<div id='theform' class='alignright'>
|
60 |
+
<form>
|
61 |
+
<div id="formheader">
|
62 |
+
<strong>Custom Menu Wizard</strong> Interactive Demo
|
63 |
+
<br /><small>v1.1.0 <em>(subset of admin options)</em></small><strong class="tryit"><em>Try it out…</em></strong>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
<p>
|
67 |
+
<label for="widget-custom-menu-wizard-2-title">Title:</label>
|
68 |
+
<label class="alignright">
|
69 |
+
<input type="checkbox" value="1" name="hide_title" id="widget-custom-menu-wizard-2-hide_title">
|
70 |
+
Hide</label>
|
71 |
+
<input type="text" value="" name="title" class="widefat" id="widget-custom-menu-wizard-2-title">
|
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">
|
78 |
+
Show all</label>
|
79 |
+
<br /><label>
|
80 |
+
<input type="radio" value="1" name="filter" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_1">
|
81 |
+
Children of:</label>
|
82 |
+
<select name="filter_item" style="max-width:100%;" class="widget-custom-menu-wizard-listen" id="widget-custom-menu-wizard-2-filter_item">
|
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" data-cmw-active-menu='true'></optgroup>
|
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">
|
106 |
+
</select>
|
107 |
+
<br /><small><em>Level to start testing items for inclusion</em></small>
|
108 |
+
</p>
|
109 |
+
|
110 |
+
<p>
|
111 |
+
<label for="widget-custom-menu-wizard-2-depth">For Depth:</label>
|
112 |
+
<select name="depth" id="widget-custom-menu-wizard-2-depth">
|
113 |
+
<option selected="selected" value="0">unlimited</option>
|
114 |
+
</select>
|
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">
|
121 |
+
Hierarchical</label>
|
122 |
+
<label>
|
123 |
+
<input type="radio" value="1" name="flat_output" id="widget-custom-menu-wizard-2-flat_output_1">
|
124 |
+
Flat</label>
|
125 |
+
</p>
|
126 |
+
|
127 |
+
<p class="widget-custom-menu-wizard-disableif">
|
128 |
+
<label>
|
129 |
+
<input type="checkbox" value="1" name="include_parent" id="widget-custom-menu-wizard-2-include_parent">
|
130 |
+
Include Parent... </label>
|
131 |
+
<label>
|
132 |
+
<input type="checkbox" value="1" name="include_parent_siblings" id="widget-custom-menu-wizard-2-include_parent_siblings">
|
133 |
+
& its Siblings</label>
|
134 |
+
<br /><label>
|
135 |
+
<input type="checkbox" value="1" name="include_ancestors" id="widget-custom-menu-wizard-2-include_ancestors">
|
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 Item</label>
|
140 |
+
<br /><small><em>Only if the "Children of:" Filter returns items</em></small>
|
141 |
+
</p>
|
142 |
+
|
143 |
+
<p>
|
144 |
+
Change UL to OL:
|
145 |
+
<br /><label>
|
146 |
+
<input type="checkbox" value="1" name="ol_root" id="widget-custom-menu-wizard-2-ol_root">
|
147 |
+
Top Level</label>
|
148 |
+
<label>
|
149 |
+
<input type="checkbox" value="1" name="ol_sub" id="widget-custom-menu-wizard-2-ol_sub">
|
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>
|
157 |
+
|
158 |
+
<button title="Reset the form to its defaults...">reset</button>
|
159 |
+
</form>
|
160 |
+
</div>
|
161 |
+
|
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'>
|
168 |
+
<div>
|
169 |
+
<strong>"Selected" Menu</strong> <small class='grey'>(example)</small>
|
170 |
+
<small><em>Click an item to toggle "Current Item"</em></small>
|
171 |
+
</div>
|
172 |
+
<ul>
|
173 |
+
<li>
|
174 |
+
<a href='#'><span>alpha</span></a>
|
175 |
+
<ul>
|
176 |
+
<li>
|
177 |
+
<a href='#'><span>bravo</span></a>
|
178 |
+
</li>
|
179 |
+
<li>
|
180 |
+
<a href='#'><span>charlie</span></a>
|
181 |
+
<ul>
|
182 |
+
<li>
|
183 |
+
<a href='#'><span>delta</span></a>
|
184 |
+
<ul>
|
185 |
+
<li>
|
186 |
+
<a href='#'><span>echo</span></a>
|
187 |
+
<ul>
|
188 |
+
<li>
|
189 |
+
<a href='#'><span>foxtrot</span></a>
|
190 |
+
</li>
|
191 |
+
<li>
|
192 |
+
<a href='#'><span>golf</span></a>
|
193 |
+
</li>
|
194 |
+
</ul>
|
195 |
+
</li>
|
196 |
+
</ul>
|
197 |
+
</li>
|
198 |
+
<li>
|
199 |
+
<a href='#'><span>hotel</span></a>
|
200 |
+
<ul>
|
201 |
+
<li>
|
202 |
+
<a href='#'><span>india</span></a>
|
203 |
+
<ul>
|
204 |
+
<li>
|
205 |
+
<a href='#'><span>juliet</span></a>
|
206 |
+
</li>
|
207 |
+
</ul>
|
208 |
+
</li>
|
209 |
+
</ul>
|
210 |
+
</li>
|
211 |
+
</ul>
|
212 |
+
</li>
|
213 |
+
<li>
|
214 |
+
<a href='#'><span>kilo</span></a>
|
215 |
+
</li>
|
216 |
+
</ul>
|
217 |
+
</li>
|
218 |
+
<li>
|
219 |
+
<a href='#'><span>lima</span></a>
|
220 |
+
<ul>
|
221 |
+
<li>
|
222 |
+
<a href='#'><span>mike</span></a>
|
223 |
+
<ul>
|
224 |
+
<li>
|
225 |
+
<a href='#'><span>november</span></a>
|
226 |
+
</li>
|
227 |
+
</ul>
|
228 |
+
</li>
|
229 |
+
</ul>
|
230 |
+
</li>
|
231 |
+
</ul>
|
232 |
+
</div>
|
233 |
+
|
234 |
+
<div id='thefooter'>
|
235 |
+
<div>
|
236 |
+
Please note that this page is a simulator : it uses javascript to reproduce what the widget
|
237 |
+
would do, without interacting with WordPress in any way.
|
238 |
+
</div>
|
239 |
+
</div>
|
240 |
+
|
241 |
+
</div>
|
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 = {};
|
249 |
+
$.each($('form').serializeArray(), function(i, v){
|
250 |
+
settings[v.name] = switches[v.name] ? v.value === '1' : (integers[v.name] ? parseInt(v.value, 10) : v.value);
|
251 |
+
});
|
252 |
+
return settings;
|
253 |
+
},
|
254 |
+
hyphenIndent = function(s, n){
|
255 |
+
while(--n){
|
256 |
+
s = '- ' + s;
|
257 |
+
}
|
258 |
+
return s;
|
259 |
+
},
|
260 |
+
show = function(e, settings){
|
261 |
+
//hide_empty is assumed to be on (WP < v3.6) or will automatically on (WP v3.6+)
|
262 |
+
var output = $('#widget-output').empty(),
|
263 |
+
items = $('.picked'),
|
264 |
+
html = '',
|
265 |
+
currLevel = 0,
|
266 |
+
startLevel, title;
|
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>';
|
278 |
+
}else if(level > currLevel){
|
279 |
+
html += settings.ol_sub ? '<ol>' : '<ul>';
|
280 |
+
}else{
|
281 |
+
while(currLevel-- > level){
|
282 |
+
html += '</li>' + (settings.ol_sub ? '</ol>' : '</ul>');
|
283 |
+
}
|
284 |
+
}
|
285 |
+
}else{
|
286 |
+
startLevel = level;
|
287 |
+
}
|
288 |
+
html += '<li><a href="#">' + $(this).children('a').text() + '</a>';
|
289 |
+
currLevel = level;
|
290 |
+
});
|
291 |
+
while(currLevel-- > startLevel){
|
292 |
+
html += '</li>' + (settings.ol_sub ? '</ol>' : '</ul>');
|
293 |
+
}
|
294 |
+
html += '</li>';
|
295 |
+
output.html( (settings.ol_root ? '<ol>' : '<ul>') + html + (settings.ol_root ? '</ol>' : '</ul>') );
|
296 |
+
if(title){
|
297 |
+
output.prepend('<h3>' + title + '</h3>');
|
298 |
+
}
|
299 |
+
}
|
300 |
+
},
|
301 |
+
walk = function(e){
|
302 |
+
var settings = getSettings(),
|
303 |
+
includeParent = settings.include_parent,
|
304 |
+
includeParentSiblings = settings.include_parent_siblings,
|
305 |
+
items = $('#themenu li').removeClass('picked-parent'),
|
306 |
+
picked = items.filter('.picked'),
|
307 |
+
cls = [],
|
308 |
+
firstParent = true,
|
309 |
+
parent, i;
|
310 |
+
if(!settings.filter){
|
311 |
+
//show all...
|
312 |
+
for(i = 1; i < settings.start_level; i++){
|
313 |
+
items = items.not('.level-' + i);
|
314 |
+
}
|
315 |
+
if(settings.depth){
|
316 |
+
for(i = i + settings.depth; i < maxlevel + 1; i++){
|
317 |
+
items = items.not('.level-' + i);
|
318 |
+
}
|
319 |
+
}
|
320 |
+
}else{
|
321 |
+
//parent item...
|
322 |
+
if(settings.filter_item > 0){
|
323 |
+
parent = items.eq(settings.filter_item - 1);
|
324 |
+
}else if(!settings.filter_item){
|
325 |
+
parent = $('.current-item').closest('li');
|
326 |
+
}else{
|
327 |
+
if(settings.filter_item < -1){
|
328 |
+
//this could be more than one!...
|
329 |
+
parent = $('.current-ancestor').closest('li');
|
330 |
+
}else{
|
331 |
+
parent = $('.current-parent').closest('li');
|
332 |
+
}
|
333 |
+
if(!parent.length && settings.fallback_no_ancestor){
|
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...
|
340 |
+
parent = parent.filter(function(){
|
341 |
+
var level = parseInt(this.className.match(/level-(\d+)/)[1], 10),
|
342 |
+
rtn = firstParent && level > settings.start_level - 2,
|
343 |
+
i, j;
|
344 |
+
for(i = level + 1, j = 0; rtn && i <= maxlevel && (!settings.depth || j < settings.depth); i++, j++){
|
345 |
+
cls.push('.level-' + i);
|
346 |
+
}
|
347 |
+
if(rtn){
|
348 |
+
firstParent = false;
|
349 |
+
}
|
350 |
+
return rtn;
|
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 );
|
357 |
+
includeParent = false;
|
358 |
+
}
|
359 |
+
if(settings.include_ancestors){
|
360 |
+
items = items.add( parent.parentsUntil('#themenu', 'li') ).add( parent );
|
361 |
+
includeParent = false;
|
362 |
+
}
|
363 |
+
if(includeParent){
|
364 |
+
items = items.add( parent );
|
365 |
+
}
|
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'],
|
378 |
+
inPath = $(this).find('span').not('.' + cls[0]).parentsUntil('#themenu', 'li'),
|
379 |
+
i, n;
|
380 |
+
$('.' + cls.join(',.')).removeClass().removeAttr('title');
|
381 |
+
for(i = 0; i < inPath.length; i++){
|
382 |
+
n = i === 1 ? cls.join(' ') : cls[0];
|
383 |
+
inPath.eq(i).children('a').find('span').addClass(n).attr({title:n.replace(' ', ' & ').replace(/-/g, ' ')});
|
384 |
+
if(cls.length > 1){
|
385 |
+
cls.shift();
|
386 |
+
}
|
387 |
+
}
|
388 |
+
flds.eq(0).trigger('change');
|
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',
|
401 |
+
att = {value:i};
|
402 |
+
$('<option/>', att).text(i + levels).appendTo('#widget-custom-menu-wizard-2-depth');
|
403 |
+
if(i < 2){
|
404 |
+
att.selected = 'selected';
|
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 |
+
flds.not( flds.filter('[type="text"]').on('blur', show) )
|
414 |
+
.on('change', walk).eq(0).trigger('change');
|
415 |
+
});
|
416 |
+
</script>
|
417 |
+
</body>
|
418 |
+
</html>
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
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 |
-
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.
|
@@ -20,12 +20,13 @@ Features include:
|
|
20 |
* Specify a level to start at, and the number of levels to output
|
21 |
* Select hierarchicial or flat output, both options still abiding by the specified number of levels to output
|
22 |
* Allow the widget title to be entered but not output, or even to be set from the parent item of a menu's sub-branch
|
23 |
-
* Optionally disable widget output completely if there are no matching menu items found
|
24 |
* Include a sub-branch's parent and/or ancestor item(s) in the output, over and above any start level setting
|
25 |
* Automatically add cmw-level-N and cmw-has-submenu classes to output menu items
|
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 |
|
30 |
**Widget Options**
|
31 |
|
@@ -57,21 +58,54 @@ logical sections and made each section collapsible (with remembered state, open
|
|
57 |
|
58 |
* **Children of** *(radio & select)*
|
59 |
|
60 |
-
The dropdown list will present a "Current Item" option,
|
|
|
61 |
The widget will output the *children* of the selected item, always assuming that they lie within the bounds of any other parameters set.
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
* **Starting Level** *(select, default: "1")*
|
65 |
|
66 |
This is the level within the chosen menu (from `Select Menu`) that the widget will start looking for items to keep. Obviously, level 1
|
67 |
is the root level (ie. those items that have no parent item); level 2 is all the immediate children of the root level items, and so on.
|
|
|
68 |
|
69 |
* **For Depth** *(select, default: "unlimited")*
|
70 |
|
71 |
This is the maximum depth of the eventual output structure after filtering, and in the case of `Flat` output being requested it is
|
72 |
-
still applied - as if the output were `Hierarchical` and then flattened at the very last moment.
|
|
|
|
|
73 |
`For Depth` setting is applied relative to the level at which the first item to be kept is found. For example, say you were to set
|
74 |
-
`Children of` to "Current Item", `Starting Level` to "2", and `For Depth` to "2 levels"
|
75 |
then you would get the current item's immediate children (from level 4), plus *their* immediate children (from level 5).
|
76 |
|
77 |
* **Output**
|
@@ -85,10 +119,14 @@ logical sections and made each section collapsible (with remembered state, open
|
|
85 |
Output in a single list format, ignoring any parent-child relationship other than to maintain the same physical order as would be
|
86 |
presented in a `Hierarchical` output.
|
87 |
|
88 |
-
* **Include Parent
|
89 |
|
90 |
If checked, include the parent item in the output. Only applies to a successful `Children of` filter.
|
91 |
|
|
|
|
|
|
|
|
|
92 |
* **Include Ancestors** *(checkbox)*
|
93 |
|
94 |
Same as `Include Parent` except that all ancestors, right back to root level, are included. Only applies to a successful
|
@@ -115,6 +153,11 @@ logical sections and made each section collapsible (with remembered state, open
|
|
115 |
* **Hide Widget if Empty** *(checkbox)*
|
116 |
|
117 |
If checked, the widget will not output *any* HTML unless it finds at least one menu item that matches the Filter settings.
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
* **Container**
|
120 |
|
@@ -126,7 +169,7 @@ logical sections and made each section collapsible (with remembered state, open
|
|
126 |
|
127 |
* **Unique ID**
|
128 |
|
129 |
-
This allows you to specify
|
130 |
|
131 |
* **Class**
|
132 |
|
@@ -177,18 +220,47 @@ If you have a question or problem, please use the integrated Support forum.
|
|
177 |
|
178 |
== Screenshots ==
|
179 |
|
180 |
-
1. Widget options
|
|
|
|
|
181 |
|
182 |
-
|
183 |
|
184 |
-
|
185 |
|
186 |
== Changelog ==
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
= 1.0.0 =
|
|
|
189 |
Initial release
|
190 |
|
191 |
== Upgrade Notice ==
|
192 |
|
193 |
-
= 1.
|
194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
2 |
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.1.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.
|
20 |
* Specify a level to start at, and the number of levels to output
|
21 |
* Select hierarchicial or flat output, both options still abiding by the specified number of levels to output
|
22 |
* Allow the widget title to be entered but not output, or even to be set from the parent item of a menu's sub-branch
|
23 |
+
* Optionally disable widget output completely if there are no matching menu items found (WordPress < v3.6)
|
24 |
* Include a sub-branch's parent and/or ancestor item(s) in the output, over and above any start level setting
|
25 |
* Automatically add cmw-level-N and cmw-has-submenu classes to output menu items
|
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 |
|
58 |
|
59 |
* **Children of** *(radio & select)*
|
60 |
|
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 |
+
* **Fallback to Current Item** *(checkbox)* as of v1.1.0
|
74 |
+
|
75 |
+
This option is only applicable when `Children of` is set to either "Current Root Item" or "Current Parent Item". If enabled,
|
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 |
+
* **& its Siblings** *(checkbox)* as of v1.1.0
|
90 |
+
|
91 |
+
This option extends the `Fallback to Current Item` option (above). If the enabled fallback is actually used, this option can
|
92 |
+
temporarily override the equivalent **Output** option to ON. Note that if the equivalent **Output** option is already enabled,
|
93 |
+
this option has absolutely no effect.
|
94 |
|
95 |
* **Starting Level** *(select, default: "1")*
|
96 |
|
97 |
This is the level within the chosen menu (from `Select Menu`) that the widget will start looking for items to keep. Obviously, level 1
|
98 |
is the root level (ie. those items that have no parent item); level 2 is all the immediate children of the root level items, and so on.
|
99 |
+
Note that for a `Children of` filter there is no difference between level 1 and level 2 (because there are no children at level 1).
|
100 |
|
101 |
* **For Depth** *(select, default: "unlimited")*
|
102 |
|
103 |
This is the maximum depth of the eventual output structure after filtering, and in the case of `Flat` output being requested it is
|
104 |
+
still applied - as if the output were `Hierarchical` and then flattened at the very last moment.
|
105 |
+
|
106 |
+
You need to be aware that the
|
107 |
`For Depth` setting is applied relative to the level at which the first item to be kept is found. For example, say you were to set
|
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**
|
119 |
Output in a single list format, ignoring any parent-child relationship other than to maintain the same physical order as would be
|
120 |
presented in a `Hierarchical` output.
|
121 |
|
122 |
+
* **Include Parent...** *(checkbox)*
|
123 |
|
124 |
If checked, include the parent item in the output. Only applies to a successful `Children of` filter.
|
125 |
|
126 |
+
* **& its Siblings** *(checkbox)* as of v1.1.0
|
127 |
+
|
128 |
+
If checked, include the parent item **and** its siblings in the output. Only applies to a successful `Children of` filter.
|
129 |
+
|
130 |
* **Include Ancestors** *(checkbox)*
|
131 |
|
132 |
Same as `Include Parent` except that all ancestors, right back to root level, are included. Only applies to a successful
|
153 |
* **Hide Widget if Empty** *(checkbox)*
|
154 |
|
155 |
If checked, the widget will not output *any* HTML unless it finds at least one menu item that matches the Filter settings.
|
156 |
+
|
157 |
+
Please note that as of WordPress v3.6, this option becomes superfluous and will **not** be presented (the wp_nav_menu() function
|
158 |
+
has been modified to automatically suppress all HTML output if there are no items to be displayed). The widget will retain
|
159 |
+
the setting used on earlier WP versions (in case reversion from WP v3.6 might be required) but *will not present the option
|
160 |
+
for WP v3.6+*.
|
161 |
|
162 |
* **Container**
|
163 |
|
169 |
|
170 |
* **Unique ID**
|
171 |
|
172 |
+
This allows you to specify your own id (which should be unique) for the container.
|
173 |
|
174 |
* **Class**
|
175 |
|
220 |
|
221 |
== Screenshots ==
|
222 |
|
223 |
+
1. Widget options
|
224 |
+
|
225 |
+
2. More widget options
|
226 |
|
227 |
+
3. Even more widget options
|
228 |
|
229 |
+
4. Demo / Helper
|
230 |
|
231 |
== Changelog ==
|
232 |
|
233 |
+
= 1.1.0 =
|
234 |
+
|
235 |
+
* added 'Current Root Item' and 'Current Parent Item' to the `Children of` filter
|
236 |
+
|
237 |
+
* added `Fallback to Current Item` option, with subsibiary options for overriding a couple of Output options, as a means to enable Current Root & Current Parent to match a Current Item at root level
|
238 |
+
|
239 |
+
* added an Output option to include both the parent item **and** the parent's siblings (for a successful `Children of` filter)
|
240 |
+
|
241 |
+
* added max-width style (100%) to the `Children of` SELECT in the widget options
|
242 |
+
|
243 |
+
* added widget version to the admin js enqueuer
|
244 |
+
|
245 |
+
* ignore/disable Hide Empty option for WP >= v3.6 (wp_nav_menu() now does it automatically)
|
246 |
+
|
247 |
+
* included a stand-alone helper/demo html page
|
248 |
+
|
249 |
+
* rebuilt the `Children of` SELECT in the widget options to cope with IE's lack of OPTGROUP/OPTION styling
|
250 |
+
|
251 |
+
* moved the setting of 'disabled' attributes on INPUTs/SELECTs from PHP into javascript
|
252 |
+
|
253 |
= 1.0.0 =
|
254 |
+
|
255 |
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,
|
262 |
+
with fallbacks for when a Current Item has no ancestor. There is also an additional Output option which extends Include Parent to also
|
263 |
+
include the parent's siblings. An interactive helper/demo page is now available, which will hopefully assist in deciding which options
|
264 |
+
need setting for particular requirements. Other changes include tweaks to the management of the `Children of` SELECT (to allow for IE),
|
265 |
+
a few style enhancements to the presentation of the widget in admin, and removal of the `Hide Widget if Empty` option for WP v3.6 (still
|
266 |
+
presented for WP < 3.6 though!).
|