对主题开发者很有用处的技术文章,外语不好就不给大家翻译了,自行参阅。
对主题开发者很有用处的技术文章,外语不好就不给大家翻译了,自行参阅。
So you’re a designer and you create beautiful looking themes for WordPress. However you find it quite hard making your beautiful theme come to life when trying to integrate it with WordPress. Or maybe you’re getting the hang of this whole “coding” thing (you know HTML and CSS after all) but you need a helping hand to lead you in the right direction when it comes to the more complex PHP stuff in WordPress. Or maybe you’re simply looking for a comprehensive tutorial on a certain aspect of WordPress programming.
If you are any of these people then this series of tutorials is for you. In this series I will cover most of the popular programming topics that designers tend to struggle with when doing development work for WordPress. You might even find that it’s not as hard as you think.
Part 1How to Build Custom Widgets for Your Themes
One of the most common features of almost every theme that has ever existed is the ability to customize your sidebar with widgets.
“WordPress Widgets (WPW) is like a plugin, but designed to provide a simple way to arrange the various elements of your sidebar content (known as “widgets”) without having to change any code.”
WordPress Codex
Widgets provide WordPress users an easy way to customize content without having to code anything. Unfortunately that means that it is down to theme developers to do it. But don’t worry it might not be as bad as you think. Since v2.8 WordPress has come packaged with a Widget API which makes it really easy to create custom widgets for your themes, and this is what we will be using to create our example widget.
Using the Widgets API
To create a new widget using the Widgets API you simply need to create a class that extends the standard widget class. Don’t worry if you don’t know what that means, because all you have to do is open up your functions.php
file and paste the following code:
class My_Widget extends WP_Widget{function My_Widget() {// register the widget}function widget($args, $instance) {// output the content of the widget}function form($instance) {// output the admin options form}function update($new_instance, $old_instance) {// processes the admin options form when saved}}add_action('widgets_init', create_function('', 'return register_widget("My_Widget");'));
This is the template code for your widget. Obviously you can rename each instance of “My_Widget” above to something more appropriate. The important thing to notice here is the four functions which will hold all of the functionality of our widget. It’s easier to explain what these functions do by showing you an example of a widget and explaining how these four functions make it work. So that’s exactly what I’ll do.Our Newsletter Signup Widget
For this example we are going to create a simple widget that lets users enter a title, some descriptive text and paste in their favourite newsletter signup form code (like MailChimp or CampaignMonitor for example). You will be able to change the title, description and code of the widget from the widget admin. So let’s get coding!
class Newsletter_Signup_Widget extends WP_Widget{// Register the widgetfunction Newsletter_Signup_Widget() {// Set some widget options$widget_options = array( 'description' => 'Allow users to signup to your newsletter easily', 'classname' => 'newsletter-signup' );// Set some control options (width, height etc)$control_options = array( 'width' => 300 );// Actually create the widget (widget id, widget name, options...)$this->WP_Widget( 'newsletter-signup-widget', 'Newsletter Signup', $widget_options, $control_options );}
First we create a new class that “extends WP_Widget” then we setup the widget in what is known as a constructor (a function with the same name as the class). Don’t worry about the technicalities here. Just accept that you need them and this is how they work.
In our constructor function first we set up some options in the $widget_options and $control_options variables. These are arrays of values that we pass into the WP_Widget() function to create our widget. The important values here are the description in $widget_options which will appear below your widget on the Widgets page, and the width (you can also specify height) in $control_options which will set the width of the widget admin box (when it is expanded).
Then we call the important WP_Widget() function. The four parameters that you need to pass in to this function are: a unique widget id (lowercase with no spaces), a widget title (which will be used on the widget admin), the $widget_options variable and finally the $control_options variable. Now we have setup our widget we can move on to the next function.
// Output the content of the widgetfunction widget($args, $instance) {extract( $args ); // Don't worry about this// Get our variables$title = apply_filters( 'widget_title', $instance['title'] );$text = $instance['text'];$code = $instance['code'];// This is defined when you register a sidebarecho$before_widget;// If our title isn't empty then show itif ( $title ) {echo$before_title . $title . $after_title;}// If our description isn't empty then show itif ( $text ) {echo '<p>'. $text .'</p>';}// If we have some code then output itif ( $code ) {echo$code;}// This is defined when you register a sidebarecho$after_widget;}
The widget() function is where we code the output that the users will see on your theme. Here we get the $title, $text and $code variables that are stored in the $instance array and simply echo them if they are not empty. If you need to do any HTML formatting of your content then here is the place to do it, but in our example we don’t need much.
Note that here we also echo four variables ($before_widget, $after_widget, $before_title, $after_title) that are defined when registering sidebars. Technically it is not essential to include these variables but if you leave them out you’re sidebar might become messed up and it certainly won’t be very flexible (especially if you are designing a theme that you want to distribute). So take my advice and just include them. Then we can move on.
// Output the admin options formfunction form($instance) {// These are our default values$defaults = array( 'title' => 'Example', 'text' => 'Subscribe to our newsletter using the form below.', 'code' => '' );// This overwrites any default values with saved values$instance = wp_parse_args( (array) $instance, $defaults );?><p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label><input id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo $instance['title']; ?>" type="text" class="widefat" /></p><p><label for="<?php echo $this->get_field_id('text'); ?>"><?php _e('Description:'); ?></label><input id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>" value="<?php echo $instance['text']; ?>" type="text" class="widefat" /></p><p><label for="<?php echo $this->get_field_id('code'); ?>"><?php _e('Code:'); ?></label><textarea id="<?php echo $this->get_field_id('code'); ?>" name="<?php echo $this->get_field_name('code'); ?>" rows="10" class="widefat"><?php echo $instance['code']; ?></textarea></p><?php}
The form() function is where we put the HTML that will appear in the admin form (when a widget is expanded). In our example we are going to need two text inputs (for the title & description) and a text area (for the code).
But before we create the HTML for the form we are going to set up some variables. $defaults is simply an array which holds our default values that will appear when you first add the widget to a sidebar in the widget admin. Don’t worry too much about the wp_parse_args() function. All this does is set up $instance with our array of values. If we have saved values then they will be used, otherwise it fall’s back to the $defaults.
Setting up the form itself is just basic HTML. We set the values of the HTML inputs using the $instance array which, again, is basic PHP. The thing to note is the WordPress helper functions that are used to make sure we get the input id’s and names right. Setting the id’s and names manually would be a nightmare (imagine loads of widgets made by different developers all with different id’s and names). So we just let WordPress do it for us and ask no questions. One more function to go.
// Processes the admin options form when savedfunction update($new_instance, $old_instance) {// Get the old values$instance = $old_instance;// Update with any new values (and sanitise input)$instance['title'] = strip_tags( $new_instance['title'] );$instance['text'] = strip_tags( $new_instance['text'] );$instance['code'] = $new_instance['code'];return$instance;}}
The update() function is where you process the data when a user clicks “Save” on the widget admin. This function should return a variable with all of your settings (in this case the $instance variable). The code is fairly self explanatory here. Just note that the names of the array indexes (the bit in square brackets) matches the names of your inputs in the functions above.
Also remember that it is your responsibility to sanitise user input when you are saving data, hence the use of the strip_tags() function to strip any nasty HTML from our variables.
add_action('widgets_init', create_function('', 'return register_widget("Example_Widget");'));
Finally we need to “hook” our new widget into WordPress using the add_action() function. I’m not going to explain how WordPress actions work in this article, suffice to say you must include this line for your code to function properly.Full Code Listing
class Newsletter_Signup_Widget extends WP_Widget{// Register the widgetfunction Newsletter_Signup_Widget() {// Set some widget options$widget_options = array( 'description' => 'Allow users to signup to your newsletter easily', 'classname' => 'newsletter-signup' );// Set some control options (width, height etc)$control_options = array( 'width' => 300 );// Actually create the widget (widget id, widget name, options...)$this->WP_Widget( 'newsletter-signup-widget', 'Newsletter Signup', $widget_options, $control_options );}// Output the content of the widgetfunction widget($args, $instance) {extract( $args ); // Don't worry about this// Get our variables$title = apply_filters( 'widget_title', $instance['title'] );$text = $instance['text'];$code = $instance['code'];// This is defined when you register a sidebarecho$before_widget;// If our title isn't empty then show itif ( $title ) {echo$before_title . $title . $after_title;}// If our description isn't empty then show itif ( $text ) {echo '<p>'. $text .'</p>';}// If we have some code then output itif ( $code ) {echo$code;}// This is defined when you register a sidebarecho$after_widget;}// Output the admin options formfunction form($instance) {// These are our default values$defaults = array( 'title' => 'Example', 'text' => 'Subscribe to our newsletter using the form below.', 'code' => '' );// This overwrites any default values with saved values$instance = wp_parse_args( (array) $instance, $defaults );?><p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label><input id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo $instance['title']; ?>" type="text" class="widefat" /></p><p><label for="<?php echo $this->get_field_id('text'); ?>"><?php _e('Description:'); ?></label><input id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>" value="<?php echo $instance['text']; ?>" type="text" class="widefat" /></p><p><label for="<?php echo $this->get_field_id('code'); ?>"><?php _e('Code:'); ?></label><textarea id="<?php echo $this->get_field_id('code'); ?>" name="<?php echo $this->get_field_name('code'); ?>" rows="10" class="widefat"><?php echo $instance['code']; ?></textarea></p><?php}// Processes the admin options form when savedfunction update($new_instance, $old_instance) {// Get the old values$instance = $old_instance;// Update with any new values (and sanitise input)$instance['title'] = strip_tags( $new_instance['title'] );$instance['text'] = strip_tags( $new_instance['text'] );$instance['code'] = $new_instance['code'];return$instance;}}add_action('widgets_init', create_function('', 'return register_widget("Newsletter_Signup_Widget");'));
Over to You
So now that you know how to create custom widgets for your themes in WordPress, let me know how you get on. I hope this article has been easy enough to follow but comprehensive enough to give you a good introduction to creating widgets for WordPress.