-
-
Save jonathonbyrdziak/1229641 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* @Author Jonathon byrd | |
* @link http://www.jonathonbyrd.com | |
* @Package Wordpress | |
* @SubPackage Widgets | |
* @copyright Proprietary Software, Copyright Byrd Incorporated. All Rights Reserved | |
* @Since 1.0.0 | |
* | |
* Plugin Name: Master Widget | |
* Plugin URI: http://www.redrokk.com | |
* Description: <a href="http://redrokk.com" target="_blank">redrokk</a> Designs and develops software for WordPress, Drupal, Joomla, Cakephp, SugarCRM, Symfony and more! | |
* Version: 1.0.0 | |
* Author: redrokk | |
* Author URI: http://www.redrokk.com | |
* | |
* | |
*/ | |
defined('ABSPATH') or die("Cannot access pages directly."); | |
/** | |
* Register a New Master Widget | |
* | |
* The following is an array of settings for a single widget. | |
* All that you need to worry about is defining this array and the | |
* logic + administrative options for the widget is handled. | |
* | |
* The actual display of the widget is not handled by the Master | |
* Widget Class and requires that you provide a callback or a file that | |
* can be displayed when the widget is shown on the front end. | |
* | |
* A nice array of values is provided to you when displaying the widget | |
* UI, simply use extract($args) to retrieve three variables full of | |
* useful data. | |
* | |
* The following code should be placed within your theme/functions.php | |
* | |
* ************** ************* ************* | |
//build an array of settings | |
$docWidget = array( | |
'id' => 'first-custom-widget', //make sure that this is unique | |
'title' => 'aaaFirst Widget', | |
'classname' => 'st-custom-wi', | |
'do_wrapper' => true, | |
'show_view' => 'document_widget_view', | |
'fields' => array( | |
array( | |
'name' => 'Title', | |
'desc' => '', | |
'id' => 'title', | |
'type' => 'text', | |
'std' => '' | |
), | |
array( | |
'name' => 'Textarea', | |
'desc' => 'Enter big text here', | |
'id' => 'textarea_id', | |
'type' => 'textarea', | |
'std' => 'Default value 2' | |
), | |
array( | |
'name' => 'Select box', | |
'id' => 'select_id', | |
'type' => 'select', | |
'options' => array('Option 1', 'Option 2', 'Option 3') | |
), | |
array( | |
'name' => 'Radio', | |
'id' => 'radio_id', | |
'type' => 'radio', | |
'options' => array( | |
array('name' => 'Name 1', 'value' => 'Value 1'), | |
array('name' => 'Name 2', 'value' => 'Value 2') | |
) | |
), | |
array( | |
'name' => 'Checkbox', | |
'id' => 'checkbox_id', | |
'type' => 'checkbox' | |
), | |
) | |
); | |
//register this widget | |
register_master_widget($docWidget); | |
function document_widget_view( $args ) | |
{ | |
extract($args); | |
?> | |
the view for my widget | |
<?php | |
} | |
*/ | |
/** | |
* Only display once | |
* | |
* This line of code will ensure that we only run the master widget class | |
* a single time. We don't need to be throwing errors. | |
*/ | |
if (!class_exists('MasterWidgetClass')) : | |
/** | |
* Initializing | |
* | |
* The directory separator is different between linux and microsoft servers. | |
* Thankfully php sets the DIRECTORY_SEPARATOR constant so that we know what | |
* to use. | |
*/ | |
defined("DS") or define("DS", DIRECTORY_SEPARATOR); | |
/** | |
* Actions and Filters | |
* | |
* Register any and all actions here. Nothing should actually be called | |
* directly, the entire system will be based on these actions and hooks. | |
*/ | |
add_action( 'widgets_init', 'widgets_init_declare_registered', 1 ); | |
/** | |
* Register a widget | |
* | |
* @param $widget | |
*/ | |
function register_master_widget( $widget = null ) | |
{ | |
global $masterWidgets; | |
if (!isset($masterWidgets)) | |
{ | |
$masterWidgets = array(); | |
} | |
if (!is_array($widget)) return false; | |
$defaults = array( | |
'id' => '1', | |
'title' => 'Generic Widget', | |
'classname' => $widget['id'], | |
'do_wrapper' => true, | |
'description' => '', | |
'width' => 200, | |
'height' => 200, | |
'fields' => array(), | |
); | |
$masterWidgets[$widget['id']] = wp_parse_args($widget, $defaults); | |
return true; | |
} | |
/** | |
* Get the registered widgets | |
* | |
* @return array | |
*/ | |
function get_registered_masterwidgets() | |
{ | |
global $masterWidgets; | |
if (!did_action('init_master_widgets')) | |
do_action('init_master_widgets'); | |
return $masterWidgets; | |
} | |
/** | |
* Initialize the widgets | |
* | |
* @return boolean | |
*/ | |
function widgets_init_declare_registered() | |
{ | |
//initialziing variables | |
global $wp_widget_factory; | |
$widgets = get_registered_masterwidgets(); | |
//reasons to fail | |
if (empty($widgets) || !is_array($widgets)) return false; | |
foreach ($widgets as $id => $widget) | |
{ | |
$wp_widget_factory->widgets[$id] =& new MasterWidgetClass( $widget ); | |
} | |
return false; | |
} | |
/** | |
* Multiple Widget Master Class | |
* | |
* This class allows us to easily create qidgets without having to deal with the | |
* mass of php code. | |
* | |
* @author byrd | |
* @since 1.3 | |
*/ | |
class MasterWidgetClass extends WP_Widget | |
{ | |
/** | |
* Constructor. | |
* | |
* @param $widget | |
*/ | |
function MasterWidgetClass( $widget ) | |
{ | |
$this->widget = apply_filters('master_widget_setup', $widget); | |
$widget_ops = array( | |
'classname' => $this->widget['classname'], | |
'description' => $this->widget['description'] | |
); | |
$this->WP_Widget($this->widget['id'], $this->widget['title'], $widget_ops); | |
} | |
/** | |
* Display the Widget View | |
* | |
* @example extract the args within the view template | |
extract($args[1]); | |
* @param $args | |
* @param $instance | |
*/ | |
function widget($sidebar, $instance) | |
{ | |
//initializing variables | |
$widget = $this->widget; | |
$widget['number'] = $this->number; | |
$args = array( | |
'sidebar' => $sidebar, | |
'widget' => $widget, | |
'params' => $instance, | |
); | |
$show_view = apply_filters('master_widget_view', $this->widget['show_view'], $widget, $instance, $sidebar); | |
$title = apply_filters( 'master_widget_title', $instance['title'] ); | |
if ( $widget['do_wrapper'] ) | |
echo $sidebar['before_widget']; | |
if ( $title && $widget['do_wrapper'] ) | |
echo $sidebar['before_title'] . $title . $sidebar['after_title']; | |
//give people an opportunity | |
do_action('master_widget_show_'.$widget['id']); | |
//load the file if it exists | |
if (file_exists($show_view)) | |
require $show_view; | |
//call the function if it exists | |
elseif (is_callable($show_view)) | |
call_user_func( $show_view, $args ); | |
//echo if we can't figure it out | |
else echo $show_view; | |
if ($widget['do_wrapper']) | |
echo $sidebar['after_widget']; | |
} | |
/** | |
* Update from within the admin | |
* | |
* @param $new_instance | |
* @param $old_instance | |
*/ | |
function update($new_instance, $old_instance) | |
{ | |
//initializing variables | |
$new_instance = array_map('strip_tags', $new_instance); | |
$instance = wp_parse_args($new_instance, $old_instance); | |
return $instance; | |
} | |
/** | |
* Display the options form | |
* | |
* @param $instance | |
*/ | |
function form($instance) | |
{ | |
//reasons to fail | |
if (empty($this->widget['fields'])) return false; | |
$defaults = array( | |
'id' => '', | |
'name' => '', | |
'desc' => '', | |
'type' => '', | |
'options' => '', | |
'std' => '', | |
); | |
do_action('master_widget_before'); | |
foreach ($this->widget['fields'] as $field) | |
{ | |
//making sure we don't throw strict errors | |
$field = wp_parse_args($field, $defaults); | |
$meta = false; | |
if (isset($field['id']) && array_key_exists($field['id'], $instance)) | |
@$meta = attribute_escape($instance[$field['id']]); | |
if ($field['type'] != 'custom' && $field['type'] != 'metabox') | |
{ | |
echo '<p><label for="',$this->get_field_id($field['id']),'">'; | |
} | |
if (isset($field['name']) && $field['name']) echo $field['name'],':'; | |
switch ($field['type']) | |
{ | |
case 'text': | |
echo '<input type="text" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '" value="', ($meta ? $meta : @$field['std']), '" class="vibe_text" />', | |
'<br/><span class="description">', @$field['desc'], '</span>'; | |
break; | |
case 'textarea': | |
echo '<textarea class="vibe_textarea" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '" cols="60" rows="4" style="width:97%">', $meta ? $meta : @$field['std'], '</textarea>', | |
'<br/><span class="description">', @$field['desc'], '</span>'; | |
break; | |
case 'select': | |
echo '<select class="vibe_select" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '">'; | |
foreach ($field['options'] as $option) | |
{ | |
echo '<option', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>'; | |
} | |
echo '</select>', | |
'<br/><span class="description">', @$field['desc'], '</span>'; | |
break; | |
case 'radio': | |
foreach ($field['options'] as $option) | |
{ | |
echo '<input class="vibe_radio" type="radio" name="', $this->get_field_name($field['id']), '" value="', $option['value'], '"', $meta == $option['value'] ? ' checked="checked"' : '', ' />', | |
$option['name']; | |
} | |
echo '<br/><span class="description">', @$field['desc'], '</span>'; | |
break; | |
case 'checkbox': | |
echo '<input type="hidden" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '" /> ', | |
'<input class="vibe_checkbox" type="checkbox" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '"', $meta ? ' checked="checked"' : '', ' /> ', | |
'<br/><span class="description">', @$field['desc'], '</span>'; | |
break; | |
case 'custom': | |
echo $field['std']; | |
break; | |
} | |
if ($field['type'] != 'custom' && $field['type'] != 'metabox') | |
{ | |
echo '</label></p>'; | |
} | |
} | |
do_action('master_widget_after'); | |
return; | |
} | |
}// ends Master Widget Class | |
endif; //if !class_exists |
<?php | |
/** | |
* @Author Jonathon byrd | |
* @link http://www.jonathonbyrd.com | |
* @Package Wordpress | |
* @SubPackage Widgets | |
* @copyright Proprietary Software, Copyright Byrd Incorporated. All Rights Reserved | |
* @Since 1.0.0 | |
* | |
* Plugin Name: Document Widget | |
* Plugin URI: http://www.redrokk.com | |
* Description: <a href="http://redrokk.com" target="_blank">redrokk</a> Designs and develops software for WordPress, Drupal, Joomla, Cakephp, SugarCRM, Symfony and more! | |
* Version: 1.0.0 | |
* Author: redrokk | |
* Author URI: http://www.redrokk.com | |
* | |
* | |
*/ | |
defined('ABSPATH') or die("Cannot access pages directly."); | |
/** | |
* Initializing | |
* | |
* The directory separator is different between linux and microsoft servers. | |
* Thankfully php sets the DIRECTORY_SEPARATOR constant so that we know what | |
* to use. | |
*/ | |
defined("DS") or define("DS", DIRECTORY_SEPARATOR); | |
/** | |
* Actions and Filters | |
* | |
* Register any and all actions here. Nothing should actually be called | |
* directly, the entire system will be based on these actions and hooks. | |
*/ | |
add_action( 'widgets_init', create_function( '', 'register_widget("Document_Widget");' ) ); | |
/** | |
* | |
* @author byrd | |
* Document Widget | |
*/ | |
class Document_Widget extends WP_Widget | |
{ | |
/** | |
* Constructor | |
* | |
* Registers the widget details with the parent class | |
*/ | |
function Document_Widget() | |
{ | |
// widget actual processes | |
parent::WP_Widget( $id = 'foo_widget', $name = get_class($this), $options = array( 'description' => 'A Foo Widget' ) ); | |
} | |
function form($instance) | |
{ | |
// outputs the options form on admin | |
?> | |
Form goes here | |
<?php | |
} | |
function update($new_instance, $old_instance) | |
{ | |
// processes widget options to be saved | |
$instance = wp_parse_args($old_instance, $new_instance); | |
return $instance; | |
} | |
function widget($args, $instance) | |
{ | |
// outputs the content of the widget | |
extract( $args ); | |
$title = apply_filters( 'widget_title', $instance['title'] ); | |
echo $before_widget; | |
if ( $title ) | |
echo $before_title . $title . $after_title; | |
?> | |
Widget view to users goes here | |
<?php | |
} | |
} |
The new form() method looks far more powerful. I'll update my plugin to use the new method tonight. I'll let you know how it goes.
@CHANGELOG 5/29/2012.2 : Added Shortcode WYSIWYG button support
The Empty_Widget class now turns your widget into a shortcode with a supporting WYSIWYG custom button. Upon clicking the button you will see the same widget options available to you for sidebars. You also have the option to view a preview of what the widget will look like when creating the shortcode. Finally, upon hitting submit within the buttons popup, the shortcode string will be created and inserted into your post or page.
@CHANGELOG 5/30/2012 : Added additional form fields
The additional fields are select boxes of the default wordpress data, such as: capabilities, categories, roles, users n more!
Hi - this plugin looks epic!
I added the widget, but clicking save doesnt save the values, returns back to default. Using the latest WordPress version. Any ideas?
Sorry, I've been making lots of changes. I'm working on it right now and should post an update within the hour.
Ahh hehe thanks man! Awesome work - just post a notice when updated, working on a project as we speak and your widget is SUPER USEFUL and easy to understand and manage!!
Alright! Should be good to go bro. I tested it in WP 3.3.2, worked great.
Oh yeah! Works GREAT! Thanks so much man....perfect!!!
Just something weird...
I use the function "dynamic_sidebar( 'Home Pane' )" to get the contents of my Widget's HTML on my Home Page, but it only gets the default values set in the Widget's php file, not the values from WordPress Widget itself...not sure why, any advice?
Thanks for bug testin this with me today :) I just had to toggle lines 336 and 337.
$field['args']['name'] = $element_name = $this->get_field_name($id);
is now above
$id = $this->get_field_id($id);
Hehe I'm trying :) it's now doing that no saving thing again....
The toggle makes the value show up correctly, but in the widget settings it doesnt return the value just keeps the default. However it does update the fields...
Fixed!
// grabbing the meta value
if (array_key_exists($id, $instance))
@$meta = attribute_escape($instance[$id]);
else
$meta = $default;
Had to move this above the if (!$shortcode)
command
Nice one bro! Working great!! Thank you very much for looking into this today, and the additions you implemented are epic! bows down
Johnathan,
The checkbox part of the updated form() method has been working perfectly for me, thanks. I just wanted to point out that according to the Codex, attribute_escape() (line 316 of the abstract class' form method) has been deprecated since 2.8.0. That should probably be changed to esc_attr()?
Thanks again for releasing this excellent code.
Jonathan,
Just added a textarea to my plugin and thought you should know that the line break on line 349 of the abstract class' form method was inserting all that whitespace into the textarea when clicking save in the admin. I moved that line up so it doesn't break right in the "echo $meta" output. That fixed the issue. Not sure if anyone else is experiencing this issue, but I thought you'd want to know incase you wanted to update that section.
You're welcome, looking forward to the updates. Don't forget about changing attribute_escape() to esc_attr() on line 316. :-)
(Someday, I'll figure out github better to submit a real patch. Hopefully this is useful.)
Possible bug: If there are multiple checkboxes/radioes in a single field, clicking any label toggles the first checkbox or radio button because of the id/for attributes.
I fixed that with the following:
` $_name): ?>
<input name="" id=""
value="" type=""
class="" />
<label class="<?php echo $element_name; ?>" for="<?php echo $id; ?>">
<?php echo $_name; ?>
</label>
`
For some reason, using only <?php echo $_value; ?>
as the id/for attribute didn't work. Also, I moved the <br />
tag inside the foreach
so each checkbox/radio button gets its own line.
I love this thing. Thanks!
Should've previewed that. Sorry. I can't get code to paste. Weird. Anyway...snippet is here: http://pastebin.com/wTxPhvTj
(Sorry if this got submitted. I posted this and then it disappeared. Also, someday I'll learn github, but right now my priority is submitting this patch.)
When using multiple checkboxes or radio buttons in a single option, clicking on any label toggles the first box/button. This is because the id/for values of the input/label aren't unique. I changed that, and now they work. I also moved the linebreak into the foreach loop so that each box/button gets its own line.
Code here: http://pastebin.com/wTxPhvTj
Thanks buddy, I don't think I ever received an email that you commented, but noticed it now and made the adjustment.
Hello, when ui try to activate this plugin i get error:
Fatal error: Class 'Empty_Widget_Abstract' not found in /plugins/123/CustomWidgetFile.php on line 28
why i get this error?
thanks for help.
I'm using your code on some widgets and found a little problem using the "select_categories" field type.
On line 422:
<?php wp_dropdown_categories($args); ?>
You forgot to actually pass arguments to wp_dropdown_categories().
This is what I'm using and is working fine:
<?php wp_dropdown_categories( array( 'id' => $id, 'name' => $element_name, 'class' => $class, 'selected' => $meta ) ); ?>
Hope it helps :)
Nice @ozzysong I'll get that added
I'm using your class and i've noticed that it doesn't allow widgets to be localized/translated. Anytime i try using __() to localize a string (widget title/fields names/desc/ etc), it returns an unexpected "(" error. Any idea how to fix it?
Update 21st November
This also seem to cause issues with WPML when trying to translate widgets fields/titles they are not being recognized.
Hello!
First of all thanx for this code, it's very well made and I'm learning a lot by working with it.
I made a few experiments in the last year, and everything was working fine.
then I've noticed that on versions after wordpress 4.0 the tinymce popup is not working properly.
when you click to submit, it loads the homepage into the popup, and it doesn't close it, nor it adds the actual shortcode into the post content..
I've tried to search around and I found out that actually there have been some changes in tinymce popups, but I've not been able to figure out how to fix your code..
could you have a look at this issue please?
cheers!
and Merry Christmas!
Andrea
Thanks for an amazing tutorial on how to create widgets. WordPress give a best drag and drop design option through widgets. This components allow users to add design and structure control elements through WordPress themes. Create Widget Plugin
Careful! In widget.class.phpn at line 176, it shows
parent::WP_Widget(
which is deprecated. However, the fix is simple, simply replace WP_Widget(
by __construct(
.
This piece of code was so useful and makes the plugin developement so much streamlined, thanks alot ♥
@CHANGELOG 5/29/2012 : Adjusted the default value handling with wp-admin configurations
The system was using an old form field creation method. I've since updated my other plugins and now this class to use a new style form field creation method. This new method is quite a bit cleaner and handles the default field values in a much more stable manner. This new method will also allow us to expand on the default form functionality with ease.