Admin Menu Tree Page View - Version 1.2

Version Description

  • Tree now always opens up when editing a page, so you will always see the page you're ediiting.
  • When searching, the parents of a page with a match is opened, so search hits will always be visible.
  • When searching and no pages found, show text "no pages found".
  • CSS changes for upcoming admin area CSS changes in WordPress (may look wierd on current/older versions of WordPress...)
  • Some preparing for using nestedSortable to order the pages
Download this release

Release Info

Developer eskapism
Plugin Icon wp plugin Admin Menu Tree Page View
Version 1.2
Comparing to
See all releases

Code changes from version 1.1 to 1.2

Files changed (5) hide show
  1. index.php +32 -17
  2. jquery.ui.nestedSortable.js +374 -0
  3. readme.txt +8 -1
  4. scripts.js +51 -25
  5. styles.css +22 -11
index.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Admin Menu Tree Page View
4
  Plugin URI: http://eskapism.se/code-playground/admin-menu-tree-page-view/
5
  Description: Get a tree view of all your pages directly in the admin menu. Search, edit, view and add pages - all with just one click away!
6
- Version: 1.1
7
  Author: Pär Thernström
8
  Author URI: http://eskapism.se/
9
  License: GPL2
@@ -32,20 +32,20 @@ add_action('wp_ajax_admin_menu_tree_page_view_add_page', 'admin_menu_tree_page_v
32
 
33
  function admin_menu_tree_page_view_admin_init() {
34
 
35
- define( "admin_menu_tree_page_view_VERSION", "1.1" );
36
  define( "admin_menu_tree_page_view_URL", WP_PLUGIN_URL . '/admin-menu-tree-page-view/' );
37
 
38
  wp_enqueue_style("admin_menu_tree_page_view_styles", admin_menu_tree_page_view_URL . "styles.css", false, admin_menu_tree_page_view_VERSION);
39
  wp_enqueue_script("jquery.highlight", admin_menu_tree_page_view_URL . "jquery.highlight.js", array("jquery"));
40
- wp_enqueue_script( "jquery-cookie", admin_menu_tree_page_view_URL . "jquery.biscuit.js", array("jquery")); // renamed from cookie to fix problems with mod_security
 
41
  wp_enqueue_script("admin_menu_tree_page_view", admin_menu_tree_page_view_URL . "scripts.js", array("jquery"));
42
 
43
-
44
  $oLocale = array(
45
  "Edit" => __("Edit", 'admin-menu-tree-page-view'),
46
  "View" => __("View", 'admin-menu-tree-page-view'),
47
- "Add_new_page_here" => __("New page here", 'admin-menu-tree-page-view'),
48
- "Add_new_page_inside" => __("New page inside", 'admin-menu-tree-page-view'),
49
  "Untitled" => __("Untitled", 'admin-menu-tree-page-view'),
50
  );
51
  wp_localize_script( "admin_menu_tree_page_view", 'amtpv_l10n', $oLocale);
@@ -114,13 +114,27 @@ function admin_menu_tree_page_view_get_pages($args) {
114
  // check cookie first
115
  $cookie_opened = isset($_COOKIE["admin-menu-tree-page-view-open-posts"]) ? $_COOKIE["admin-menu-tree-page-view-open-posts"] : ""; // 2,95,n
116
  $cookie_opened = explode(",", $cookie_opened);
117
- if (in_array($one_page->ID, $cookie_opened) || $isOpened && $post_children_count>0) {
 
 
 
 
 
 
 
 
 
 
 
 
118
  $class .= " admin-menu-tree-page-view-opened";
119
  } elseif ($post_children_count>0) {
120
  $class .= " admin-menu-tree-page-view-closed";
121
- }
122
-
123
- $output .= "<li class='$class'>";
 
 
124
  $output .= "<a href='$edit_link'>$status_span";
125
  $output .= $title;
126
 
@@ -137,7 +151,7 @@ function admin_menu_tree_page_view_get_pages($args) {
137
 
138
  $output .= $str_child_output;
139
 
140
- $output .= "</li>";
141
  }
142
 
143
  // if this is a child listing, add ul
@@ -159,12 +173,13 @@ function admin_menu_tree_page_view_admin_menu() {
159
  $output = "
160
  </a>
161
  <ul class='admin-menu-tree-page-tree'>
162
- <li class='admin-menu-tree-page-tree_headline'>" . __("Pages", 'admin-menu-tree-page-view') . "</li>
163
- <li class='admin-menu-tree-page-filter'>
164
- <label>".__("Search", 'admin-menu-tree-page-view')."</label>
165
- <input type='text' class='' />
166
- <div class='admin-menu-tree-page-filter-reset' title='".__("Reset search and show all pages", 'admin-menu-tree-page-view')."'></div>
167
- </li>
 
168
  ";
169
 
170
  // get root items
3
  Plugin Name: Admin Menu Tree Page View
4
  Plugin URI: http://eskapism.se/code-playground/admin-menu-tree-page-view/
5
  Description: Get a tree view of all your pages directly in the admin menu. Search, edit, view and add pages - all with just one click away!
6
+ Version: 1.2
7
  Author: Pär Thernström
8
  Author URI: http://eskapism.se/
9
  License: GPL2
32
 
33
  function admin_menu_tree_page_view_admin_init() {
34
 
35
+ define( "admin_menu_tree_page_view_VERSION", "1.2" );
36
  define( "admin_menu_tree_page_view_URL", WP_PLUGIN_URL . '/admin-menu-tree-page-view/' );
37
 
38
  wp_enqueue_style("admin_menu_tree_page_view_styles", admin_menu_tree_page_view_URL . "styles.css", false, admin_menu_tree_page_view_VERSION);
39
  wp_enqueue_script("jquery.highlight", admin_menu_tree_page_view_URL . "jquery.highlight.js", array("jquery"));
40
+ wp_enqueue_script("jquery-cookie", admin_menu_tree_page_view_URL . "jquery.biscuit.js", array("jquery")); // renamed from cookie to fix problems with mod_security
41
+ wp_enqueue_script("jquery.ui.nestedSortable", admin_menu_tree_page_view_URL . "jquery.ui.nestedSortable.js", array("jquery", "jquery-ui-sortable"));
42
  wp_enqueue_script("admin_menu_tree_page_view", admin_menu_tree_page_view_URL . "scripts.js", array("jquery"));
43
 
 
44
  $oLocale = array(
45
  "Edit" => __("Edit", 'admin-menu-tree-page-view'),
46
  "View" => __("View", 'admin-menu-tree-page-view'),
47
+ "Add_new_page_here" => __("Add new page after", 'admin-menu-tree-page-view'),
48
+ "Add_new_page_inside" => __("Add new page inside", 'admin-menu-tree-page-view'),
49
  "Untitled" => __("Untitled", 'admin-menu-tree-page-view'),
50
  );
51
  wp_localize_script( "admin_menu_tree_page_view", 'amtpv_l10n', $oLocale);
114
  // check cookie first
115
  $cookie_opened = isset($_COOKIE["admin-menu-tree-page-view-open-posts"]) ? $_COOKIE["admin-menu-tree-page-view-open-posts"] : ""; // 2,95,n
116
  $cookie_opened = explode(",", $cookie_opened);
117
+
118
+ // if we are editing a post, we should see it in the tree, right?
119
+ if ( isset($_GET["action"]) && "edit" == $_GET["action"] && isset($_GET["post"])) {
120
+ // if post with id get[post] is a parent of the current post, show it
121
+ if ($_GET["post"] != $one_page->ID) {
122
+ $one_page_parents = get_post_ancestors($_GET["post"]);
123
+ if (in_array($one_page->ID, $one_page_parents)) {
124
+ $isOpened = TRUE;
125
+ }
126
+ }
127
+ }
128
+
129
+ if (in_array($one_page->ID, $cookie_opened) || $isOpened && $post_children_count>0) {
130
  $class .= " admin-menu-tree-page-view-opened";
131
  } elseif ($post_children_count>0) {
132
  $class .= " admin-menu-tree-page-view-closed";
133
+ }
134
+
135
+ $class .= " nestedSortable";
136
+
137
+ $output .= "<li class='$class'><div>";
138
  $output .= "<a href='$edit_link'>$status_span";
139
  $output .= $title;
140
 
151
 
152
  $output .= $str_child_output;
153
 
154
+ $output .= "</div></li>";
155
  }
156
 
157
  // if this is a child listing, add ul
173
  $output = "
174
  </a>
175
  <ul class='admin-menu-tree-page-tree'>
176
+ <li class='admin-menu-tree-page-tree_headline'>" . __("Pages", 'admin-menu-tree-page-view') . "</li>
177
+ <li class='admin-menu-tree-page-filter'>
178
+ <label>".__("Search", 'admin-menu-tree-page-view')."</label>
179
+ <input type='text' class='' />
180
+ <div class='admin-menu-tree-page-filter-reset' title='".__("Reset search and show all pages", 'admin-menu-tree-page-view')."'></div>
181
+ <div class='admin-menu-tree-page-filter-nohits'>".__("No pages found", 'admin-menu-tree-page-view')."</div>
182
+ </li>
183
  ";
184
 
185
  // get root items
jquery.ui.nestedSortable.js ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Nested Sortable
3
+ * v 1.3.4 / 28 apr 2011
4
+ * http://mjsarfatti.com/sandbox/nestedSortable
5
+ *
6
+ * Depends:
7
+ * jquery.ui.sortable.js 1.8+
8
+ *
9
+ * License CC BY-SA 3.0
10
+ * Copyright 2010-2011, Manuele J Sarfatti
11
+ */
12
+
13
+ (function($) {
14
+
15
+ $.widget("ui.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
16
+
17
+ options: {
18
+ tabSize: 20,
19
+ disableNesting: 'ui-nestedSortable-no-nesting',
20
+ errorClass: 'ui-nestedSortable-error',
21
+ listType: 'ol',
22
+ maxLevels: 0,
23
+ noJumpFix: 0,
24
+ revertOnError: 1
25
+ },
26
+
27
+ _create: function(){
28
+ if (this.noJumpFix == false)
29
+ this.element.height(this.element.height());
30
+ this.element.data('sortable', this.element.data('nestedSortable'));
31
+ return $.ui.sortable.prototype._create.apply(this, arguments);
32
+ },
33
+
34
+ destroy: function() {
35
+ this.element
36
+ .removeData("nestedSortable")
37
+ .unbind(".nestedSortable");
38
+ return $.ui.sortable.prototype.destroy.apply(this, arguments);
39
+ },
40
+
41
+ _mouseDrag: function(event) {
42
+
43
+ //Compute the helpers position
44
+ this.position = this._generatePosition(event);
45
+ this.positionAbs = this._convertPositionTo("absolute");
46
+
47
+ if (!this.lastPositionAbs) {
48
+ this.lastPositionAbs = this.positionAbs;
49
+ }
50
+
51
+ //Do scrolling
52
+ if(this.options.scroll) {
53
+ var o = this.options, scrolled = false;
54
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
55
+
56
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
57
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
58
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
59
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
60
+
61
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
62
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
63
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
64
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
65
+
66
+ } else {
67
+
68
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
69
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
70
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
71
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
72
+
73
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
74
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
75
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
76
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
77
+
78
+ }
79
+
80
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
81
+ $.ui.ddmanager.prepareOffsets(this, event);
82
+ }
83
+
84
+ //Regenerate the absolute position used for position checks
85
+ this.positionAbs = this._convertPositionTo("absolute");
86
+
87
+ //Set the helper position
88
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
89
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
90
+
91
+ //Rearrange
92
+ for (var i = this.items.length - 1; i >= 0; i--) {
93
+
94
+ //Cache variables and intersection, continue if no intersection
95
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
96
+ if (!intersection) continue;
97
+
98
+ if(itemElement != this.currentItem[0] //cannot intersect with itself
99
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
100
+ && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
101
+ && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
102
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
103
+ ) {
104
+
105
+ this.direction = intersection == 1 ? "down" : "up";
106
+
107
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
108
+ this._rearrange(event, item);
109
+ } else {
110
+ break;
111
+ }
112
+
113
+ // Clear emtpy ul's/ol's
114
+ this._clearEmpty(itemElement);
115
+
116
+ this._trigger("change", event, this._uiHash());
117
+ break;
118
+ }
119
+ }
120
+
121
+ var parentItem = (this.placeholder[0].parentNode.parentNode && $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length) ? $(this.placeholder[0].parentNode.parentNode) : null;
122
+ var level = this._getLevel(this.placeholder);
123
+ var childLevels = this._getChildLevels(this.helper);
124
+ var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
125
+ if (previousItem != null) {
126
+ while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0]) {
127
+ if (previousItem[0].previousSibling) {
128
+ previousItem = $(previousItem[0].previousSibling);
129
+ } else {
130
+ previousItem = null;
131
+ break;
132
+ }
133
+ }
134
+ }
135
+
136
+ newList = document.createElement(o.listType);
137
+
138
+ this.beyondMaxLevels = 0;
139
+
140
+ // If the item is moved to the left, send it to its parent level
141
+ if (parentItem != null && this.positionAbs.left < parentItem.offset().left) {
142
+ parentItem.after(this.placeholder[0]);
143
+ this._clearEmpty(parentItem[0]);
144
+ this._trigger("change", event, this._uiHash());
145
+ }
146
+ // If the item is below another one and is moved to the right, make it a children of it
147
+ else if (previousItem != null && this.positionAbs.left > previousItem.offset().left + o.tabSize) {
148
+ this._isAllowed(previousItem, level+childLevels+1);
149
+ if (!previousItem.children(o.listType).length) {
150
+ previousItem[0].appendChild(newList);
151
+ }
152
+ previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
153
+ this._trigger("change", event, this._uiHash());
154
+ }
155
+ else {
156
+ this._isAllowed(parentItem, level+childLevels);
157
+ }
158
+
159
+ //Post events to containers
160
+ this._contactContainers(event);
161
+
162
+ //Interconnect with droppables
163
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
164
+
165
+ //Call callbacks
166
+ this._trigger('sort', event, this._uiHash());
167
+
168
+ this.lastPositionAbs = this.positionAbs;
169
+ return false;
170
+
171
+ },
172
+
173
+ _mouseStop: function(event, noPropagation) {
174
+
175
+ // If the item is in a position not allowed, send it back
176
+ if (this.beyondMaxLevels) {
177
+
178
+ this.placeholder.removeClass(this.options.errorClass);
179
+
180
+ if (this.options.revertOnError) {
181
+ if (this.domPosition.prev) {
182
+ $(this.domPosition.prev).after(this.placeholder);
183
+ } else {
184
+ $(this.domPosition.parent).prepend(this.placeholder);
185
+ }
186
+ this._trigger("revert", event, this._uiHash());
187
+ } else {
188
+ var parent = this.placeholder.parent().closest(this.options.items);
189
+
190
+ for (var i = this.beyondMaxLevels - 1; i > 0; i--) {
191
+ parent = parent.parent().closest(this.options.items);
192
+ }
193
+
194
+ parent.after(this.placeholder);
195
+ this._trigger("change", event, this._uiHash());
196
+ }
197
+
198
+ }
199
+
200
+ $.ui.sortable.prototype._mouseStop.apply(this, arguments);
201
+
202
+ },
203
+
204
+ serialize: function(o) {
205
+
206
+ var items = this._getItemsAsjQuery(o && o.connected);
207
+ var str = []; o = o || {};
208
+
209
+ $(items).each(function() {
210
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
211
+ var pid = ($(o.item || this).parent(o.listType).parent('li').attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
212
+ if(res) str.push((o.key || res[1]+'['+(o.key && o.expression ? res[1] : res[2])+']')+'='+(pid ? (o.key && o.expression ? pid[1] : pid[2]) : 'root'));
213
+ });
214
+
215
+ if(!str.length && o.key) {
216
+ str.push(o.key + '=');
217
+ }
218
+
219
+ return str.join('&');
220
+
221
+ },
222
+
223
+ toHierarchy: function(o) {
224
+
225
+ o = o || {};
226
+ var sDepth = o.startDepthCount || 0;
227
+ var ret = [];
228
+
229
+ $(this.element).children('li').each(function() {
230
+ var level = _recursiveItems($(this));
231
+ ret.push(level);
232
+ });
233
+
234
+ return ret;
235
+
236
+ function _recursiveItems(li) {
237
+ var id = ($(li).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
238
+ if (id != null) {
239
+ var item = {"id" : id[2]};
240
+ if ($(li).children(o.listType).children('li').length > 0) {
241
+ item.children = [];
242
+ $(li).children(o.listType).children('li').each(function () {
243
+ var level = _recursiveItems($(this));
244
+ item.children.push(level);
245
+ });
246
+ }
247
+ return item;
248
+ }
249
+ }
250
+ },
251
+
252
+ toArray: function(o) {
253
+
254
+ o = o || {};
255
+ var sDepth = o.startDepthCount || 0;
256
+ var ret = [];
257
+ var left = 2;
258
+
259
+ ret.push({"item_id": 'root', "parent_id": 'none', "depth": sDepth, "left": '1', "right": ($('li', this.element).length + 1) * 2});
260
+
261
+ $(this.element).children('li').each(function () {
262
+ left = _recursiveArray(this, sDepth + 1, left);
263
+ });
264
+
265
+ function _sortByLeft(a,b) {
266
+ return a['left'] - b['left'];
267
+ }
268
+ ret = ret.sort(_sortByLeft);
269
+
270
+ return ret;
271
+
272
+ function _recursiveArray(item, depth, left) {
273
+
274
+ right = left + 1;
275
+
276
+ if ($(item).children(o.listType).children('li').length > 0) {
277
+ depth ++;
278
+ $(item).children(o.listType).children('li').each(function () {
279
+ right = _recursiveArray($(this), depth, right);
280
+ });
281
+ depth --;
282
+ }
283
+
284
+ id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
285
+
286
+ if (depth === sDepth + 1) pid = 'root';
287
+ else {
288
+ parentItem = ($(item).parent(o.listType).parent('li').attr('id')).match(o.expression || (/(.+)[-=_](.+)/));
289
+ pid = parentItem[2];
290
+ }
291
+
292
+ if (id != null) {
293
+ ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
294
+ }
295
+
296
+ return left = right + 1;
297
+ }
298
+
299
+ },
300
+
301
+ _clear: function(event, noPropagation) {
302
+
303
+ $.ui.sortable.prototype._clear.apply(this, arguments);
304
+
305
+ // Clean last empty ul/ol
306
+ for (var i = this.items.length - 1; i >= 0; i--) {
307
+ var item = this.items[i].item[0];
308
+ this._clearEmpty(item);
309
+ }
310
+ return true;
311
+
312
+ },
313
+
314
+ _clearEmpty: function(item) {
315
+
316
+ if (item.children[1] && item.children[1].children.length == 0) {
317
+ item.removeChild(item.children[1]);
318
+ }
319
+
320
+ },
321
+
322
+ _getLevel: function(item) {
323
+
324
+ var level = 1;
325
+
326
+ if (this.options.listType) {
327
+ var list = item.closest(this.options.listType);
328
+ while (!list.is('.ui-sortable')/* && level < this.options.maxLevels*/) {
329
+ level++;
330
+ list = list.parent().closest(this.options.listType);
331
+ }
332
+ }
333
+
334
+ return level;
335
+ },
336
+
337
+ _getChildLevels: function(parent, depth) {
338
+ var self = this,
339
+ o = this.options,
340
+ result = 0;
341
+ depth = depth || 0;
342
+
343
+ $(parent).children(o.listType).children(o.items).each(function (index, child) {
344
+ result = Math.max(self._getChildLevels(child, depth + 1), result);
345
+ });
346
+
347
+ return depth ? result + 1 : result;
348
+ },
349
+
350
+ _isAllowed: function(parentItem, levels) {
351
+ var o = this.options
352
+ // Are we trying to nest under a no-nest or are we nesting too deep?
353
+ if (parentItem == null || !(parentItem.hasClass(o.disableNesting))) {
354
+ if (o.maxLevels < levels && o.maxLevels != 0) {
355
+ this.placeholder.addClass(o.errorClass);
356
+ this.beyondMaxLevels = levels - o.maxLevels;
357
+ } else {
358
+ this.placeholder.removeClass(o.errorClass);
359
+ this.beyondMaxLevels = 0;
360
+ }
361
+ } else {
362
+ this.placeholder.addClass(o.errorClass);
363
+ if (o.maxLevels < levels && o.maxLevels != 0) {
364
+ this.beyondMaxLevels = levels - o.maxLevels;
365
+ } else {
366
+ this.beyondMaxLevels = 1;
367
+ }
368
+ }
369
+ }
370
+
371
+ }));
372
+
373
+ $.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
374
+ })(jQuery);
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://eskapism.se/sida/donate/
4
  Tags: admin, page, pages, tree, view, admin menu, menu
5
  Requires at least: 3.0
6
  Tested up to: 3.0
7
- Stable tag: trunk
8
 
9
  Get a tree view of all your pages directly in the admin menu. Search, edit, view and add pages - all with just one click away!
10
 
@@ -40,6 +40,13 @@ Now the tree with the pages will be visible in the admin menu to the left.
40
 
41
  == Changelog ==
42
 
 
 
 
 
 
 
 
43
  = 1.1 =
44
  - Children count was sometines wrong.
45
 
4
  Tags: admin, page, pages, tree, view, admin menu, menu
5
  Requires at least: 3.0
6
  Tested up to: 3.0
7
+ Stable tag: 1.2
8
 
9
  Get a tree view of all your pages directly in the admin menu. Search, edit, view and add pages - all with just one click away!
10
 
40
 
41
  == Changelog ==
42
 
43
+ = 1.2 =
44
+ - Tree now always opens up when editing a page, so you will always see the page you're ediiting.
45
+ - When searching, the parents of a page with a match is opened, so search hits will always be visible.
46
+ - When searching and no pages found, show text "no pages found".
47
+ - CSS changes for upcoming admin area CSS changes in WordPress (may look wierd on current/older versions of WordPress...)
48
+ - Some preparing for using nestedSortable to order the pages
49
+
50
  = 1.1 =
51
  - Children count was sometines wrong.
52
 
scripts.js CHANGED
@@ -6,7 +6,7 @@ jQuery(function($) {
6
  }, 100);
7
 
8
  // show menu when menu icon is clicked
9
- jQuery(".admin-menu-tree-page-view-edit").click(function() {
10
 
11
  var $this = $(this);
12
 
@@ -14,7 +14,7 @@ jQuery(function($) {
14
  var wpsubmenu = $(this).closest("div.wp-submenu");
15
  if (wpsubmenu.length == 1) {
16
 
17
- var div_popup = wpsubmenu.find(".admin-menu-tree-page-view-popup");
18
  var do_show = true;
19
  if (div_popup.length == 0) {
20
  // no menu div yet, create it
@@ -37,10 +37,10 @@ jQuery(function($) {
37
 
38
  var a = $this.closest("a");
39
  var link_text = a.text();
40
- if (div_popup.find(".admin-menu-tree-page-view-popup-page").text() == link_text) {
41
  do_show = false;
42
  }
43
- div_popup.find(".admin-menu-tree-page-view-popup-page").text( link_text );
44
  var offset = $this.offset();
45
  offset.top = (offset.top-3);
46
  offset.left = (offset.left-3);
@@ -52,18 +52,18 @@ jQuery(function($) {
52
 
53
  // setup edit and view links
54
  var edit_link = "post.php?post="+post_id+"&action=edit";
55
- div_popup.find(".admin-menu-tree-page-view-popup-edit a").attr("href", edit_link);
56
 
57
  // view link, this is probably not such a safe way to this this. but let's try! :)
58
  var view_link = $this.closest("li").find(".admin-menu-tree-page-view-view-link").text();
59
- div_popup.find(".admin-menu-tree-page-view-popup-view a").attr("href", view_link);
60
 
61
  if (do_show) {
62
  div_popup.fadeIn("fast");
63
  } else {
64
  // same popup, so close it
65
  div_popup.fadeOut("fast");
66
- div_popup.find(".admin-menu-tree-page-view-popup-page").text("");
67
  }
68
 
69
  div_popup.offset( offset ); // must be last or position gets wrong somehow
@@ -74,14 +74,14 @@ jQuery(function($) {
74
  });
75
 
76
  // hide menu
77
- $(".admin-menu-tree-page-view-popup-arrow").live("click", function() {
78
- $(this).closest(".admin-menu-tree-page-view-popup").fadeOut("fast");
79
  return false;
80
  });
81
 
82
  // add page
83
  $(".admin-menu-tree-page-view-popup-add-here, .admin-menu-tree-page-view-popup-add-inside").live("click", function() {
84
- var div_popup = $(this).closest(".admin-menu-tree-page-view-popup");
85
  var post_id = div_popup.data("admin-menu-tree-page-view-current-post-id");
86
 
87
  var type = "after";
@@ -113,46 +113,67 @@ jQuery(function($) {
113
  });
114
 
115
  // search/filter pages
116
- $(".admin-menu-tree-page-filter input").keyup(function(e) {
117
- var ul = $(this).closest(".admin-menu-tree-page-tree");
118
  ul.find("li").hide();
119
- ul.find(".admin-menu-tree-page-tree_headline,.admin-menu-tree-page-filter").show();
120
  var s = $(this).val();
121
  var selector = "li:AminMenuTreePageContains('"+s+"')";
122
  var hits = ul.find(selector);
123
  if (hits.length > 0 || s != "") {
124
- ul.find(".admin-menu-tree-page-filter-reset").fadeIn("fast");
125
  ul.unhighlight();
126
  }
127
  if (s == "") {
128
- ul.find(".admin-menu-tree-page-filter-reset").fadeOut("fast");
129
  }
130
  ul.highlight(s);
131
  hits.show();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  });
133
 
134
  // clear/reset filter and show all pages again
135
- $(".admin-menu-tree-page-filter-reset").click(function() {
136
  var $t = $(this);
137
- var ul = $t.closest(".admin-menu-tree-page-tree");
138
  ul.find("li").fadeIn("fast");
139
  $t.fadeOut("fast");
140
- $t.closest(".admin-menu-tree-page-filter").find("input").val("").focus();
141
  ul.unhighlight();
 
142
  });
143
 
144
  // label = hide in and focus input
145
- $(".admin-menu-tree-page-filter label, .admin-menu-tree-page-filter input").click(function() {
146
  var $t = $(this);
147
- $t.closest(".admin-menu-tree-page-filter").find("label").hide();
148
- $t.closest(".admin-menu-tree-page-filter").find("input").focus();
149
  });
150
 
151
- var trees = jQuery(".admin-menu-tree-page-tree");
152
 
153
  // add links to expand/collapse
154
- trees.find(".admin-menu-tree-page-view-has-childs").prepend("<div class='admin-menu-tree-page-expand' title='Show/Hide child pages' />");
155
- trees.find(".admin-menu-tree-page-expand").live("click", function(e) {
156
 
157
  e.preventDefault();
158
  var $t = $(this);
@@ -183,13 +204,18 @@ jQuery(function($) {
183
  if (isOpen) {
184
  admin_menu_tree_page_view_opened_posts.push(post_id);
185
  }
186
- jQuery.cookie('admin-menu-tree-page-view-open-posts', admin_menu_tree_page_view_opened_posts.join(","));
 
187
 
188
  });
189
 
190
 
191
  });
192
 
 
 
 
 
193
  // array with all post ids that are open
194
  var admin_menu_tree_page_view_opened_posts = jQuery.cookie('admin-menu-tree-page-view-open-posts') || "";
195
  admin_menu_tree_page_view_opened_posts = admin_menu_tree_page_view_opened_posts.split(",");
6
  }, 100);
7
 
8
  // show menu when menu icon is clicked
9
+ jQuery("span.admin-menu-tree-page-view-edit").click(function() {
10
 
11
  var $this = $(this);
12
 
14
  var wpsubmenu = $(this).closest("div.wp-submenu");
15
  if (wpsubmenu.length == 1) {
16
 
17
+ var div_popup = wpsubmenu.find("div.admin-menu-tree-page-view-popup");
18
  var do_show = true;
19
  if (div_popup.length == 0) {
20
  // no menu div yet, create it
37
 
38
  var a = $this.closest("a");
39
  var link_text = a.text();
40
+ if (div_popup.find("div.admin-menu-tree-page-view-popup-page").text() == link_text) {
41
  do_show = false;
42
  }
43
+ div_popup.find("div.admin-menu-tree-page-view-popup-page").text( link_text );
44
  var offset = $this.offset();
45
  offset.top = (offset.top-3);
46
  offset.left = (offset.left-3);
52
 
53
  // setup edit and view links
54
  var edit_link = "post.php?post="+post_id+"&action=edit";
55
+ div_popup.find("div.admin-menu-tree-page-view-popup-edit a").attr("href", edit_link);
56
 
57
  // view link, this is probably not such a safe way to this this. but let's try! :)
58
  var view_link = $this.closest("li").find(".admin-menu-tree-page-view-view-link").text();
59
+ div_popup.find("div.admin-menu-tree-page-view-popup-view a").attr("href", view_link);
60
 
61
  if (do_show) {
62
  div_popup.fadeIn("fast");
63
  } else {
64
  // same popup, so close it
65
  div_popup.fadeOut("fast");
66
+ div_popup.find("div.admin-menu-tree-page-view-popup-page").text("");
67
  }
68
 
69
  div_popup.offset( offset ); // must be last or position gets wrong somehow
74
  });
75
 
76
  // hide menu
77
+ $("span.admin-menu-tree-page-view-popup-arrow").live("click", function() {
78
+ $(this).closest("div.admin-menu-tree-page-view-popup").fadeOut("fast");
79
  return false;
80
  });
81
 
82
  // add page
83
  $(".admin-menu-tree-page-view-popup-add-here, .admin-menu-tree-page-view-popup-add-inside").live("click", function() {
84
+ var div_popup = $(this).closest("div.admin-menu-tree-page-view-popup");
85
  var post_id = div_popup.data("admin-menu-tree-page-view-current-post-id");
86
 
87
  var type = "after";
113
  });
114
 
115
  // search/filter pages
116
+ $("li.admin-menu-tree-page-filter input").keyup(function(e) {
117
+ var ul = $(this).closest("ul.admin-menu-tree-page-tree");
118
  ul.find("li").hide();
119
+ ul.find("li.admin-menu-tree-page-tree_headline,li.admin-menu-tree-page-filter").show();
120
  var s = $(this).val();
121
  var selector = "li:AminMenuTreePageContains('"+s+"')";
122
  var hits = ul.find(selector);
123
  if (hits.length > 0 || s != "") {
124
+ ul.find("div.admin-menu-tree-page-filter-reset").fadeIn("fast");
125
  ul.unhighlight();
126
  }
127
  if (s == "") {
128
+ ul.find("div.admin-menu-tree-page-filter-reset").fadeOut("fast");
129
  }
130
  ul.highlight(s);
131
  hits.show();
132
+
133
+ // hits can be childs of hidden li:s, so we must show the parents of the hits too
134
+ hits.each(function(i, elm) {
135
+ var parent = elm.parentNode;
136
+ if (parent) {
137
+ parent = $(parent);
138
+ parent.parent().addClass("admin-menu-tree-page-view-opened").removeClass("admin-menu-tree-page-view-closed");
139
+ //console.log(parent.parent());
140
+ parent.show();
141
+ }
142
+ });
143
+
144
+ // if no hits: tell the user so we have less confusion. confusion is bad.
145
+ var nohits_div = ul.find("div.admin-menu-tree-page-filter-nohits");
146
+ if (hits.length == 0) {
147
+ nohits_div.show();
148
+ } else {
149
+ nohits_div.hide();
150
+ }
151
+
152
  });
153
 
154
  // clear/reset filter and show all pages again
155
+ $("div.admin-menu-tree-page-filter-reset").click(function() {
156
  var $t = $(this);
157
+ var ul = $t.closest("ul.admin-menu-tree-page-tree");
158
  ul.find("li").fadeIn("fast");
159
  $t.fadeOut("fast");
160
+ $t.closest("li.admin-menu-tree-page-filter").find("input").val("").focus();
161
  ul.unhighlight();
162
+ ul.find("div.admin-menu-tree-page-filter-nohits").hide();
163
  });
164
 
165
  // label = hide in and focus input
166
+ $("li.admin-menu-tree-page-filter label, li.admin-menu-tree-page-filter input").click(function() {
167
  var $t = $(this);
168
+ $t.closest("li.admin-menu-tree-page-filter").find("label").hide();
169
+ $t.closest("li.admin-menu-tree-page-filter").find("input").focus();
170
  });
171
 
172
+ var trees = jQuery("ul.admin-menu-tree-page-tree");
173
 
174
  // add links to expand/collapse
175
+ trees.find("li.admin-menu-tree-page-view-has-childs > div").after("<div class='admin-menu-tree-page-expand' title='Show/Hide child pages' />");
176
+ trees.find("div.admin-menu-tree-page-expand").live("click", function(e) {
177
 
178
  e.preventDefault();
179
  var $t = $(this);
204
  if (isOpen) {
205
  admin_menu_tree_page_view_opened_posts.push(post_id);
206
  }
207
+
208
+ admin_menu_tree_page_view_save_opened_posts();
209
 
210
  });
211
 
212
 
213
  });
214
 
215
+ function admin_menu_tree_page_view_save_opened_posts() {
216
+ jQuery.cookie('admin-menu-tree-page-view-open-posts', admin_menu_tree_page_view_opened_posts.join(","));
217
+ }
218
+
219
  // array with all post ids that are open
220
  var admin_menu_tree_page_view_opened_posts = jQuery.cookie('admin-menu-tree-page-view-open-posts') || "";
221
  admin_menu_tree_page_view_opened_posts = admin_menu_tree_page_view_opened_posts.split(",");
styles.css CHANGED
@@ -18,8 +18,8 @@ li.toplevel_page_admin-menu-tree-page-tree_main .wp-submenu a {
18
 
19
 
20
  #adminmenu li.wp-has-current-submenu ul.admin-menu-tree-page-tree {
21
- border-left: 1px solid #aaa;
22
- border-right: 1px solid #aaa;
23
  padding-top: 5px;
24
  }
25
 
@@ -27,10 +27,10 @@ li.toplevel_page_admin-menu-tree-page-tree_main .wp-submenu a {
27
  #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li {
28
  position: relative;
29
  }
30
- #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li a {
31
- border-left-width: 1px;
32
  border-left-style: solid;
33
- border-right-width: 1px;
34
  border-right-style: solid;
35
  background: transparent url(page-small.gif) no-repeat 7px 2px !important;
36
  padding-left: 19px;
@@ -78,10 +78,10 @@ li.toplevel_page_admin-menu-tree-page-tree_main .wp-submenu a {
78
  }
79
 
80
  /* sublevels */
81
- #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-opened > a {
82
  background-image: url(page-small-minus.gif) !important;
83
  }
84
- #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-closed > a {
85
  background-image: url(page-small-plus.gif) !important;
86
  }
87
 
@@ -95,9 +95,9 @@ li.admin-menu-tree-page-filter
95
  margin: 0 0 0 0 !important;
96
  padding-left: 6px !important;
97
  border-left-style: solid;
98
- border-left-width: 1px;
99
  border-right-style: solid;
100
- border-right-width: 1px;
101
  }
102
 
103
  .wp-has-current-submenu li.admin-menu-tree-page-tree_headline,
@@ -186,7 +186,7 @@ li.admin-menu-tree-page-filter
186
  display: none;
187
  }
188
  .admin-menu-tree-page-view-popup li {
189
- text-decoration: underline;
190
  white-space: nowrap;
191
  }
192
 
@@ -251,6 +251,11 @@ li.admin-menu-tree-page-filter
251
  cursor: text;
252
  }
253
 
 
 
 
 
 
254
  ul.admin-menu-tree-page-tree .highlight {
255
  background-color: #fff879;
256
  color: #21759B;
@@ -269,10 +274,12 @@ ul.admin-menu-tree-page-tree ul .admin-menu-tree-page-expand {
269
  top: 0px;
270
  left: 9px;
271
  }
 
 
272
  ul.admin-menu-tree-page-tree ul {
273
  display: none;
274
  }
275
- ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-opened > ul {
276
  display: block;
277
  }
278
 
@@ -280,3 +287,7 @@ ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-opened > ul {
280
  ul.admin-menu-tree-page-tree span.child-count {
281
  color: #999999;
282
  }
 
 
 
 
18
 
19
 
20
  #adminmenu li.wp-has-current-submenu ul.admin-menu-tree-page-tree {
21
+ border-left: 0px solid #aaa;
22
+ border-right: 0px solid #aaa;
23
  padding-top: 5px;
24
  }
25
 
27
  #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li {
28
  position: relative;
29
  }
30
+ #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li div > a {
31
+ border-left-width: 0px;
32
  border-left-style: solid;
33
+ border-right-width: 0px;
34
  border-right-style: solid;
35
  background: transparent url(page-small.gif) no-repeat 7px 2px !important;
36
  padding-left: 19px;
78
  }
79
 
80
  /* sublevels */
81
+ #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-opened > div > a {
82
  background-image: url(page-small-minus.gif) !important;
83
  }
84
+ #adminmenu li .wp-submenu ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-closed > div > a {
85
  background-image: url(page-small-plus.gif) !important;
86
  }
87
 
95
  margin: 0 0 0 0 !important;
96
  padding-left: 6px !important;
97
  border-left-style: solid;
98
+ border-left-width: 0px;
99
  border-right-style: solid;
100
+ border-right-width: 0px;
101
  }
102
 
103
  .wp-has-current-submenu li.admin-menu-tree-page-tree_headline,
186
  display: none;
187
  }
188
  .admin-menu-tree-page-view-popup li {
189
+ /* text-decoration: underline; */
190
  white-space: nowrap;
191
  }
192
 
251
  cursor: text;
252
  }
253
 
254
+ .admin-menu-tree-page-filter-nohits {
255
+ display: none;
256
+ text-transform: none;
257
+ }
258
+
259
  ul.admin-menu-tree-page-tree .highlight {
260
  background-color: #fff879;
261
  color: #21759B;
274
  top: 0px;
275
  left: 9px;
276
  }
277
+
278
+
279
  ul.admin-menu-tree-page-tree ul {
280
  display: none;
281
  }
282
+ ul.admin-menu-tree-page-tree li.admin-menu-tree-page-view-opened > div > ul {
283
  display: block;
284
  }
285
 
287
  ul.admin-menu-tree-page-tree span.child-count {
288
  color: #999999;
289
  }
290
+
291
+ .admin-menu-tree-page-placeholder {
292
+ background-color: yellow;
293
+ }