Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Difference between revisions of "Widgets API"

(fixed a bug)
(Example)
 
(137 intermediate revisions by 67 users not shown)
Line 1: Line 1:
 
{{Languages|
 
{{Languages|
 
{{en|Widgets API}}
 
{{en|Widgets API}}
  +
{{es|API de Widget}}
{{ja|WordPress ウィジェット API}}
 
{{zh-cn|挂件接口}}
+
{{ja|Widgets_API}}
  +
{{zh-cn|小工具接口}}
 
}}
 
}}
  +
  +
{{copyedit}}
   
 
==Widgets API==
 
==Widgets API==
This page contains the technical documentation of the WordPress Widgets API (Application Programming Interface). The intended audience for this information includes WordPress theme authors, plug-in authors and anyone who would like to write a stand-alone widget. This document assumes a basic understanding of PHP scripting.
+
This page contains the technical documentation for the WordPress Widgets API and is written for developers. If you're not a developer you may want to review the [[WordPress_Widgets | Widgets]] page.
 
A widget is a [http://www.php.net/manual/en/language.functions.php PHP function] that echoes string data to STDOUT when called. To turn such a PHP function into a Wordpress Widget it must be registered as such. This is done using a [http://www.php.net/manual/en/language.pseudo-types.php PHP callback] (a ''Pseudo-Type'' in PHP documentation) that is registered by a wordpress widget API function.
 
 
register_sidebar_widget($callback);
 
   
  +
In technical terms: a WordPress Widget is a [http://php.net/manual/en/language.oop5.php PHP object] that echoes string data to [http://en.wikipedia.org/wiki/Stdout#Standard_output_.28stdout.29 STDOUT] when its <tt>widget()</tt> method is called. It's located in {{Trac|wp-includes/widgets.php}}.
The Wordpress widget API is located in {{Trac|wp-includes/widgets.php}}.
 
   
 
== Function Reference ==
 
== Function Reference ==
Line 22: Line 21:
 
{| class="widefat"
 
{| class="widefat"
 
|- style="background:#464646; color:#d7d7d7;"
 
|- style="background:#464646; color:#d7d7d7;"
! '''Sidebar Functions'''
+
! '''Widget Functions'''
 
|-
 
|-
 
|
 
|
* <tt>[[Function Reference/is_active_sidebar|is_active_sidebar]]</tt>
+
* <tt>[[Function Reference/is_active_widget | is_active_widget()]]</tt>
* <tt>[[Function Reference/register_sidebars|register_sidebars]]</tt>
+
* <tt>[[Function Reference/the_widget | the_widget()]]</tt>
* <tt>[[Function Reference/register_sidebar|register_sidebar]]</tt>
+
* <tt>[[Function Reference/register_widget | register_widget()]]</tt>
* <tt>[[Function Reference/unregister_sidebar|unregister_sidebar]]</tt>
+
* <tt>[[Function Reference/unregister_widget | unregister_widget()]]</tt>
* <tt>[[Function Reference/is_dynamic_sidebar|is_dynamic_sidebar]]</tt>
 
* <tt>[[Function Reference/dynamic_sidebar|dynamic_sidebar]]</tt>
 
* <tt>[[Function Reference/register_sidebar_widget|register_sidebar_widget]]</tt>
 
* <tt>[[Function Reference/unregister_sidebar_widget|unregister_sidebar_widget]]</tt>
 
* <tt>[[Function Reference/wp_register_sidebar_widget|wp_register_sidebar_widget]]</tt>
 
* <tt>[[Function Reference/wp_unregister_sidebar_widget|wp_unregister_sidebar_widget]]</tt>
 
* <tt>[[Function Reference/wp_get_sidebars_widgets|wp_get_sidebars_widgets]]</tt>
 
* <tt>[[Function Reference/wp_set_sidebars_widgets|wp_set_sidebars_widgets]]</tt>
 
 
|}
 
|}
   
Line 43: Line 34:
 
{| class="widefat"
 
{| class="widefat"
 
|- style="background:#464646; color:#d7d7d7;"
 
|- style="background:#464646; color:#d7d7d7;"
! '''Widget Functions'''
+
! '''internal Functions'''
 
|-
 
|-
 
|
 
|
* <tt>[[Function Reference/is_active_widget|is_active_widget]]</tt>
+
* <tt>[[Function Reference/wp_register_widget_control | wp_register_widget_control()]]</tt>
* <tt>[[Function Reference/the_widget|the_widget]]</tt>
+
* <tt>[[Function Reference/wp_unregister_widget_control | wp_unregister_widget_control()]]</tt>
* <tt>[[Function Reference/register_widget|register_widget]]</tt>
+
* <tt>[[Function Reference/wp_convert_widget_settings | wp_convert_widget_settings()]]</tt>
* <tt>[[Function Reference/unregister_widget|unregister_widget]]</tt>
+
* <tt>[[Function Reference/wp_get_widget_defaults | wp_get_widget_defaults()]]</tt>
* <tt>[[Function Reference/register_widget_control|register_widget_control]]</tt>
+
* <tt>[[Function Reference/wp_widget_description | wp_widget_description()]]</tt>
* <tt>[[Function Reference/unregister_widget_control|unregister_widget_control]]</tt>
 
* <tt>[[Function Reference/wp_register_widget_control|wp_register_widget_control]]</tt>
 
* <tt>[[Function Reference/wp_unregister_widget_control|wp_unregister_widget_control]]</tt>
 
* <tt>[[Function Reference/wp_convert_widget_settings|wp_convert_widget_settings]]</tt>
 
* <tt>[[Function Reference/wp_get_widget_defaults|wp_get_widget_defaults]]</tt>
 
* <tt>[[Function Reference/wp_widget_description|wp_widget_description]]</tt>
 
 
|}
 
|}
   
 
|}
 
|}
   
  +
== Developing Widgets ==
'''Note:''' It is advised '''not''' to use the functions starting with "''wp_''" as these could change in subsequent releases. This is why we use [[Function Reference/register_sidebar_widget|register_sidebar_widget()]] instead of [[Function Reference/wp_register_sidebar_widget|wp_register_sidebar_widget()]].
 
   
  +
To create a widget, you only need to extend the standard <tt>WP_Widget</tt> class and some of its functions.
== Developing New Widgets (2.8 and up) ==
 
   
  +
That base class also contains information about the functions that must be extended to get a working widget.
Widget development has become easier since version 2.8. To create a widget, you only need to extend the standard widget class and some of it's functions.
 
   
  +
The <tt>WP_Widget</tt> class is located in {{Trac|wp-includes/class-wp-widget.php}}.
That base class also contains information about the function that must be extended to get a working widget.
 
   
 
=== Default Usage ===
 
=== Default Usage ===
 
<pre>
 
<pre>
 
class My_Widget extends WP_Widget {
 
class My_Widget extends WP_Widget {
  +
function My_Widget() {
 
  +
/**
// widget actual processes
 
  +
* Sets up the widgets name etc
  +
*/
  +
public function __construct() {
  +
$widget_ops = array(
  +
'classname' => 'my_widget',
  +
'description' => 'My Widget is awesome',
  +
);
  +
parent::__construct( 'my_widget', 'My Widget', $widget_ops );
 
}
 
}
   
  +
/**
function widget($args, $instance) {
 
  +
* Outputs the content of the widget
  +
*
  +
* @param array $args
  +
* @param array $instance
  +
*/
  +
public function widget( $args, $instance ) {
 
// outputs the content of the widget
 
// outputs the content of the widget
 
}
 
}
   
  +
/**
function update($new_instance, $old_instance) {
 
// processes widget options to be saved
+
* Outputs the options form on admin
  +
*
  +
* @param array $instance The widget options
  +
*/
  +
public function form( $instance ) {
  +
// outputs the options form on admin
 
}
 
}
   
  +
/**
function form($instance) {
 
  +
* Processing widget options on save
// outputs the options form on admin
 
  +
*
  +
* @param array $new_instance The new options
  +
* @param array $old_instance The previous options
  +
*
  +
* @return array
  +
*/
  +
public function update( $new_instance, $old_instance ) {
  +
// processes widget options to be saved
 
}
 
}
 
}
 
}
  +
</pre>
register_widget('My_Widget');
 
  +
The widget can then be registered using the <code>widgets_init</code> hook:
  +
  +
PHP 5.3+ only:
  +
<pre>
  +
add_action( 'widgets_init', function(){
  +
register_widget( 'My_Widget' );
  +
});
  +
</pre>
  +
PHP 5.2+:
  +
<pre>
  +
add_action('widgets_init',
  +
create_function('', 'return register_widget("My_Widget");')
  +
);
 
</pre>
 
</pre>
   
 
=== Example ===
 
=== Example ===
   
This sample code creates a Widget named ''FooWidget'' that has a settings form to change the display title.
+
This sample code creates a Widget named <tt>''Foo_Widget''</tt> that has a settings form to change the display title.
   
 
<pre>
 
<pre>
 
/**
 
/**
  +
* Adds Foo_Widget widget.
* FooWidget Class
 
 
*/
 
*/
class FooWidget extends WP_Widget {
+
class Foo_Widget extends WP_Widget {
/** constructor */
 
function FooWidget() {
 
parent::WP_Widget(false, $name = 'FooWidget');
 
}
 
   
  +
/**
/** @see WP_Widget::widget */
 
function widget($args, $instance) {
+
* Register widget with WordPress.
  +
*/
extract( $args );
 
  +
function __construct() {
?>
 
  +
parent::__construct(
<?php echo $before_widget; ?>
 
  +
'foo_widget', // Base ID
<?php echo $before_title
 
  +
esc_html__( 'Widget Title', 'text_domain' ), // Name
. $instance['title']
 
  +
array( 'description' => esc_html__( 'A Foo Widget', 'text_domain' ), ) // Args
. $after_title; ?>
 
  +
);
Hello, World!
 
  +
}
<?php echo $after_widget; ?>
 
<?php
 
}
 
   
  +
/**
/** @see WP_Widget::update */
 
  +
* Front-end display of widget.
function update($new_instance, $old_instance) {
 
  +
*
return $new_instance;
 
  +
* @see WP_Widget::widget()
}
 
  +
*
  +
* @param array $args Widget arguments.
  +
* @param array $instance Saved values from database.
  +
*/
  +
public function widget( $args, $instance ) {
  +
echo $args['before_widget'];
  +
if ( ! empty( $instance['title'] ) ) {
  +
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
  +
}
  +
echo esc_html__( 'Hello, World!', 'text_domain' );
  +
echo $args['after_widget'];
  +
}
   
  +
/**
/** @see WP_Widget::form */
 
  +
* Back-end widget form.
function form($instance) {
 
  +
*
$title = esc_attr($instance['title']);
 
  +
* @see WP_Widget::form()
?>
 
  +
*
<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></label></p>
 
  +
* @param array $instance Previously saved values from database.
<?php
 
  +
*/
}
 
  +
public function form( $instance ) {
  +
$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'text_domain' );
  +
?>
  +
<p>
  +
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label>
  +
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
  +
</p>
  +
<?php
  +
}
  +
  +
/**
  +
* Sanitize widget form values as they are saved.
  +
*
  +
* @see WP_Widget::update()
  +
*
  +
* @param array $new_instance Values just sent to be saved.
  +
* @param array $old_instance Previously saved values from database.
  +
*
  +
* @return array Updated safe values to be saved.
  +
*/
  +
public function update( $new_instance, $old_instance ) {
  +
$instance = array();
  +
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
  +
  +
return $instance;
  +
}
   
} // class FooWidget
+
} // class Foo_Widget
 
</pre>
 
</pre>
   
This sample widget can then be registered in the ''widgets_init'' hook:
+
This sample widget can then be registered in the <tt>'widgets_init'</tt> hook:
   
 
<pre>
 
<pre>
// register FooWidget widget
+
// register Foo_Widget widget
  +
function register_foo_widget() {
add_action('widgets_init', create_function('', 'return register_widget("FooWidget");'));
 
  +
register_widget( 'Foo_Widget' );
  +
}
  +
add_action( 'widgets_init', 'register_foo_widget' );
 
</pre>
 
</pre>
   
  +
Note : You must use <tt>[[Function_Reference/get_field_name|get_field_name()]]</tt> and <tt>get_field_id()</tt> function to generate form element name and id.
That's all. You will automatically get a multi-widget. No special tweaks needed any longer for that.
 
   
  +
=== Example With Namespaces ===
More information is available in the [[Version 2.8#New_Widgets_API|version information]].
 
   
  +
If you use PHP 5.3. with namespaces you should call the constructor directly as in the following example:
== Developing New Widgets ==
 
   
  +
<pre>
The Google Search widget which was included in the deprecated (i.e. not needed since WordPress 2.2) [http://downloads.wordpress.org/plugin/widgets.zip original widget plugin] is commented within inches of its life, so consider that your tutorial. Additionally, there are a few guidelines to follow:
 
  +
namespace a\b\c;
   
  +
class My_Widget_Class extends \WP_Widget {
* Don’t execute any code while the plugin is being loaded. Use the plugins_loaded hook or you risk fatal errors due to undefined functions, or missing the boat completely because your plugin loaded before the one it depends on.
 
  +
function __construct() {
* Use register_sidebar_widget($name, $callback) to add your widget to the admin interface.
 
  +
parent::__construct( 'baseID', 'name' );
* Follow this template:
 
  +
}
  +
// ... rest of functions
  +
}
  +
</pre>
  +
  +
and call the <tt>register_widget()</tt> with:
   
 
<pre>
 
<pre>
  +
add_action( 'widgets_init', function(){
function widget_myuniquewidget($args) {
 
  +
register_widget( 'a\b\c\My_Widget_Class' );
extract($args);
 
  +
});
?>
 
<?php echo $before_widget; ?>
 
<?php echo $before_title
 
. 'My Unique Widget'
 
. $after_title; ?>
 
Hello, World!
 
<?php echo $after_widget; ?>
 
<?php
 
}
 
register_sidebar_widget('My Unique Widget',
 
'widget_myuniquewidget');
 
 
</pre>
 
</pre>
   
  +
(see: http://stackoverflow.com/questions/5247302/php-namespace-5-3-and-wordpress-widget/5247436#5247436)
'''Important''': To use the above in a plugin, wrap it with:
 
   
  +
That's all. You will automatically get a multi-widget. No special tweaks needed any longer for that.
function widget_myuniquewidget_register() {
 
--the above goes here--
 
register_sidebar_widget('My Unique Widget','widget_myuniquewidget');}
 
add_action('init', widget_myuniquewidget_register);
 
   
  +
More information is available in the [[Version 2.8#New_Widgets_API|version 2.8 information]].
* Don’t leave out $before_widget, $after_widget, $before_title, or $after_title by accident. They are required for compatibility with various themes.
 
* Name your widget and its functions carefully. Those strings will be used as HTML attributes and you don’t want to cause identical id’s in a single HTML document.
 
* Localization is done internally to preserve the HTML id attribute. If you want your widget name localized with a textdomain, pass array($name, $textdomain) instead of $name.
 
* To accommodate multi-widgets (e.g. Text and RSS) you can also pass a replacement value with the name: array($name_as_sprintf_pattern, $textdomain, $replacement). See the source.
 
* You may use the variables mentioned above in different ways, or neglect them in some circumstances. Some widgets may not need a title, for example. Some widgets will use the $before_widget and $after_widget several times, or as arguments to tell another template tag how to format its output.
 
* Optionally, use the following syntax to add a configuration page to the admin. Your callback will be used within the main form, so you must not include any <form> tags or a form submit button.
 
   
  +
== Displaying Widgets and Widget Areas ==
  +
There are at least 3 ways that Widgets can be displayed:
  +
  +
=== Widget Areas ===
  +
The first, and most common, is by adding the desired [[Glossary#Widget | Widget]] to a [[Widgetizing_Themes#How_to_Register_a_Widget_Area | Widget Area]] via the [[Appearance_Widgets_Screen | Appearance -> Widgets menu]] in the Administration Screens.
  +
  +
WordPress comes with some predefined Widget Areas that each have unique identifiers (view the source of the Widgets page to see them) that you'll need to know in order to display the Widget Area. If the predefined Widget Areas are insufficient for your needs you may [[Glossary#register | register]] a [[Widgetizing_Themes#How_to_Register_a_Widget_Area | custom Widget Areas]].
  +
  +
When you're ready you can display that Widget Area by inserting the following code into whichever Theme file you desire:
  +
  +
<pre id="how-to-display-a-widget-area"><?php if ( dynamic_sidebar('example_widget_area_name') ) : else : endif; ?></pre>
  +
  +
That code displays all of the Widgets added to that Widget Area.
  +
  +
== Display Widget Area Only If Active ==
  +
  +
Here's the code used in the sidebar.php file of the [[Twenty Fourteen]] Theme.
 
<pre>
 
<pre>
  +
<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
register_widget_control($name, $callback [, $width [, $height ]] );
 
  +
<div id="primary-sidebar" class="primary-sidebar widget-area" role="complementary">
  +
<?php dynamic_sidebar( 'sidebar-1' ); ?>
  +
</div><!-- #primary-sidebar -->
  +
<?php endif; ?>
 
</pre>
 
</pre>
  +
This code checks to see if the new widget area is populated otherwise doesn't execute.
   
  +
=== Independent Widgets ===
* Namespace your form elements so they don’t conflict with other widgets.
 
  +
The second, and more technical, is via <tt>[[Function Reference/the_widget | the_widget()]]</tt> method.
* Each widget must have a unique name. You can replace an already-registered widget by registering another one with the same name, supplying your own callback.
 
* Any extra arguments to register_sidebar_widget() or register_widget_control() will be passed to your callback. See the Text and RSS widgets for examples.
 
* Any widget or control can be “unregistered” by passing an empty string to the registration function.
 
* There are probably some undocumented functions. You are encouraged to read the source code and see how we’ve created the standard widgets using these functions.
 
* Please test your widgets with several themes other than Classic and Default (they both use the ul/li/h2 markup).
 
* Please audit the security of your widgets before distributing them.
 
* If you would like your widget to be considered for use on WordPress.com, send a link (no attachments please) to widgets@wordpress.com and we’ll have a look.
 
 
==What else can I do with Widgets?==
 
You have no idea how glad we are that you asked that. Here are a few ideas:
 
   
  +
<small><i>Tags: how do i display widgets, how do i display widget areas</i></small>
* Write a theme that includes a special widget to set it apart from the others.
 
* How about this for a special widget: a WordPress loop to show asides.
 
* Register a replacement widget that buffers the original widget and transforms it somehow.
 
* Remember that a “sidebar” is really just a name for a list. It can be displayed vertically or horizontally.
 
* Remember that a “widget” is really just a name for a configurable code snippet. It can be invisible or it can be absolutely positioned.
 
* Use the id and class attributes of any or all widgets in scripts to animate your sidebar.
 
* Heck, use script.aculo.us or dbx (included with WordPress) to make your widgets draggable or even collapsible. Ain’t scripting sweet?
 
* Remember that the widget control API is just for convenience. You can always set up your own admin page instead.
 
* Support your users and get feedback so you can improve your widget. Put a link to your email or your site at the bottom of your widget control.
 
* Send a link to your widgets to widgets@wordpress.com for review. We might put them up for everyone to use on WordPress.com. You could be internet famous!
 
   
== Widgets - One or many ==
+
== Resources ==
  +
* [https://make.wordpress.org/core/2015/07/02/deprecating-php4-style-constructors-in-wordpress-4-3/ Deprecating PHP4 style constructors in WordPress 4.3.]
Widgets can be coded so that they can exist one time or they can exist multiple times. Wordpress is doing the work for you to instantiate your Widget multiple times if you follow some rules.
 
  +
* [https://w3guy.com/fix-notice-called-constructor-method-wp_widget-deprecated/ How to Fix – Notice: The called constructor method for WP_Widget is deprecated]
  +
* [http://generatewp.com/sidebar/ WordPress Sidebar Generator]
   
==Resources==
+
== Related ==
  +
{{Theme Support}}
* [http://brainfart.com.ua/post/lesson-wordpress-multi-widgets/ Multiple Widget Lesson]
 
* [http://jessealtman.com/2009/06/08/tutorial-wordpress-28-widget-api/ Tutorial for creating a widget using WordPress 2.8]
 
   
 
[[Category:Widgets|*]]
 
[[Category:Widgets|*]]
  +
[[Category:Advanced Topics]]
  +
[[Category:WordPress Development]]
  +
[[Category:API]]

Latest revision as of 16:08, 24 April 2018

This article is marked as in need of editing. You can help Codex by editing it.

Widgets API

This page contains the technical documentation for the WordPress Widgets API and is written for developers. If you're not a developer you may want to review the Widgets page.

In technical terms: a WordPress Widget is a PHP object that echoes string data to STDOUT when its widget() method is called. It's located in wp-includes/widgets.php.

Function Reference

Widget Functions
internal Functions

Developing Widgets

To create a widget, you only need to extend the standard WP_Widget class and some of its functions.

That base class also contains information about the functions that must be extended to get a working widget.

The WP_Widget class is located in wp-includes/class-wp-widget.php.

Default Usage

class My_Widget extends WP_Widget {

	/**
	 * Sets up the widgets name etc
	 */
	public function __construct() {
		$widget_ops = array( 
			'classname' => 'my_widget',
			'description' => 'My Widget is awesome',
		);
		parent::__construct( 'my_widget', 'My Widget', $widget_ops );
	}

	/**
	 * Outputs the content of the widget
	 *
	 * @param array $args
	 * @param array $instance
	 */
	public function widget( $args, $instance ) {
		// outputs the content of the widget
	}

	/**
	 * Outputs the options form on admin
	 *
	 * @param array $instance The widget options
	 */
	public function form( $instance ) {
		// outputs the options form on admin
	}

	/**
	 * Processing widget options on save
	 *
	 * @param array $new_instance The new options
	 * @param array $old_instance The previous options
	 *
	 * @return array
	 */
	public function update( $new_instance, $old_instance ) {
		// processes widget options to be saved
	}
}

The widget can then be registered using the widgets_init hook:

PHP 5.3+ only:

add_action( 'widgets_init', function(){
	register_widget( 'My_Widget' );
});

PHP 5.2+:

add_action('widgets_init',
	create_function('', 'return register_widget("My_Widget");')
);

Example

This sample code creates a Widget named Foo_Widget that has a settings form to change the display title.

/**
 * Adds Foo_Widget widget.
 */
class Foo_Widget extends WP_Widget {

	/**
	 * Register widget with WordPress.
	 */
	function __construct() {
		parent::__construct(
			'foo_widget', // Base ID
			esc_html__( 'Widget Title', 'text_domain' ), // Name
			array( 'description' => esc_html__( 'A Foo Widget', 'text_domain' ), ) // Args
		);
	}

	/**
	 * Front-end display of widget.
	 *
	 * @see WP_Widget::widget()
	 *
	 * @param array $args     Widget arguments.
	 * @param array $instance Saved values from database.
	 */
	public function widget( $args, $instance ) {
		echo $args['before_widget'];
		if ( ! empty( $instance['title'] ) ) {
			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
		}
		echo esc_html__( 'Hello, World!', 'text_domain' );
		echo $args['after_widget'];
	}

	/**
	 * Back-end widget form.
	 *
	 * @see WP_Widget::form()
	 *
	 * @param array $instance Previously saved values from database.
	 */
	public function form( $instance ) {
		$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'text_domain' );
		?>
		<p>
		<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label> 
		<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>
		<?php 
	}

	/**
	 * Sanitize widget form values as they are saved.
	 *
	 * @see WP_Widget::update()
	 *
	 * @param array $new_instance Values just sent to be saved.
	 * @param array $old_instance Previously saved values from database.
	 *
	 * @return array Updated safe values to be saved.
	 */
	public function update( $new_instance, $old_instance ) {
		$instance = array();
		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';

		return $instance;
	}

} // class Foo_Widget

This sample widget can then be registered in the 'widgets_init' hook:

// register Foo_Widget widget
function register_foo_widget() {
    register_widget( 'Foo_Widget' );
}
add_action( 'widgets_init', 'register_foo_widget' );

Note : You must use get_field_name() and get_field_id() function to generate form element name and id.

Example With Namespaces

If you use PHP 5.3. with namespaces you should call the constructor directly as in the following example:

namespace a\b\c;

class My_Widget_Class extends \WP_Widget {
	function __construct() {
       	    parent::__construct( 'baseID', 'name' );
        }
        // ... rest of functions
}

and call the register_widget() with:

add_action( 'widgets_init', function(){
     register_widget( 'a\b\c\My_Widget_Class' );
});

(see: http://stackoverflow.com/questions/5247302/php-namespace-5-3-and-wordpress-widget/5247436#5247436)

That's all. You will automatically get a multi-widget. No special tweaks needed any longer for that.

More information is available in the version 2.8 information.

Displaying Widgets and Widget Areas

There are at least 3 ways that Widgets can be displayed:

Widget Areas

The first, and most common, is by adding the desired Widget to a Widget Area via the Appearance -> Widgets menu in the Administration Screens.

WordPress comes with some predefined Widget Areas that each have unique identifiers (view the source of the Widgets page to see them) that you'll need to know in order to display the Widget Area. If the predefined Widget Areas are insufficient for your needs you may register a custom Widget Areas.

When you're ready you can display that Widget Area by inserting the following code into whichever Theme file you desire:

<?php if ( dynamic_sidebar('example_widget_area_name') ) : else : endif; ?>

That code displays all of the Widgets added to that Widget Area.

Display Widget Area Only If Active

Here's the code used in the sidebar.php file of the Twenty Fourteen Theme.

<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
	<div id="primary-sidebar" class="primary-sidebar widget-area" role="complementary">
		<?php dynamic_sidebar( 'sidebar-1' ); ?>
	</div><!-- #primary-sidebar -->
<?php endif; ?>

This code checks to see if the new widget area is populated otherwise doesn't execute.

Independent Widgets

The second, and more technical, is via the_widget() method.

Tags: how do i display widgets, how do i display widget areas

Resources

Related

Theme Support: add_theme_support(), remove_theme_support(), current_theme_supports()
Theme Features: sidebar, menus, post-formats, title-tag, custom-background, custom-header, custom-logo, post-thumbnails, automatic-feed-links, html5, editor-style, content_width