Added MenuWidget
Showing
6 changed files
with
351 additions
and
13 deletions
MenuWidget.js
0 → 100644
| 1 | // Lines of code vs jQuery: +30ish | ||
| 2 | // Performance gain: Yes | ||
| 3 | // Time tanken vs jQuery implementation: substantially less | ||
| 4 | // Does it work: Fuck yes (jQuery didn't, dear jQuery: LEARN TO CLONE PROPERLY!) | ||
| 5 | // Native JavaScript: Tried, tested and true! | ||
| 6 | |||
| 7 | var MenuWidget = function() { | ||
| 8 | var init = function(e) { | ||
| 9 | jQuery(document).ajaxSuccess(doLinks); | ||
| 10 | doLinks(); | ||
| 11 | } | ||
| 12 | |||
| 13 | var doLinks = function() { | ||
| 14 | var Links = document.getElementsByTagName('a'); | ||
| 15 | for (var i = 0, len = Links.length; i < len; i++) { | ||
| 16 | var strRel = ' ' + Links[i].rel + ' '; | ||
| 17 | if (strRel.indexOf(' TzMenuDone ') != -1) { | ||
| 18 | continue; | ||
| 19 | } | ||
| 20 | |||
| 21 | var strClass = ' ' + Links[i].className + ' '; | ||
| 22 | if (strClass.indexOf(' TzAddMenuItem ') != -1) { | ||
| 23 | Links[i].onclick = function() { return false; }; | ||
| 24 | addEvent(Links[i], 'click', addLink); | ||
| 25 | } | ||
| 26 | |||
| 27 | if (strClass.indexOf(' TzDelMenuItem ') != -1) { | ||
| 28 | Links[i].onclick = function() { return false; }; | ||
| 29 | addEvent(Links[i], 'click', delLink); | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | var addLink = function(e) { | ||
| 35 | var p = e.target; | ||
| 36 | while (p.tagName != 'body' && p.className != 'TzMenuPageList') { | ||
| 37 | p = p.parentNode; | ||
| 38 | } | ||
| 39 | if (p.tagName == 'body') { | ||
| 40 | console.error('Something missing in widget!'); | ||
| 41 | return; | ||
| 42 | } | ||
| 43 | |||
| 44 | var Container = document.createElement('span'); | ||
| 45 | Container.className = 'TzPageContainer'; | ||
| 46 | |||
| 47 | var Copy = p.getElementsByTagName('select')[0].cloneNode(true); | ||
| 48 | Copy.id = ''; | ||
| 49 | |||
| 50 | var Del = document.createElement('a'); | ||
| 51 | Del.href = '#'; | ||
| 52 | Del.appendChild(document.createTextNode('Del')); | ||
| 53 | Del.onclick = function() { return false; }; | ||
| 54 | Del.className = 'TzDelMenuItem'; | ||
| 55 | addEvent(Del, 'click', delLink); | ||
| 56 | |||
| 57 | Container.appendChild(Copy); | ||
| 58 | Container.appendChild(Del); | ||
| 59 | p.appendChild(Container); | ||
| 60 | } | ||
| 61 | |||
| 62 | var delLink = function(e) { | ||
| 63 | var Container = e.target; | ||
| 64 | while (Container.tagName != 'body' && Container.className != 'TzPageContainer') { | ||
| 65 | Container = Container.parentNode; | ||
| 66 | } | ||
| 67 | if (Container.tagName == 'body') { | ||
| 68 | console.error('Container not found'); | ||
| 69 | return; | ||
| 70 | } | ||
| 71 | |||
| 72 | Container.parentNode.removeChild(Container); | ||
| 73 | } | ||
| 74 | |||
| 75 | addEvent(window, 'load', init); | ||
| 76 | }(); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
MenuWidget.php
0 → 100644
| 1 | <?php | ||
| 2 | class MenuWidget extends WP_Widget { | ||
| 3 | public static function init() { | ||
| 4 | register_widget(__CLASS__); | ||
| 5 | |||
| 6 | if (is_admin()) { | ||
| 7 | _enqueue_script('tz-menu-widget', plugins_url('MenuWidget.js', __FILE__), Array('addEvent','jQuery')); | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | public function __construct() { | ||
| 12 | static $options = Array( | ||
| 13 | 'classname' => '' | ||
| 14 | , 'description' => 'Configurable menu to site hierarchy' | ||
| 15 | ); | ||
| 16 | |||
| 17 | parent::__construct('tz-menu-widget', 'Menu', $options); | ||
| 18 | } | ||
| 19 | |||
| 20 | public function widget($args, $instance) { | ||
| 21 | static $all_pages = false; | ||
| 22 | |||
| 23 | foreach ($instance['pages'] as $page) { | ||
| 24 | if ($instance['inclusive'] == 0) { | ||
| 25 | $instance['child_of'] = $page; | ||
| 26 | _list_pages($instance); | ||
| 27 | continue; | ||
| 28 | } | ||
| 29 | |||
| 30 | if (!$all_pages) { | ||
| 31 | $all_pages = get_pages(Array('sort_column' => 'menu_order')); | ||
| 32 | } | ||
| 33 | |||
| 34 | $instance['exclude'] = ''; | ||
| 35 | $children = Array($page); | ||
| 36 | foreach ($all_pages as $key => $wp_page) { | ||
| 37 | if ($wp_page->post_parent == $page || in_array($wp_page->post_parent, $children)) { | ||
| 38 | $children[] = $wp_page->ID; | ||
| 39 | } | ||
| 40 | |||
| 41 | if (!in_array($wp_page->ID, $children)) { | ||
| 42 | if (!empty($instance['exclude'])) { | ||
| 43 | $instance['exclude'] .= ','; | ||
| 44 | } | ||
| 45 | $instance['exclude'] .= $wp_page->ID; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | _list_pages($instance); | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | public function update($new_instance, $old_instance) { | ||
| 54 | $instance = $old_instance; | ||
| 55 | |||
| 56 | $instance['pages'] = Array(); | ||
| 57 | |||
| 58 | $instance['title_li'] = strip_tags(stripslashes($new_instance['title_li'])); | ||
| 59 | $instance['pages'] = (array)$new_instance['pages']; // (int)strip_tags(stripslashes($new_instance['page'])); | ||
| 60 | $instance['depth'] = (int)strip_tags(stripslashes($new_instance['depth'])); | ||
| 61 | $instance['inclusive'] = ($new_instance['inclusive'] == 'on' ? 1 : 0); | ||
| 62 | |||
| 63 | return $instance; | ||
| 64 | } | ||
| 65 | |||
| 66 | public function form($instance) { | ||
| 67 | $instance = _parse_args((array)$instance, Array('title_li' => '', 'pages' => Array(0 => ''), 'depth' => '', 'inclusive' => '')); | ||
| 68 | $checked = ($instance['inclusive'] == 1 ? ' checked="checked" ' : ''); | ||
| 69 | |||
| 70 | ?> | ||
| 71 | <p> | ||
| 72 | <label for="<?php echo $this->get_field_id('title_li'); ?>">Title</label> | ||
| 73 | <br /><input type="text" id="<?php echo $this->get_field_id('title_li'); ?>" name="<?php echo $this->get_field_name('title_li'); ?>" value="<?php echo attribute_escape($instance['title_li']); ?>" /> | ||
| 74 | </p> | ||
| 75 | |||
| 76 | <p class="TzMenuPageList"> | ||
| 77 | <label>Page(s)</label> <a href="#" class="TzAddMenuItem">Add Another</a> | ||
| 78 | <?php | ||
| 79 | foreach ($instance['pages'] as $key => $page) { | ||
| 80 | echo '<span class="TzPageContainer">'; | ||
| 81 | _dropdown_pages(Array('name' => $this->get_field_name('pages') . '[]', 'selected' => attribute_escape($instance['pages'][$key]), 'sort_column' => 'menu_order', 'echo' => 1)); | ||
| 82 | if ($key > 0) { | ||
| 83 | echo '<a href="#" class="TzDelMenuItem">Del</a>'; | ||
| 84 | } | ||
| 85 | echo '</span>'; | ||
| 86 | } | ||
| 87 | ?> | ||
| 88 | </p> | ||
| 89 | |||
| 90 | <p> | ||
| 91 | <label for="<?php echo $this->get_field_id('depth'); ?>">Depth</label> (0 for infinite) | ||
| 92 | <br /><input type="text" size="2" maxlength="2" id="<?php echo $this->get_field_id('depth'); ?>" name="<?php echo $this->get_field_name('depth'); ?>" value="<?php echo attribute_escape($instance['depth']); ?>" /> | ||
| 93 | </p> | ||
| 94 | |||
| 95 | <p> | ||
| 96 | <input type="checkbox" id="<?php echo $this->get_field_id('inclusive'); ?>" name="<?php echo $this->get_field_name('inclusive'); ?>" <?php echo $checked; ?> /> | ||
| 97 | <label for="<?php echo $this->get_field_id('inclusive'); ?>">Show Selected (vs just children)</label> | ||
| 98 | </p> | ||
| 99 | <?php | ||
| 100 | } | ||
| 101 | } | ||
| 102 | ?> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -11,7 +11,7 @@ class WP_Option implements ArrayAccess, Countable { | ... | @@ -11,7 +11,7 @@ class WP_Option implements ArrayAccess, Countable { |
| 11 | $this->_ns = $ns; | 11 | $this->_ns = $ns; |
| 12 | $this->_data = get_option($ns); | 12 | $this->_data = get_option($ns); |
| 13 | 13 | ||
| 14 | if (!is_null($defaults) && is_array($defaults)) { | 14 | if (is_array($defaults)) { |
| 15 | foreach ($this->_data as $key => $val) { | 15 | foreach ($this->_data as $key => $val) { |
| 16 | $defaults[$key] = $val; | 16 | $defaults[$key] = $val; |
| 17 | } | 17 | } |
| ... | @@ -53,5 +53,10 @@ class WP_Option implements ArrayAccess, Countable { | ... | @@ -53,5 +53,10 @@ class WP_Option implements ArrayAccess, Countable { |
| 53 | array_merge($this->_data, $data); | 53 | array_merge($this->_data, $data); |
| 54 | $this->save(); | 54 | $this->save(); |
| 55 | } | 55 | } |
| 56 | |||
| 57 | public function dump() { | ||
| 58 | echo "Here\n"; | ||
| 59 | print_r($this->_data); | ||
| 60 | } | ||
| 56 | } | 61 | } |
| 57 | ?> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 62 | ?> | ... | ... |
addEvent.js
0 → 100644
| 1 | /** | ||
| 2 | * addEvent & removeEvent -- cross-browser event handling | ||
| 3 | * Copyright (C) 2006-2007 Dao Gottwald | ||
| 4 | * | ||
| 5 | * This library is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU Lesser General Public | ||
| 7 | * License as published by the Free Software Foundation; either | ||
| 8 | * version 2.1 of the License, or (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This library is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * Lesser General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU Lesser General Public | ||
| 16 | * License along with this library; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | * | ||
| 19 | * Contact information: | ||
| 20 | * Dao Gottwald <dao at design-noir.de> | ||
| 21 | * | ||
| 22 | * @version 1.1.7 | ||
| 23 | */ | ||
| 24 | |||
| 25 | function addEvent(o, type, fn) { | ||
| 26 | o.addEventListener(type, fn, false); | ||
| 27 | } | ||
| 28 | function removeEvent(o, type, fn) { | ||
| 29 | o.removeEventListener(type, fn, false); | ||
| 30 | } | ||
| 31 | /*@cc_on if (!window.addEventListener) { | ||
| 32 | var addEvent = function(o, type, fn) { | ||
| 33 | if (!o._events) o._events = {}; | ||
| 34 | var queue = o._events[type]; | ||
| 35 | if (!queue) { | ||
| 36 | o._events[type] = [fn]; | ||
| 37 | if (!o._events._callback) | ||
| 38 | o._events._callback = function(e) { Event._callListeners(e, o) }; | ||
| 39 | o.attachEvent("on" + type, o._events._callback); | ||
| 40 | } else if (Event._fnIndex(o, type, fn) == -1) | ||
| 41 | queue.push(fn); | ||
| 42 | else return; | ||
| 43 | Event._mem.push([o, type, fn]); | ||
| 44 | }; | ||
| 45 | var removeEvent = function(o, type, fn) { | ||
| 46 | var i = Event._fnIndex(o, type, fn); | ||
| 47 | if (i < 0) return; | ||
| 48 | var queue = o._events[type]; | ||
| 49 | if (queue.calling) { | ||
| 50 | delete queue[i]; | ||
| 51 | if (queue.removeListeners) | ||
| 52 | queue.removeListeners.push(i); | ||
| 53 | else | ||
| 54 | queue.removeListeners = [i]; | ||
| 55 | } else | ||
| 56 | if (queue.length == 1) | ||
| 57 | Event._detach(o, type); | ||
| 58 | else | ||
| 59 | queue.splice(i, 1); | ||
| 60 | }; | ||
| 61 | var Event = { | ||
| 62 | AT_TARGET: 2, | ||
| 63 | BUBBLING_PHASE: 3, | ||
| 64 | stopPropagation: function() { this.cancelBubble = true }, | ||
| 65 | preventDefault: function() { this.returnValue = false }, | ||
| 66 | _mem: [], | ||
| 67 | _callListeners: function(e, o) { | ||
| 68 | e.stopPropagation = this.stopPropagation; | ||
| 69 | e.preventDefault = this.preventDefault; | ||
| 70 | e.currentTarget = o; | ||
| 71 | e.target = e.srcElement; | ||
| 72 | e.eventPhase = e.currentTarget == e.target ? this.AT_TARGET : this.BUBBLING_PHASE; | ||
| 73 | switch (e.type) { | ||
| 74 | case "mouseover": | ||
| 75 | e.relatedTarget = e.fromElement; | ||
| 76 | break; | ||
| 77 | case "mouseout": | ||
| 78 | e.relatedTarget = e.toElement; | ||
| 79 | } | ||
| 80 | var queue = o._events[e.type]; | ||
| 81 | queue.calling = true; | ||
| 82 | for (var i = 0, l = queue.length; i < l; i++) | ||
| 83 | if (queue[i]) | ||
| 84 | queue[i].call(o,e); | ||
| 85 | queue.calling = null; | ||
| 86 | if (!queue.removeListeners) | ||
| 87 | return; | ||
| 88 | if (queue.length == queue.removeListeners.length) { | ||
| 89 | this._detach(o, e.type); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | queue.removeListeners = queue.removeListeners.sort(function(a,b){return a-b}); | ||
| 93 | var i = queue.removeListeners.length; | ||
| 94 | while (i--) | ||
| 95 | queue.splice(queue.removeListeners[i], 1); | ||
| 96 | if (queue.length == 0) | ||
| 97 | this._detach(o, e.type); | ||
| 98 | else | ||
| 99 | queue.removeListeners = null; | ||
| 100 | }, | ||
| 101 | _detach: function(o, type) { | ||
| 102 | o.detachEvent("on" + type, o._events._callback); | ||
| 103 | delete o._events[type]; | ||
| 104 | }, | ||
| 105 | _fnIndex: function(o, type, fn) { | ||
| 106 | var queue = o._events[type]; | ||
| 107 | if (queue) | ||
| 108 | for (var i = 0, l = queue.length; i < l; i++) | ||
| 109 | if (queue[i] == fn) | ||
| 110 | return i; | ||
| 111 | return -1; | ||
| 112 | }, | ||
| 113 | _cleanup: function() { | ||
| 114 | for (var m, i = 0; m = this._mem[i]; i++) | ||
| 115 | if (m[1] != "unload" || m[2] == this._cleanup) | ||
| 116 | removeEvent(m[0], m[1], m[2]); | ||
| 117 | } | ||
| 118 | }; | ||
| 119 | addEvent(window, "unload", Event._cleanup); | ||
| 120 | } @*/ |
| ... | @@ -10,27 +10,26 @@ Author: Tenzing | ... | @@ -10,27 +10,26 @@ Author: Tenzing |
| 10 | die('PHP version 5.2.2 or greater is required'); | 10 | die('PHP version 5.2.2 or greater is required'); |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | new TzTools(); | 13 | TzTools::load(); |
| 14 | 14 | ||
| 15 | class TzTools { | 15 | class TzTools { |
| 16 | public function __construct() { | 16 | public static function load() { |
| 17 | set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__)); | 17 | // set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__)); |
| 18 | spl_autoload_register(Array('TzTools', 'loader')); | 18 | spl_autoload_register(Array(__CLASS__, 'autoloader')); |
| 19 | 19 | ||
| 20 | require_once(dirname(__FILE__) . '/wp_functions.php'); | 20 | require_once(dirname(__FILE__) . '/wp_functions.php'); |
| 21 | 21 | ||
| 22 | add_action('wp_print_scripts', Array('TzTools', 'registerScripts')); | 22 | _register_script('addEvent', plugins_url('addEvent.js', __FILE__)); |
| 23 | } | ||
| 24 | |||
| 25 | public static function registerScripts() { | ||
| 26 | _register_script('xmlhttpHandler', plugins_url('xmlhttpHandler.js', __FILE__)); | 23 | _register_script('xmlhttpHandler', plugins_url('xmlhttpHandler.js', __FILE__)); |
| 24 | |||
| 25 | add_action('widgets_init', Array('MenuWidget', 'init')); | ||
| 27 | } | 26 | } |
| 28 | 27 | ||
| 29 | public static function loader($class) { | 28 | public static function autoloader($class) { |
| 30 | $file = dirname(__FILE__) . '/' . $class . '.php'; | 29 | $file = dirname(__FILE__) . '/' . $class . '.php'; |
| 31 | if (is_file($file)) { | 30 | if (is_file($file)) { |
| 32 | require($file); | 31 | require($file); |
| 33 | } | 32 | } |
| 34 | } | 33 | } |
| 35 | } | 34 | } |
| 36 | ?> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 35 | ?> | ... | ... |
| ... | @@ -52,4 +52,40 @@ function _nonce_field() { | ... | @@ -52,4 +52,40 @@ function _nonce_field() { |
| 52 | $params = func_get_args(); | 52 | $params = func_get_args(); |
| 53 | return call_user_func_array('wp_nonce_field', $params); | 53 | return call_user_func_array('wp_nonce_field', $params); |
| 54 | } | 54 | } |
| 55 | ?> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 55 | |||
| 56 | function _loginout() { | ||
| 57 | $params = func_get_args(); | ||
| 58 | return call_user_func_array('wp_loginout', $params); | ||
| 59 | } | ||
| 60 | |||
| 61 | // I made this one because register_sidebar_widget() is fucked | ||
| 62 | function _register_sidebar_widget() { | ||
| 63 | $params = func_get_args(); | ||
| 64 | return call_user_func_array('wp_register_sidebar_widget', $params); | ||
| 65 | } | ||
| 66 | |||
| 67 | function _register_widget_control() { | ||
| 68 | $params = func_get_args(); | ||
| 69 | return call_user_func_array('wp_register_widget_control', $params); | ||
| 70 | } | ||
| 71 | |||
| 72 | function _parse_args() { | ||
| 73 | $params = func_get_args(); | ||
| 74 | return call_user_func_array('wp_parse_args', $params); | ||
| 75 | } | ||
| 76 | |||
| 77 | function _get_sidebars_widgets() { | ||
| 78 | $params = func_get_args(); | ||
| 79 | return call_user_func_array('wp_get_sidebars_widgets', $params); | ||
| 80 | } | ||
| 81 | |||
| 82 | function _list_pages() { | ||
| 83 | $params = func_get_args(); | ||
| 84 | return call_user_func_array('wp_list_pages', $params); | ||
| 85 | } | ||
| 86 | |||
| 87 | function _dropdown_pages() { | ||
| 88 | $params = func_get_args(); | ||
| 89 | return call_user_func_array('wp_dropdown_pages', $params); | ||
| 90 | } | ||
| 91 | ?> | ... | ... |
-
Please register or sign in to post a comment