Version Description
- Provisional WPMU support.
- Missing and unused menu items now get different icons in the menu editor.
- Fixed some visual glitches.
- Items that are not present in the default menu will only be included in the generated menu if their "Custom" flag is set. Makes perfect sense, eh? The takeaway is that you should tick the "Custom" checkbox for the menus you have created manually if you want them to show up.
- You no longer need to manually reload the page to see the changes you made to the menu. Just clicking "Save Changes" is enough.
- Added tooltips to the small flag icons that indicate that a particular menu item is hidden, user-created or otherwise special.
- Updated the readme.txt
Download this release
Release Info
Developer | whiteshadow |
Plugin | Admin Menu Editor |
Version | 0.2 |
Comparing to | |
See all releases |
Code changes from version 0.1.6 to 0.2
- admin-menu-editor-mu.php +43 -0
- images/plugin_add.png +0 -0
- images/plugin_error.png +0 -0
- menu-editor-core.php +115 -83
- menu-editor.css +41 -19
- menu-editor.js +153 -49
- menu-editor.php +1 -1
- readme.txt +30 -14
- shadow_plugin_framework.php +46 -7
admin-menu-editor-mu.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
To install Admin Menu Editor as a global plugin in WPMU :
|
5 |
+
1) Place the "admin-menu-editor" directory into your "mu-plugins" directory.
|
6 |
+
2) Move this file, admin-menu-editor-mu.php, from the "admin-menu-editor" directory
|
7 |
+
to your "mu-plugins" directory.
|
8 |
+
|
9 |
+
The resulting directory structure should look like this :
|
10 |
+
|
11 |
+
mu-plugins/
|
12 |
+
admin-menu-editor-mu.php
|
13 |
+
admin-menu-editor/
|
14 |
+
menu-editor.php
|
15 |
+
menu-editor-core.php
|
16 |
+
...and other Admin Menu Editor files
|
17 |
+
|
18 |
+
**/
|
19 |
+
|
20 |
+
//Load the plugin
|
21 |
+
$ws_menu_editor_filename = dirname(__FILE__) . '/admin-menu-editor/menu-editor.php';
|
22 |
+
if ( file_exists($ws_menu_editor_filename) ) {
|
23 |
+
require $ws_menu_editor_filename;
|
24 |
+
} else {
|
25 |
+
add_action('admin_notices', 'ws_ame_installation_error');
|
26 |
+
}
|
27 |
+
|
28 |
+
function ws_ame_installation_error(){
|
29 |
+
if ( !is_site_admin() ) return;
|
30 |
+
?>
|
31 |
+
<div class="error fade"><p>
|
32 |
+
<strong>Admin Menu Editor is installed incorrectly!</strong>
|
33 |
+
</p>
|
34 |
+
<p>
|
35 |
+
Please copy the entire <code>admin-menu-directory</code> directory to your <code>mu-plugins</code>
|
36 |
+
directory, then move only the admin-menu-editor-mu.php file from
|
37 |
+
<code>admin-menu-editor</code> to <code>mu-plugins</code>.
|
38 |
+
</p>
|
39 |
+
</div>
|
40 |
+
<?php
|
41 |
+
}
|
42 |
+
|
43 |
+
?>
|
images/plugin_add.png
ADDED
Binary file
|
images/plugin_error.png
ADDED
Binary file
|
menu-editor-core.php
CHANGED
@@ -12,20 +12,30 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
12 |
|
13 |
protected $default_wp_menu = null; //Holds the default WP menu for later use in the editor
|
14 |
protected $default_wp_submenu = null; //Holds the default WP menu for later use
|
|
|
|
|
|
|
15 |
|
16 |
function __construct($plugin_file=''){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
//Set some plugin-specific options
|
18 |
$this->option_name = 'ws_menu_editor';
|
19 |
-
$this->defaults = array(
|
20 |
-
);
|
21 |
|
22 |
$this->settings_link = 'options-general.php?page=menu_editor';
|
23 |
-
|
24 |
$this->magic_hooks = true;
|
25 |
$this->magic_hook_priority = 99999;
|
26 |
-
|
27 |
//Call the default constructor
|
28 |
-
if ( empty($plugin_file) ) $plugin_file = __FILE__;
|
29 |
parent::__construct($plugin_file);
|
30 |
|
31 |
//Build some template arrays
|
@@ -38,6 +48,9 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
38 |
'hookname' => null,
|
39 |
'icon_url' => null,
|
40 |
'position' => null,
|
|
|
|
|
|
|
41 |
);
|
42 |
|
43 |
$this->blank_item = array(
|
@@ -46,6 +59,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
46 |
'file' => null,
|
47 |
'page_title' => null,
|
48 |
'position' => null,
|
|
|
49 |
);
|
50 |
|
51 |
}
|
@@ -100,10 +114,14 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
100 |
function hook_admin_menu(){
|
101 |
global $menu, $submenu;
|
102 |
|
103 |
-
|
104 |
-
//
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
107 |
|
108 |
$this->default_wp_menu = $menu;
|
109 |
$this->default_wp_submenu = $submenu;
|
@@ -129,7 +147,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
129 |
*/
|
130 |
function filter_menu(){
|
131 |
global $menu, $submenu, $_wp_submenu_nopriv, $_wp_menu_nopriv;
|
132 |
-
|
133 |
foreach ( array( 'submenu' ) as $sub_loop ) {
|
134 |
foreach ($$sub_loop as $parent => $sub) {
|
135 |
foreach ($sub as $index => $data) {
|
@@ -143,7 +161,6 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
143 |
unset(${$sub_loop}[$parent]);
|
144 |
}
|
145 |
}
|
146 |
-
|
147 |
}
|
148 |
|
149 |
/**
|
@@ -158,10 +175,6 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
158 |
die("Access denied");
|
159 |
}
|
160 |
|
161 |
-
?>
|
162 |
-
<div class="wrap">
|
163 |
-
<h2>Menu Editor</h2>
|
164 |
-
<?php
|
165 |
//Handle form submissions
|
166 |
if (isset($_POST['data'])){
|
167 |
check_admin_referer('menu-editor-form');
|
@@ -169,17 +182,34 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
169 |
//Try to decode a menu tree encoded as JSON
|
170 |
$data = $this->json_decode($_POST['data'], true);
|
171 |
if (!$data){
|
172 |
-
echo "<!-- First decodind attempt failed, trying to fix with stripslashes() -->";
|
173 |
$fixed = stripslashes($_POST['data']);
|
174 |
$data = $this->json_decode( $fixed, true );
|
175 |
}
|
|
|
|
|
176 |
|
177 |
if ($data){
|
178 |
//Save the custom menu
|
179 |
$this->options['custom_menu'] = $data;
|
180 |
$this->save_options();
|
181 |
-
|
|
|
182 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
echo '<div id="message" class="error"><p><strong>Failed to decode input! The menu wasn\'t modified.</strong></p></div>';
|
184 |
}
|
185 |
}
|
@@ -196,7 +226,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
196 |
//Start out with the default menu if there is no user-created one
|
197 |
$custom_menu = $default_menu;
|
198 |
}
|
199 |
-
|
200 |
//Encode both menus as JSON
|
201 |
$default_menu_js = $this->getMenuAsJS($default_menu);
|
202 |
$custom_menu_js = $this->getMenuAsJS($custom_menu);
|
@@ -227,16 +257,16 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
227 |
</div>
|
228 |
</div>
|
229 |
|
230 |
-
<
|
231 |
-
<
|
232 |
<?php wp_nonce_field('menu-editor-form'); ?>
|
233 |
<input type="button" id='ws_save_menu' class="button-primary ws_main_button" value="Save Changes"
|
234 |
style="margin-bottom: 20px;" />
|
235 |
<input type="button" id='ws_load_menu' value="Load default menu" class="button ws_main_button" />
|
236 |
<input type="button" id='ws_reset_menu' value="Reset menu" class="button ws_main_button" />
|
237 |
<input type="hidden" name="data" id="ws_data" value="">
|
238 |
-
</form>
|
239 |
</div>
|
|
|
240 |
|
241 |
</div>
|
242 |
<script type='text/javascript'>
|
@@ -357,7 +387,7 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
357 |
$menu_defaults[$topfile]['used'] = true;
|
358 |
} else {
|
359 |
//Record the menu as missing, unless it's a menu separator
|
360 |
-
if ( empty($topmenu['separator'])
|
361 |
$topmenu['missing'] = true;
|
362 |
}
|
363 |
|
@@ -419,13 +449,7 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
419 |
}
|
420 |
|
421 |
//Resort the tree to ensure the found items are in the right spots
|
422 |
-
|
423 |
-
//Resort all submenus as well
|
424 |
-
foreach ($tree as $topfile => &$topmenu){
|
425 |
-
if (!empty($topmenu['items'])){
|
426 |
-
uasort($topmenu['items'], array(&$this, 'compare_position'));
|
427 |
-
}
|
428 |
-
}
|
429 |
|
430 |
return $tree;
|
431 |
}
|
@@ -442,37 +466,18 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
442 |
$tree = array();
|
443 |
$separator_count = 0;
|
444 |
foreach ($menu as $pos => $item){
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
'css_class' => null,
|
454 |
-
'hookname' => null,
|
455 |
-
'icon_url' => null,
|
456 |
-
'position' => null,
|
457 |
-
'defaults' => $this->menu2assoc($item, $pos),
|
458 |
-
'separator' => true,
|
459 |
-
);
|
460 |
$separator_count++;
|
461 |
-
} else {
|
462 |
-
//No, a normal menu item
|
463 |
-
$tree[$item[2]] = array(
|
464 |
-
'page_title' => null,
|
465 |
-
'menu_title' => null,
|
466 |
-
'access_level' => null,
|
467 |
-
'file' => null,
|
468 |
-
'css_class' => null,
|
469 |
-
'hookname' => null,
|
470 |
-
'icon_url' => null,
|
471 |
-
'position' => null,
|
472 |
-
'items' => array(),
|
473 |
-
'defaults' => $this->menu2assoc($item, $pos),
|
474 |
-
);
|
475 |
}
|
|
|
|
|
476 |
}
|
477 |
|
478 |
//Attach all submenu items
|
@@ -493,6 +498,8 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
493 |
);
|
494 |
}
|
495 |
}
|
|
|
|
|
496 |
|
497 |
return $tree;
|
498 |
}
|
@@ -548,6 +555,26 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
548 |
|
549 |
return $p1 - $p2;
|
550 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
551 |
|
552 |
/**
|
553 |
* WPMenuEditor::tree2wp()
|
@@ -557,16 +584,20 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
557 |
* @return array $menu and $submenu
|
558 |
*/
|
559 |
function tree2wp($tree){
|
|
|
|
|
|
|
560 |
//Sort the menu by position
|
561 |
uasort($tree, array(&$this, 'compare_position'));
|
562 |
|
563 |
//Prepare the top menu
|
564 |
-
$menu = array();
|
565 |
foreach ($tree as &$topmenu){
|
566 |
-
|
567 |
-
//
|
|
|
568 |
//Skip hidden entries
|
569 |
if (!empty($topmenu['hidden'])) continue;
|
|
|
570 |
//Build the WP item structure, using defaults where necessary
|
571 |
$topmenu = $this->apply_defaults($topmenu);
|
572 |
$menu[] = array(
|
@@ -578,31 +609,32 @@ var customMenu = <?php echo $custom_menu_js; ?>;
|
|
578 |
$topmenu['hookname'], //ID
|
579 |
$topmenu['icon_url']
|
580 |
);
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
594 |
}
|
595 |
-
|
596 |
-
$item = $this->apply_defaults($item);
|
597 |
-
$submenu[$x['file']][] = array(
|
598 |
-
$item['menu_title'],
|
599 |
-
$item['access_level'],
|
600 |
-
$item['file'],
|
601 |
-
$item['page_title'],
|
602 |
-
);
|
603 |
}
|
604 |
}
|
605 |
-
|
606 |
return array($menu, $submenu);
|
607 |
}
|
608 |
|
12 |
|
13 |
protected $default_wp_menu = null; //Holds the default WP menu for later use in the editor
|
14 |
protected $default_wp_submenu = null; //Holds the default WP menu for later use
|
15 |
+
|
16 |
+
private $blank_menu = null;
|
17 |
+
private $blank_item = null;
|
18 |
|
19 |
function __construct($plugin_file=''){
|
20 |
+
if ( empty($plugin_file) ) $plugin_file = __FILE__;
|
21 |
+
|
22 |
+
//Determine if the plugin is installed in the mu-plugins directory
|
23 |
+
$this->is_mu_plugin = $this->is_in_wpmu_plugin_dir($plugin_file);
|
24 |
+
//If so, we'll store the custom menu in a site-wide option
|
25 |
+
if ( $this->is_mu_plugin ){
|
26 |
+
$this->sitewide_options = true;
|
27 |
+
}
|
28 |
+
|
29 |
//Set some plugin-specific options
|
30 |
$this->option_name = 'ws_menu_editor';
|
31 |
+
$this->defaults = array();
|
|
|
32 |
|
33 |
$this->settings_link = 'options-general.php?page=menu_editor';
|
34 |
+
|
35 |
$this->magic_hooks = true;
|
36 |
$this->magic_hook_priority = 99999;
|
37 |
+
|
38 |
//Call the default constructor
|
|
|
39 |
parent::__construct($plugin_file);
|
40 |
|
41 |
//Build some template arrays
|
48 |
'hookname' => null,
|
49 |
'icon_url' => null,
|
50 |
'position' => null,
|
51 |
+
'defaults' => null,
|
52 |
+
'separator' => null,
|
53 |
+
'custom' => null,
|
54 |
);
|
55 |
|
56 |
$this->blank_item = array(
|
59 |
'file' => null,
|
60 |
'page_title' => null,
|
61 |
'position' => null,
|
62 |
+
'custom' => null,
|
63 |
);
|
64 |
|
65 |
}
|
114 |
function hook_admin_menu(){
|
115 |
global $menu, $submenu;
|
116 |
|
117 |
+
//The menu editor is only visible to users with the manage_options privilege.
|
118 |
+
//Or, if the plugin is installed in mu-plugins, only to the site administrator(s).
|
119 |
+
if ( !$this->is_mu_plugin || ( function_exists('is_site_admin') && is_site_admin() ) ){
|
120 |
+
$page = add_options_page('Menu Editor', 'Menu Editor', 'manage_options', 'menu_editor', array(&$this, 'page_menu_editor'));
|
121 |
+
//Output our JS & CSS on that page only
|
122 |
+
add_action("admin_print_scripts-$page", array(&$this, 'enqueue_scripts'));
|
123 |
+
add_action("admin_print_scripts-$page", array(&$this, 'print_editor_css'));
|
124 |
+
}
|
125 |
|
126 |
$this->default_wp_menu = $menu;
|
127 |
$this->default_wp_submenu = $submenu;
|
147 |
*/
|
148 |
function filter_menu(){
|
149 |
global $menu, $submenu, $_wp_submenu_nopriv, $_wp_menu_nopriv;
|
150 |
+
|
151 |
foreach ( array( 'submenu' ) as $sub_loop ) {
|
152 |
foreach ($$sub_loop as $parent => $sub) {
|
153 |
foreach ($sub as $index => $data) {
|
161 |
unset(${$sub_loop}[$parent]);
|
162 |
}
|
163 |
}
|
|
|
164 |
}
|
165 |
|
166 |
/**
|
175 |
die("Access denied");
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
178 |
//Handle form submissions
|
179 |
if (isset($_POST['data'])){
|
180 |
check_admin_referer('menu-editor-form');
|
182 |
//Try to decode a menu tree encoded as JSON
|
183 |
$data = $this->json_decode($_POST['data'], true);
|
184 |
if (!$data){
|
|
|
185 |
$fixed = stripslashes($_POST['data']);
|
186 |
$data = $this->json_decode( $fixed, true );
|
187 |
}
|
188 |
+
|
189 |
+
$url = remove_query_arg('noheader');
|
190 |
|
191 |
if ($data){
|
192 |
//Save the custom menu
|
193 |
$this->options['custom_menu'] = $data;
|
194 |
$this->save_options();
|
195 |
+
//Redirect back to the editor and display the success message
|
196 |
+
wp_redirect( add_query_arg('message', 1, $url) );
|
197 |
} else {
|
198 |
+
//Or redirect & display the error message
|
199 |
+
wp_redirect( add_query_arg('message', 2, $url) );
|
200 |
+
}
|
201 |
+
die();
|
202 |
+
}
|
203 |
+
|
204 |
+
?>
|
205 |
+
<div class="wrap">
|
206 |
+
<h2>Menu Editor</h2>
|
207 |
+
<?php
|
208 |
+
|
209 |
+
if ( !empty($_GET['message']) ){
|
210 |
+
if ( intval($_GET['message']) == 1 ){
|
211 |
+
echo '<div id="message" class="updated fade"><p><strong>Settings saved.</strong></p></div>';
|
212 |
+
} elseif ( intval($_GET['message']) == 2 ) {
|
213 |
echo '<div id="message" class="error"><p><strong>Failed to decode input! The menu wasn\'t modified.</strong></p></div>';
|
214 |
}
|
215 |
}
|
226 |
//Start out with the default menu if there is no user-created one
|
227 |
$custom_menu = $default_menu;
|
228 |
}
|
229 |
+
|
230 |
//Encode both menus as JSON
|
231 |
$default_menu_js = $this->getMenuAsJS($default_menu);
|
232 |
$custom_menu_js = $this->getMenuAsJS($custom_menu);
|
257 |
</div>
|
258 |
</div>
|
259 |
|
260 |
+
<form method="post" action="<?php echo admin_url('options-general.php?page=menu_editor&noheader=1'); ?>" id='ws_main_form' name='ws_main_form'>
|
261 |
+
<div class="ws_main_container" style="width: 138px;">
|
262 |
<?php wp_nonce_field('menu-editor-form'); ?>
|
263 |
<input type="button" id='ws_save_menu' class="button-primary ws_main_button" value="Save Changes"
|
264 |
style="margin-bottom: 20px;" />
|
265 |
<input type="button" id='ws_load_menu' value="Load default menu" class="button ws_main_button" />
|
266 |
<input type="button" id='ws_reset_menu' value="Reset menu" class="button ws_main_button" />
|
267 |
<input type="hidden" name="data" id="ws_data" value="">
|
|
|
268 |
</div>
|
269 |
+
</form>
|
270 |
|
271 |
</div>
|
272 |
<script type='text/javascript'>
|
387 |
$menu_defaults[$topfile]['used'] = true;
|
388 |
} else {
|
389 |
//Record the menu as missing, unless it's a menu separator
|
390 |
+
if ( empty($topmenu['separator']) )
|
391 |
$topmenu['missing'] = true;
|
392 |
}
|
393 |
|
449 |
}
|
450 |
|
451 |
//Resort the tree to ensure the found items are in the right spots
|
452 |
+
$tree = $this->sort_menu_tree($tree);
|
|
|
|
|
|
|
|
|
|
|
|
|
453 |
|
454 |
return $tree;
|
455 |
}
|
466 |
$tree = array();
|
467 |
$separator_count = 0;
|
468 |
foreach ($menu as $pos => $item){
|
469 |
+
|
470 |
+
$tree_item = $this->blank_menu;
|
471 |
+
$tree_item['defaults'] = $this->menu2assoc($item, $pos);
|
472 |
+
$tree_item['separator'] = empty($item[2]) || empty($item[0]);
|
473 |
+
|
474 |
+
$item_file = $tree_item['defaults']['file'];
|
475 |
+
if ( empty($item_file) ){
|
476 |
+
$item_file = 'separator_'.$separator_count.'_';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
477 |
$separator_count++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
478 |
}
|
479 |
+
|
480 |
+
$tree[$item_file] = $tree_item;
|
481 |
}
|
482 |
|
483 |
//Attach all submenu items
|
498 |
);
|
499 |
}
|
500 |
}
|
501 |
+
|
502 |
+
$tree = $this->sort_menu_tree($tree);
|
503 |
|
504 |
return $tree;
|
505 |
}
|
555 |
|
556 |
return $p1 - $p2;
|
557 |
}
|
558 |
+
|
559 |
+
/**
|
560 |
+
* WPMenuEditor::sort_menu_tree()
|
561 |
+
* Sort the menus and menu items of a given menu according to their positions
|
562 |
+
*
|
563 |
+
* @param array $tree A menu structure in the internal format
|
564 |
+
* @return array Sorted menu in the internal format
|
565 |
+
*/
|
566 |
+
function sort_menu_tree($tree){
|
567 |
+
//Resort the tree to ensure the found items are in the right spots
|
568 |
+
uasort($tree, array(&$this, 'compare_position'));
|
569 |
+
//Resort all submenus as well
|
570 |
+
foreach ($tree as $topfile => &$topmenu){
|
571 |
+
if (!empty($topmenu['items'])){
|
572 |
+
uasort($topmenu['items'], array(&$this, 'compare_position'));
|
573 |
+
}
|
574 |
+
}
|
575 |
+
|
576 |
+
return $tree;
|
577 |
+
}
|
578 |
|
579 |
/**
|
580 |
* WPMenuEditor::tree2wp()
|
584 |
* @return array $menu and $submenu
|
585 |
*/
|
586 |
function tree2wp($tree){
|
587 |
+
$menu = array();
|
588 |
+
$submenu = array();
|
589 |
+
|
590 |
//Sort the menu by position
|
591 |
uasort($tree, array(&$this, 'compare_position'));
|
592 |
|
593 |
//Prepare the top menu
|
|
|
594 |
foreach ($tree as &$topmenu){
|
595 |
+
|
596 |
+
//Skip missing menus, unless they're user-created and thus might point to a non-standard file
|
597 |
+
if ( !empty($topmenu['missing']) && empty($topmenu['custom']) ) continue;
|
598 |
//Skip hidden entries
|
599 |
if (!empty($topmenu['hidden'])) continue;
|
600 |
+
|
601 |
//Build the WP item structure, using defaults where necessary
|
602 |
$topmenu = $this->apply_defaults($topmenu);
|
603 |
$menu[] = array(
|
609 |
$topmenu['hookname'], //ID
|
610 |
$topmenu['icon_url']
|
611 |
);
|
612 |
+
|
613 |
+
//Prepare the submenu of this menu
|
614 |
+
if( !empty($topmenu['items']) ){
|
615 |
+
$items = $topmenu['items'];
|
616 |
+
//Sort by position
|
617 |
+
uasort($items, array(&$this, 'compare_position'));
|
618 |
+
foreach ($items as $item) {
|
619 |
+
|
620 |
+
//Skip missing items, unless they're user-created
|
621 |
+
if ( !empty($item['missing']) && empty($item['custom']) ) continue;
|
622 |
+
//Skip hidden items
|
623 |
+
if (!empty($item['hidden'])) {
|
624 |
+
continue;
|
625 |
+
}
|
626 |
+
|
627 |
+
$item = $this->apply_defaults($item);
|
628 |
+
$submenu[$topmenu['file']][] = array(
|
629 |
+
$item['menu_title'],
|
630 |
+
$item['access_level'],
|
631 |
+
$item['file'],
|
632 |
+
$item['page_title'],
|
633 |
+
);
|
634 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
635 |
}
|
636 |
}
|
637 |
+
|
638 |
return array($menu, $submenu);
|
639 |
}
|
640 |
|
menu-editor.css
CHANGED
@@ -12,10 +12,12 @@
|
|
12 |
|
13 |
.ws_main_button {
|
14 |
clear: both;
|
15 |
-
display:block;
|
16 |
-
width: 120px;
|
17 |
margin: 4px;
|
18 |
-
|
|
|
|
|
|
|
19 |
}
|
20 |
|
21 |
.ws_container {
|
@@ -87,30 +89,50 @@ a.ws_edit_link:hover {
|
|
87 |
background-position: center;
|
88 |
}
|
89 |
|
90 |
-
/*
|
91 |
-
.
|
92 |
-
|
93 |
-
|
94 |
-
background-position: 232px 5px;
|
95 |
}
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
|
|
|
|
|
|
|
100 |
background-repeat: no-repeat;
|
101 |
-
background-position: 232px 5px;
|
102 |
}
|
103 |
|
104 |
-
/*
|
105 |
-
.
|
106 |
-
background-image: url('images/
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
}
|
110 |
|
111 |
-
|
|
|
|
|
112 |
}
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
.ws_editbox {
|
115 |
display: block;
|
116 |
background-color: #ffffd0;
|
@@ -124,7 +146,7 @@ a.ws_edit_link:hover {
|
|
124 |
cursor: pointer;
|
125 |
}
|
126 |
|
127 |
-
.ws_editbox input {
|
128 |
width: 220px;
|
129 |
}
|
130 |
|
12 |
|
13 |
.ws_main_button {
|
14 |
clear: both;
|
15 |
+
display: block;
|
|
|
16 |
margin: 4px;
|
17 |
+
margin-left: auto;
|
18 |
+
margin-right: auto;
|
19 |
+
width: 120px;
|
20 |
+
padding: 4px !important;
|
21 |
}
|
22 |
|
23 |
.ws_container {
|
89 |
background-position: center;
|
90 |
}
|
91 |
|
92 |
+
/* Menu/menu item flags */
|
93 |
+
.ws_flag_container {
|
94 |
+
float: right;
|
95 |
+
margin-right: 4px;
|
|
|
96 |
}
|
97 |
|
98 |
+
.ws_flag {
|
99 |
+
display: block;
|
100 |
+
float: right;
|
101 |
+
width: 16px;
|
102 |
+
height: 16px;
|
103 |
+
margin-left: 4px;
|
104 |
background-repeat: no-repeat;
|
|
|
105 |
}
|
106 |
|
107 |
+
/* user-created items */
|
108 |
+
.ws_custom_item_flag {
|
109 |
+
background-image: url('images/page_white_add.png');
|
110 |
+
}
|
111 |
+
|
112 |
+
/* items not present in the default menu */
|
113 |
+
.ws_missing_flag {
|
114 |
+
background-image: url('images/plugin_error.png');
|
115 |
+
}
|
116 |
+
|
117 |
+
/* unused items - those that are in the default menu but not in the custom one */
|
118 |
+
.ws_unused_flag {
|
119 |
+
background-image: url('images/plugin_add.png');
|
120 |
}
|
121 |
|
122 |
+
/* hidden items */
|
123 |
+
.ws_hidden_flag {
|
124 |
+
background-image: url('images/plugin_disabled.png');
|
125 |
}
|
126 |
|
127 |
+
/* These classes could be used to apply different styles to items depending on their flags */
|
128 |
+
.ws_missing { }
|
129 |
+
.ws_custom_item { }
|
130 |
+
.ws_hidden { }
|
131 |
+
.ws_unused { }
|
132 |
+
|
133 |
+
|
134 |
+
.ws_item { }
|
135 |
+
|
136 |
.ws_editbox {
|
137 |
display: block;
|
138 |
background-color: #ffffd0;
|
146 |
cursor: pointer;
|
147 |
}
|
148 |
|
149 |
+
.ws_editbox input[type="text"] {
|
150 |
width: 220px;
|
151 |
}
|
152 |
|
menu-editor.js
CHANGED
@@ -54,8 +54,6 @@ function outputWpMenu(menu){
|
|
54 |
}
|
55 |
});
|
56 |
|
57 |
-
|
58 |
-
|
59 |
//The "Default" button : Reset to default value when clicked
|
60 |
$('.ws_reset_button').click(function () {
|
61 |
//Find the related input field
|
@@ -80,32 +78,34 @@ function outputWpMenu(menu){
|
|
80 |
$(this).parent().parent().parent().find('.ws_item_title').html($(this).val()+' ');
|
81 |
}
|
82 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
}
|
84 |
|
85 |
function outputTopMenu(menu, filename, ind){
|
86 |
id = 'topmenu-'+ind;
|
87 |
submenu_id = 'submenu-'+ind;
|
88 |
|
89 |
-
//menu = menu_obj[filename];
|
90 |
-
|
91 |
var subclass = '';
|
92 |
-
|
93 |
-
if ( menu.separator /*(!menu.defaults.menu_title) && (!menu.menu_title)*/ ) {
|
94 |
subclass = subclass + ' ws_menu_separator';
|
95 |
}
|
96 |
-
if (menu.missing) {
|
97 |
-
subclass = subclass + ' ws_missing';
|
98 |
-
}
|
99 |
-
if (menu.hidden) {
|
100 |
-
subclass = subclass + ' ws_hidden';
|
101 |
-
}
|
102 |
-
if (menu.unused) {
|
103 |
-
subclass = subclass + ' ws_unused';
|
104 |
-
}
|
105 |
|
|
|
106 |
var s = '<div id="'+id+'" class="ws_container ws_menu '+subclass+'" submenu_id="'+submenu_id+'">'+
|
107 |
'<div class="ws_item_head">'+
|
108 |
'<a class="ws_edit_link"> </a>'+
|
|
|
109 |
'<span class="ws_item_title">'+
|
110 |
((menu.menu_title!=null)?menu.menu_title:menu.defaults.menu_title)+
|
111 |
' </span>'+
|
@@ -113,7 +113,22 @@ function outputTopMenu(menu, filename, ind){
|
|
113 |
'<div class="ws_editbox" style="display: none;">'+buildEditboxFields(menu)+'</div>'+
|
114 |
'</div>';
|
115 |
|
116 |
-
$('#ws_menu_box')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
//Create a container for menu items, even if there are none
|
118 |
$('#ws_submenu_box').append('<div class="ws_submenu" id="'+submenu_id+'" style="display:none;"></div>');
|
119 |
|
@@ -131,27 +146,32 @@ function outputTopMenu(menu, filename, ind){
|
|
131 |
function outputMenuEntry(entry, ind, parent){
|
132 |
if (!entry.defaults) return;
|
133 |
|
134 |
-
var
|
135 |
-
|
136 |
-
|
137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
}
|
139 |
if (entry.hidden) {
|
140 |
-
|
141 |
}
|
142 |
if (entry.unused) {
|
143 |
-
|
|
|
|
|
|
|
144 |
}
|
145 |
-
|
146 |
-
var item = $('#'+parent).append('<div class="ws_container ws_item '+subclass+'">'+
|
147 |
-
'<div class="ws_item_head">'+
|
148 |
-
'<a class="ws_edit_link"> </a>'+
|
149 |
-
'<span class="ws_item_title">'+
|
150 |
-
((entry.menu_title!=null)?entry.menu_title:entry.defaults.menu_title)+
|
151 |
-
' </span>'+
|
152 |
-
'</div>'+
|
153 |
-
'<div class="ws_editbox" style="display:none;">'+buildEditboxFields(entry)+'</div>'+
|
154 |
-
'<div>');
|
155 |
}
|
156 |
|
157 |
function buildEditboxField(entry, field_name, field_caption){
|
@@ -181,6 +201,19 @@ function buildEditboxFields(entry){
|
|
181 |
for (var field_name in fields){
|
182 |
s = s + buildEditboxField(entry, field_name, fields[field_name]);
|
183 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
return s;
|
185 |
}
|
186 |
|
@@ -202,9 +235,11 @@ function encodeMenuAsJSON(){
|
|
202 |
|
203 |
var filename = $(this).find('.ws_edit_field[field_name="file"] input').val();
|
204 |
//Check if this is a separator
|
205 |
-
if (
|
206 |
-
filename = 'separator_'+separator_count+'_';
|
207 |
menu_obj.separator = true;
|
|
|
|
|
|
|
208 |
separator_count++;
|
209 |
}
|
210 |
|
@@ -226,10 +261,10 @@ function encodeMenuAsJSON(){
|
|
226 |
|
227 |
});
|
228 |
//Check if the menu is hidden
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
menu_obj.items = {};
|
234 |
|
235 |
var item_position = 0;
|
@@ -267,6 +302,9 @@ function encodeMenuAsJSON(){
|
|
267 |
if ($(this).hasClass('ws_hidden')){
|
268 |
item.hidden = true;
|
269 |
}
|
|
|
|
|
|
|
270 |
//Save the item in the parent menu
|
271 |
menu_obj.items[filename] = item;
|
272 |
});
|
@@ -280,6 +318,58 @@ function encodeMenuAsJSON(){
|
|
280 |
return $.toJSON(data);
|
281 |
}
|
282 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
var menu_in_clipboard = null;
|
284 |
var submenu_in_clipboard = null;
|
285 |
var item_in_clipboard = null;
|
@@ -304,13 +394,19 @@ $(document).ready(function(){
|
|
304 |
var selection = $('#ws_menu_box .ws_active');
|
305 |
if (!selection.length) return;
|
306 |
|
307 |
-
//Mark the menu as hidden
|
308 |
-
selection.toggleClass('ws_hidden');
|
|
|
|
|
309 |
//Also mark all of it's submenus as hidden/visible
|
310 |
-
if (selection
|
311 |
-
$('#' + selection.attr('submenu_id') + ' .ws_item').
|
|
|
|
|
312 |
} else {
|
313 |
-
$('#' + selection.attr('submenu_id') + ' .ws_item').
|
|
|
|
|
314 |
}
|
315 |
});
|
316 |
|
@@ -422,9 +518,13 @@ $(document).ready(function(){
|
|
422 |
dropOnEmpty: true,
|
423 |
});
|
424 |
|
425 |
-
//
|
426 |
-
menu.attr('class','ws_container ws_menu
|
|
|
|
|
427 |
|
|
|
|
|
428 |
|
429 |
var temp_id = 'custom_menu_'+ws_paste_count;
|
430 |
//Assign a stub title
|
@@ -459,7 +559,7 @@ $(document).ready(function(){
|
|
459 |
if (!selection.length) return;
|
460 |
|
461 |
//Mark the item as hidden
|
462 |
-
selection
|
463 |
});
|
464 |
|
465 |
//Delete menu
|
@@ -532,8 +632,13 @@ $(document).ready(function(){
|
|
532 |
//Clone another item to use as a template (hack)
|
533 |
var menu = $('#ws_submenu_box .ws_item:first').clone(true);
|
534 |
|
535 |
-
//Cleanup the items's classes
|
536 |
-
menu.attr('class','ws_container ws_item
|
|
|
|
|
|
|
|
|
|
|
537 |
|
538 |
var temp_id = 'custom_item_'+ws_paste_count;
|
539 |
//Assign a stub title
|
@@ -581,6 +686,5 @@ $(document).ready(function(){
|
|
581 |
});
|
582 |
|
583 |
});
|
584 |
-
|
585 |
|
586 |
})(jQuery);
|
54 |
}
|
55 |
});
|
56 |
|
|
|
|
|
57 |
//The "Default" button : Reset to default value when clicked
|
58 |
$('.ws_reset_button').click(function () {
|
59 |
//Find the related input field
|
78 |
$(this).parent().parent().parent().find('.ws_item_title').html($(this).val()+' ');
|
79 |
}
|
80 |
});
|
81 |
+
|
82 |
+
//When the "Custom" checkbox is clicked, add/remove the ws_custom_item class to
|
83 |
+
//the menu (or menu item) in question.
|
84 |
+
$('.ws_custom_toggle').change(function(){
|
85 |
+
//Find the container
|
86 |
+
var my_container = $(this).parents('.ws_container:first');
|
87 |
+
if ( $(this).is(':checked') ){
|
88 |
+
addMenuFlag(my_container, 'custom_item');
|
89 |
+
} else {
|
90 |
+
removeMenuFlag(my_container, 'custom_item');
|
91 |
+
}
|
92 |
+
});
|
93 |
}
|
94 |
|
95 |
function outputTopMenu(menu, filename, ind){
|
96 |
id = 'topmenu-'+ind;
|
97 |
submenu_id = 'submenu-'+ind;
|
98 |
|
|
|
|
|
99 |
var subclass = '';
|
100 |
+
if ( menu.separator ) {
|
|
|
101 |
subclass = subclass + ' ws_menu_separator';
|
102 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
+
//Create the menu HTML
|
105 |
var s = '<div id="'+id+'" class="ws_container ws_menu '+subclass+'" submenu_id="'+submenu_id+'">'+
|
106 |
'<div class="ws_item_head">'+
|
107 |
'<a class="ws_edit_link"> </a>'+
|
108 |
+
'<div class="ws_flag_container"> </div>'+
|
109 |
'<span class="ws_item_title">'+
|
110 |
((menu.menu_title!=null)?menu.menu_title:menu.defaults.menu_title)+
|
111 |
' </span>'+
|
113 |
'<div class="ws_editbox" style="display: none;">'+buildEditboxFields(menu)+'</div>'+
|
114 |
'</div>';
|
115 |
|
116 |
+
var menu_obj = $(s).appendTo('#ws_menu_box');
|
117 |
+
|
118 |
+
//Apply flags based on the item's state
|
119 |
+
if (menu.missing && !menu.custom) {
|
120 |
+
addMenuFlag(menu_obj, 'missing');
|
121 |
+
}
|
122 |
+
if (menu.hidden) {
|
123 |
+
addMenuFlag(menu_obj, 'hidden');
|
124 |
+
}
|
125 |
+
if (menu.unused) {
|
126 |
+
addMenuFlag(menu_obj, 'unused');
|
127 |
+
}
|
128 |
+
if (menu.custom) {
|
129 |
+
addMenuFlag(menu_obj, 'custom_item');
|
130 |
+
}
|
131 |
+
|
132 |
//Create a container for menu items, even if there are none
|
133 |
$('#ws_submenu_box').append('<div class="ws_submenu" id="'+submenu_id+'" style="display:none;"></div>');
|
134 |
|
146 |
function outputMenuEntry(entry, ind, parent){
|
147 |
if (!entry.defaults) return;
|
148 |
|
149 |
+
var item = $(
|
150 |
+
'<div class="ws_container ws_item">'+
|
151 |
+
'<div class="ws_item_head">'+
|
152 |
+
'<a class="ws_edit_link"> </a>'+
|
153 |
+
'<div class="ws_flag_container"> </div>'+
|
154 |
+
'<span class="ws_item_title">'+
|
155 |
+
((entry.menu_title!=null)?entry.menu_title:entry.defaults.menu_title)+
|
156 |
+
' </span>'+
|
157 |
+
'</div>'+
|
158 |
+
'<div class="ws_editbox" style="display:none;">'+buildEditboxFields(entry)+'</div>'+
|
159 |
+
'<div>'
|
160 |
+
).appendTo('#'+parent)
|
161 |
+
|
162 |
+
//Apply flags based on the item's state
|
163 |
+
if (entry.missing && !entry.custom) {
|
164 |
+
addMenuFlag(item, 'missing');
|
165 |
}
|
166 |
if (entry.hidden) {
|
167 |
+
addMenuFlag(item, 'hidden');
|
168 |
}
|
169 |
if (entry.unused) {
|
170 |
+
addMenuFlag(item, 'unused');
|
171 |
+
}
|
172 |
+
if (entry.custom) {
|
173 |
+
addMenuFlag(item, 'custom_item');
|
174 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
176 |
|
177 |
function buildEditboxField(entry, field_name, field_caption){
|
201 |
for (var field_name in fields){
|
202 |
s = s + buildEditboxField(entry, field_name, fields[field_name]);
|
203 |
}
|
204 |
+
|
205 |
+
//Add the "Custom item" checkbox
|
206 |
+
var is_custom = false;
|
207 |
+
if ( typeof(entry['custom']) != 'undefined' ){
|
208 |
+
is_custom = entry['custom'];
|
209 |
+
}
|
210 |
+
s = s +
|
211 |
+
'<div class="ws_edit_field">'+
|
212 |
+
'<label title="Custom items are visible even if they\'re not present in the default WordPress menu">'+
|
213 |
+
'<input type="checkbox" class="ws_custom_toggle"'+
|
214 |
+
(is_custom?' checked="checked"':'')+ '> Custom</label>'+
|
215 |
+
'</div>';
|
216 |
+
|
217 |
return s;
|
218 |
}
|
219 |
|
235 |
|
236 |
var filename = $(this).find('.ws_edit_field[field_name="file"] input').val();
|
237 |
//Check if this is a separator
|
238 |
+
if ( $(this).hasClass('ws_menu_separator') ){
|
|
|
239 |
menu_obj.separator = true;
|
240 |
+
if ( filename=='' ) {
|
241 |
+
filename = 'separator_'+separator_count+'_';
|
242 |
+
}
|
243 |
separator_count++;
|
244 |
}
|
245 |
|
261 |
|
262 |
});
|
263 |
//Check if the menu is hidden
|
264 |
+
menu_obj.hidden = $(this).hasClass('ws_hidden');
|
265 |
+
//Check if this is a custom menu
|
266 |
+
menu_obj.custom = $(this).hasClass('ws_custom_item');
|
267 |
+
|
268 |
menu_obj.items = {};
|
269 |
|
270 |
var item_position = 0;
|
302 |
if ($(this).hasClass('ws_hidden')){
|
303 |
item.hidden = true;
|
304 |
}
|
305 |
+
//Check if this is a custom item
|
306 |
+
item.custom = $(this).hasClass('ws_custom_item');
|
307 |
+
|
308 |
//Save the item in the parent menu
|
309 |
menu_obj.items[filename] = item;
|
310 |
});
|
318 |
return $.toJSON(data);
|
319 |
}
|
320 |
|
321 |
+
var item_flags = {
|
322 |
+
'custom_item' : 'This is a custom menu item',
|
323 |
+
'unused' : 'This item was automatically (re)inserted into your custom menu because it is present in the default WordPress menu',
|
324 |
+
'missing' : 'This item is not present in the default WordPress menu. Tick the "Custom" checkbox if you want it to be visible anyway.',
|
325 |
+
'hidden' : 'This item is hidden'
|
326 |
+
}
|
327 |
+
|
328 |
+
//These function manipulate the menu flags (e.g. hidden, custom, etc)
|
329 |
+
function addMenuFlag(item, flag){
|
330 |
+
item = $(item);
|
331 |
+
|
332 |
+
var item_class = 'ws_' + flag;
|
333 |
+
var img_class = 'ws_' + flag + '_flag';
|
334 |
+
|
335 |
+
item.addClass(item_class);
|
336 |
+
//Add the flag image
|
337 |
+
var flag_container = item.find('.ws_flag_container');
|
338 |
+
if ( flag_container.find('.' + img_class).length == 0 ){
|
339 |
+
flag_container.append('<div class="ws_flag '+img_class+'" title="'+item_flags[flag]+'"></div>');
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
function removeMenuFlag(item, flag){
|
344 |
+
item = $(item);
|
345 |
+
var item_class = 'ws_' + flag;
|
346 |
+
var img_class = 'ws_' + flag + '_flag';
|
347 |
+
|
348 |
+
item.removeClass('ws_' + flag);
|
349 |
+
item.find('.' + img_class).remove();
|
350 |
+
}
|
351 |
+
|
352 |
+
function toggleMenuFlag(item, flag){
|
353 |
+
if (menuHasFlag(item, flag)){
|
354 |
+
removeMenuFlag(item, flag);
|
355 |
+
} else {
|
356 |
+
addMenuFlag(item, flag);
|
357 |
+
}
|
358 |
+
}
|
359 |
+
|
360 |
+
function menuHasFlag(item, flag){
|
361 |
+
return $(item).hasClass('ws_'+flag);
|
362 |
+
}
|
363 |
+
|
364 |
+
function clearMenuFlags(item){
|
365 |
+
item = $(item);
|
366 |
+
item.find('.ws_flag').remove();
|
367 |
+
for(var flag in item_flags){
|
368 |
+
item.removeClass('ws_'+flag);
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
//Cut & paste stuff
|
373 |
var menu_in_clipboard = null;
|
374 |
var submenu_in_clipboard = null;
|
375 |
var item_in_clipboard = null;
|
394 |
var selection = $('#ws_menu_box .ws_active');
|
395 |
if (!selection.length) return;
|
396 |
|
397 |
+
//Mark the menu as hidden/visible
|
398 |
+
//selection.toggleClass('ws_hidden');
|
399 |
+
toggleMenuFlag(selection, 'hidden');
|
400 |
+
|
401 |
//Also mark all of it's submenus as hidden/visible
|
402 |
+
if ( menuHasFlag(selection,'hidden') ){
|
403 |
+
$('#' + selection.attr('submenu_id') + ' .ws_item').each(function(){
|
404 |
+
addMenuFlag(this, 'hidden');
|
405 |
+
});
|
406 |
} else {
|
407 |
+
$('#' + selection.attr('submenu_id') + ' .ws_item').each(function(){
|
408 |
+
removeMenuFlag(this, 'hidden');
|
409 |
+
});
|
410 |
}
|
411 |
});
|
412 |
|
518 |
dropOnEmpty: true,
|
519 |
});
|
520 |
|
521 |
+
//Clean up the menu's flags & classes
|
522 |
+
menu.attr('class','ws_container ws_menu');
|
523 |
+
clearMenuFlags(menu);
|
524 |
+
addMenuFlag(menu, 'custom_item');
|
525 |
|
526 |
+
//Check the "Custom" checkbox
|
527 |
+
menu.find('.ws_custom_toggle').attr('checked', 'checked');
|
528 |
|
529 |
var temp_id = 'custom_menu_'+ws_paste_count;
|
530 |
//Assign a stub title
|
559 |
if (!selection.length) return;
|
560 |
|
561 |
//Mark the item as hidden
|
562 |
+
toggleMenuFlag(selection, 'hidden');
|
563 |
});
|
564 |
|
565 |
//Delete menu
|
632 |
//Clone another item to use as a template (hack)
|
633 |
var menu = $('#ws_submenu_box .ws_item:first').clone(true);
|
634 |
|
635 |
+
//Cleanup the items's flags & classes
|
636 |
+
menu.attr('class','ws_container ws_item');
|
637 |
+
clearMenuFlags(menu);
|
638 |
+
addMenuFlag(menu, 'custom_item');
|
639 |
+
|
640 |
+
//Check the "Custom" checkbox
|
641 |
+
menu.find('.ws_custom_toggle').attr('checked', 'checked');
|
642 |
|
643 |
var temp_id = 'custom_item_'+ws_paste_count;
|
644 |
//Assign a stub title
|
686 |
});
|
687 |
|
688 |
});
|
|
|
689 |
|
690 |
})(jQuery);
|
menu-editor.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Admin Menu Editor
|
4 |
Plugin URI: http://w-shadow.com/blog/2008/12/20/admin-menu-editor-for-wordpress/
|
5 |
Description: Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
|
6 |
-
Version: 0.
|
7 |
Author: Janis Elsts
|
8 |
Author URI: http://w-shadow.com/blog/
|
9 |
*/
|
3 |
Plugin Name: Admin Menu Editor
|
4 |
Plugin URI: http://w-shadow.com/blog/2008/12/20/admin-menu-editor-for-wordpress/
|
5 |
Description: Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
|
6 |
+
Version: 0.2
|
7 |
Author: Janis Elsts
|
8 |
Author URI: http://w-shadow.com/blog/
|
9 |
*/
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== Admin Menu Editor ===
|
2 |
Contributors: whiteshadow
|
3 |
Donate link: http://w-shadow.com/
|
4 |
-
Tags: admin, dashboard, menu, security
|
5 |
Requires at least: 2.7.0
|
6 |
-
Tested up to: 2.9
|
7 |
-
Stable tag: 0.
|
8 |
|
9 |
Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
|
10 |
|
@@ -19,35 +19,51 @@ Admin Menu Editor lets you manually edit the Dashboard menu. You can reorder the
|
|
19 |
* Hide/show any menu or menu item. A hidden menu is invisible to all users, including administrators.
|
20 |
* Create custom menus that point to any part of the Dashboard. For example, you could create a new menu leading directly to the "Pending comments" page.
|
21 |
|
|
|
|
|
22 |
**Known Issues**
|
23 |
|
24 |
-
* If you delete any of the default menus they will reappear after saving. This is by design.
|
25 |
-
*
|
26 |
-
* A plugin's menu that is moved to a different submenu will not work unless you also include the parent file in the "File" field.
|
27 |
|
28 |
== Installation ==
|
29 |
|
30 |
-
|
31 |
|
32 |
1. Download the admin-menu-editor.zip file to your local machine.
|
33 |
-
1. Unzip the file
|
34 |
-
1. Upload `admin-menu-editor`
|
35 |
1. Activate the plugin through the 'Plugins' menu in WordPress.
|
36 |
|
37 |
That's it. You can access the the menu editor by going to *Settings -> Menu Editor*. The plugin will automatically load your current menu configuration the first time you run it.
|
38 |
|
39 |
-
|
|
|
|
|
40 |
|
41 |
-
1.
|
42 |
-
1.
|
43 |
-
1.
|
|
|
|
|
|
|
44 |
|
45 |
== Changelog ==
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
= 0.1.6 =
|
48 |
* Fixed a conflict with All In One SEO Pack 1.6.10. It was caused by that plugin adding invisible sub-menus to a non-existent top-level menu.
|
49 |
|
50 |
= 0.1.5 =
|
51 |
* First release on wordpress.org
|
52 |
* Moved all images into a separate directory.
|
53 |
-
* Added a readme.txt
|
1 |
=== Admin Menu Editor ===
|
2 |
Contributors: whiteshadow
|
3 |
Donate link: http://w-shadow.com/
|
4 |
+
Tags: admin, dashboard, menu, security, wpmu
|
5 |
Requires at least: 2.7.0
|
6 |
+
Tested up to: 2.9.2
|
7 |
+
Stable tag: 0.2
|
8 |
|
9 |
Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
|
10 |
|
19 |
* Hide/show any menu or menu item. A hidden menu is invisible to all users, including administrators.
|
20 |
* Create custom menus that point to any part of the Dashboard. For example, you could create a new menu leading directly to the "Pending comments" page.
|
21 |
|
22 |
+
[Suggest new features and improvements here](http://feedback.w-shadow.com/forums/58572-admin-menu-editor)
|
23 |
+
|
24 |
**Known Issues**
|
25 |
|
26 |
+
* If you delete any of the default menus they will reappear after saving. This is by design. To get rid of a menu for good, either hide it or set it's access rights to a higher level.
|
27 |
+
* Custom menus will only show up in the final menu if the "Custom" box is checked. If some of your menu items are only visible in the editor but not the Dashboard menu itself, this is probably the reason.
|
28 |
+
* A plugin's menu that is moved to a different submenu will not work unless you also include the parent file in the "File" field. For example, if the plugin's page was originally in the "Settings" menu and had the "File" field set to "my_plugin", you'll need to change it to "options-general.php?page=my_plugin" and tick the "Custom" checkbox after moving it to a different menu.
|
29 |
|
30 |
== Installation ==
|
31 |
|
32 |
+
**Normal installation**
|
33 |
|
34 |
1. Download the admin-menu-editor.zip file to your local machine.
|
35 |
+
1. Unzip the file.
|
36 |
+
1. Upload the `admin-menu-editor` directory to your `/wp-content/plugins/` directory.
|
37 |
1. Activate the plugin through the 'Plugins' menu in WordPress.
|
38 |
|
39 |
That's it. You can access the the menu editor by going to *Settings -> Menu Editor*. The plugin will automatically load your current menu configuration the first time you run it.
|
40 |
|
41 |
+
**WPMU/Multi-user installation**
|
42 |
+
|
43 |
+
If you have a WPMU site, you can also install Admin Menu Editor as a global plugin. This will enable you to edit the Dashboard menu for all blogs and users at once.
|
44 |
|
45 |
+
1. Download the admin-menu-editor.zip file to your local machine.
|
46 |
+
1. Unzip the file.
|
47 |
+
1. Upload the `admin-menu-editor` directory to your `/wp-content/mu-plugins/` directory.
|
48 |
+
1. Move the `admin-menu-editor-mu.php` file from `admin-menu-editor` to `/wp-content/mu-plugins/`.
|
49 |
+
|
50 |
+
*Note : It is currently not possible to install this plugin both as a normal plugin and as a mu-plugin on the same site.*
|
51 |
|
52 |
== Changelog ==
|
53 |
|
54 |
+
= 0.2 =
|
55 |
+
* Provisional WPMU support.
|
56 |
+
* Missing and unused menu items now get different icons in the menu editor.
|
57 |
+
* Fixed some visual glitches.
|
58 |
+
* Items that are not present in the default menu will only be included in the generated menu if their "Custom" flag is set. Makes perfect sense, eh? The takeaway is that you should tick the "Custom" checkbox for the menus you have created manually if you want them to show up.
|
59 |
+
* You no longer need to manually reload the page to see the changes you made to the menu. Just clicking "Save Changes" is enough.
|
60 |
+
* Added tooltips to the small flag icons that indicate that a particular menu item is hidden, user-created or otherwise special.
|
61 |
+
* Updated the readme.txt
|
62 |
+
|
63 |
= 0.1.6 =
|
64 |
* Fixed a conflict with All In One SEO Pack 1.6.10. It was caused by that plugin adding invisible sub-menus to a non-existent top-level menu.
|
65 |
|
66 |
= 0.1.5 =
|
67 |
* First release on wordpress.org
|
68 |
* Moved all images into a separate directory.
|
69 |
+
* Added a readme.txt
|
shadow_plugin_framework.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
/**
|
4 |
* @author W-Shadow
|
5 |
-
* @copyright 2008
|
6 |
*/
|
7 |
|
8 |
//Make sure the needed constants are defined
|
@@ -16,11 +16,14 @@ if ( ! defined( 'WP_PLUGIN_DIR' ) )
|
|
16 |
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
|
17 |
|
18 |
class MenuEd_ShadowPluginFramework {
|
19 |
-
public static $framework_version = '0.
|
|
|
|
|
20 |
|
21 |
protected $options = array();
|
22 |
public $option_name = ''; //should be set or overriden by the plugin
|
23 |
protected $defaults = array(); //should be set or overriden by the plugin
|
|
|
24 |
|
25 |
public $plugin_file = ''; //Filename of the plugin.
|
26 |
public $plugin_basename = ''; //Basename of the plugin, as returned by plugin_basename().
|
@@ -41,11 +44,20 @@ class MenuEd_ShadowPluginFramework {
|
|
41 |
protected function __construct( $plugin_file = ''){
|
42 |
if ($plugin_file == ''){
|
43 |
//Try to guess the name of the file that included this file.
|
44 |
-
//
|
45 |
}
|
|
|
|
|
|
|
|
|
46 |
$this->plugin_file = $plugin_file;
|
47 |
$this->plugin_basename = plugin_basename($this->plugin_file);
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
/************************************
|
51 |
Load settings
|
@@ -81,7 +93,12 @@ class MenuEd_ShadowPluginFramework {
|
|
81 |
* @return boolean TRUE if options were loaded okay and FALSE otherwise.
|
82 |
*/
|
83 |
function load_options(){
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
85 |
if(!is_array($this->options)){
|
86 |
$this->options = $this->defaults;
|
87 |
return false;
|
@@ -122,8 +139,13 @@ class MenuEd_ShadowPluginFramework {
|
|
122 |
* @return void
|
123 |
*/
|
124 |
function save_options(){
|
125 |
-
if ($this->option_name)
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
127 |
}
|
128 |
|
129 |
/**
|
@@ -171,6 +193,23 @@ class MenuEd_ShadowPluginFramework {
|
|
171 |
delete_option($this->option_name);
|
172 |
}
|
173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
175 |
|
176 |
?>
|
2 |
|
3 |
/**
|
4 |
* @author W-Shadow
|
5 |
+
* @copyright 2008-2010
|
6 |
*/
|
7 |
|
8 |
//Make sure the needed constants are defined
|
16 |
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
|
17 |
|
18 |
class MenuEd_ShadowPluginFramework {
|
19 |
+
public static $framework_version = '0.2';
|
20 |
+
|
21 |
+
public $is_mu_plugin = null; //True if installed in the mu-plugins directory, false otherwise
|
22 |
|
23 |
protected $options = array();
|
24 |
public $option_name = ''; //should be set or overriden by the plugin
|
25 |
protected $defaults = array(); //should be set or overriden by the plugin
|
26 |
+
protected $sitewide_options = false; //WPMU only : save the setting in a site-wide option
|
27 |
|
28 |
public $plugin_file = ''; //Filename of the plugin.
|
29 |
public $plugin_basename = ''; //Basename of the plugin, as returned by plugin_basename().
|
44 |
protected function __construct( $plugin_file = ''){
|
45 |
if ($plugin_file == ''){
|
46 |
//Try to guess the name of the file that included this file.
|
47 |
+
//Not implemented yet.
|
48 |
}
|
49 |
+
|
50 |
+
if ( is_null($this->is_mu_plugin) )
|
51 |
+
$this->is_mu_plugin = $this->is_in_wpmu_plugin_dir($plugin_file);
|
52 |
+
|
53 |
$this->plugin_file = $plugin_file;
|
54 |
$this->plugin_basename = plugin_basename($this->plugin_file);
|
55 |
+
|
56 |
+
if ( $this->is_mu_plugin ){
|
57 |
+
$this->plugin_dir_url = WPMU_PLUGIN_URL . '/' . dirname($this->plugin_basename);
|
58 |
+
} else {
|
59 |
+
$this->plugin_dir_url = WP_PLUGIN_URL . '/' . dirname($this->plugin_basename);
|
60 |
+
}
|
61 |
|
62 |
/************************************
|
63 |
Load settings
|
93 |
* @return boolean TRUE if options were loaded okay and FALSE otherwise.
|
94 |
*/
|
95 |
function load_options(){
|
96 |
+
if ( $this->sitewide_options ) {
|
97 |
+
$this->options = get_site_option($this->option_name);
|
98 |
+
} else {
|
99 |
+
$this->options = get_option($this->option_name);
|
100 |
+
}
|
101 |
+
|
102 |
if(!is_array($this->options)){
|
103 |
$this->options = $this->defaults;
|
104 |
return false;
|
139 |
* @return void
|
140 |
*/
|
141 |
function save_options(){
|
142 |
+
if ($this->option_name) {
|
143 |
+
if ( $this->sitewide_options ) {
|
144 |
+
update_site_option($this->option_name, $this->options);
|
145 |
+
} else {
|
146 |
+
update_option($this->option_name, $this->options);
|
147 |
+
}
|
148 |
+
}
|
149 |
}
|
150 |
|
151 |
/**
|
193 |
delete_option($this->option_name);
|
194 |
}
|
195 |
|
196 |
+
/**
|
197 |
+
* MenuEd_ShadowPluginFramework::is_in_wpmu_plugin_dir()
|
198 |
+
* Checks if the specified file is inside the mu-plugins directory.
|
199 |
+
*
|
200 |
+
* @param string $filename The filename to check. Leave blank to use the current plugin's filename.
|
201 |
+
* @return bool
|
202 |
+
*/
|
203 |
+
function is_in_wpmu_plugin_dir( $filename = '' ){
|
204 |
+
if ( !defined('WPMU_PLUGIN_DIR') ) return false;
|
205 |
+
|
206 |
+
if ( empty($filename) ){
|
207 |
+
$filename = $this->plugin_file;
|
208 |
+
}
|
209 |
+
|
210 |
+
return (strpos( realpath($filename), realpath(WPMU_PLUGIN_DIR) ) !== false);
|
211 |
+
}
|
212 |
+
|
213 |
}
|
214 |
|
215 |
?>
|