I would like to programmatically add widgets to my two sidebars that I’ve got. I couldn’t find any official way of doing it?
I started looking in the database. I’ve found that it’s the ‘sidebars_widgets’ option which puts widgets on sidebars. When looking at the options the widget names has a number added to the end like: widget_name-6. Where does that number come from?
Any idea on how to fix this?
When I started this answer it should be just a small note. Well, I failed. Sorry! Stay with me, there is a goody hidden deep down â¦
How WordPress widgets are stored
The list of widget is stored in an option named
'sidebars_widgets'
. Avar_export()
may give something like the following:Ignore
'wp_inactive_widgets'
and'array_version'
. We don’t have to care about those.The other keys are identifier for registered sidebars. In this case the sidebars may have been registered with this code:
By default the sidebars are empty after registration. Of course.
For each registered widget class a separate option is created, containing all necessary options. The option is prefixed by the string
widget_
. To get the options for all active RSS widgets we have to look into â¦Possible output:
Note the number 2. The arguments for multiple instances are all stored in this one option sorted by numbers.
To see which widget classes are already known to WordPress go to
wp-admin/options.php
and scroll down until you see something like this:Yes, serialized data. No, you can’t read those here. Don’t worry, you don’t have to.
A demo widget
To illustrate the inner workings better I have written a very simple demo widget:
Note the constructor:
't5_demo_widget'
is the$id_base
, the identifier for this widget. As you can see in the screen shot its arguments are stored in the optionwidget_t5_demo_widget
. All your custom widgets will be treated like this. You don’t have to guess the name. And since you have written your widgets (probably) you know all the arguments from your class’$instance
parameters.Theme basics
First you have to register some sidebars and the custom widget. The proper action for this is easy to remember:
'widgets_init'
. Put everything into a container â a class or a function. For simplicity I’ll use a function namedt5_default_widget_demo()
.All of the following code goes into the
functions.php
. The classT5_Demo_Widget
should be loaded already. I just put it into the same file â¦So far, so simple. Our theme is now widget ready, the demo widget is known. Now the fun.
You really don’t want to destroy the user settings. If there is already some content in the sidebars your code should not run over it. That’s why we stop in this case.
Okay, assumed the sidebars are empty ⦠we need a counter:
Widgets are numbered. These numbers are second identifiers for WordPress.
Let’s get the array to change it:
We need a counter too (more on that later):
And here is how we use the counter, the sidebar names and the the widget arguments (well, we have just one argument:
text
).Note how the widget identifier is created: the
id_base
, a minus-
and the counter. The content of the widget is stored in another variable$demo_widget_content
. Here is the counter the key and the widget arguments are stored in an array.We increment the counter by one when we are done to avoid collisions.
That was easy. Now a RSS widget. More fields, more fun!
Here is something new:
update_option()
this will store the RSS widget argument in a separate option. WordPress will find these automatically later.We didn’t save the demo widget arguments because we add a second instance to our second sidebar now â¦
⦠and save all arguments for the
t5_demo_widget
in one rush. No need to update the same option two times.Well, enough widgets for today, let’s save the
sidebars_widgets
too:Now WordPress will know that there are some registered widgets and where the arguments for each widget are stored. A
var_export()
on the sidebar_widgets will look like this:The complete code again:
If you go to
wp-admin/widgets.php
now you will see three pre-set widgets:And that’s it. Use â¦
⦠to print the widgets out.
There is a small glitch: You have to load the front-end two times for the initial registration. If anyone can help out here I’ll be very grateful.
Thanks for sharing your solution. I have used what has been described in this question to create a piece of code that can be used to initialize sidebars very easily. It is very flexible, you can create as many widgets as you want without having to modify the code at all. Just make use of the filter hooks and pass in arguments in an array. Here is the commented code:
This is a helper function which checks if the sidebar already has content in it:
Now we need to create a function that is hooked to the ‘sidebar_init’ action.
And now the widget initialization:
The last action is to create the widgets in each sidebar:
This function is used to keep track of how many instances of a specific widget have already been defined:
The last thing we need to do is to actually assign values. Make use of these filter functions:
And:
Ideally you would call initialize_sidebars in a setup function which is called upon plugin or theme activation like this:
Theme activation:
Plugin activation:
To summarize the usage of this conglomerate of functions:
create a function that initializes the sidebars which is hooked to the ‘alter_initialization_sidebars’ filter.
create a function for each sidebar you just added which is hooked to the ‘alter_initialization_widgets_$sidebarname’ filter. Replace $sidebarname with the name of each sidebar you created in step 1.
You can also simply copy this uncommented code into your functions file and start creating your filter functions right away: Code on pastie (without initialization filter functions)
First of all, thanks to @toscho for the detailed answer.
This is a simple example for those who are searching for a simple solution and default widget options:
Note 1: You can get
sidebar-id
going to widgets menu and inspecting the wanted sidebar. The first<div id="widgets-holder-wrap">
‘s<div>
child has thesidebar-id
.Note 2: You can get the
widget_name
going to widgets menu and inspecting the wanted widget. You’ll see something like<div id="widget-6_widget_name-__i__" class="widget ui-draggable">
.I wish it helps.
This is how you do it:
(WARNING, this could REMOVE all previous widgets if you did not put back the original widgets into the
widgets
array.)The -number can be used if you later want to add options to the widget with something like this: