I build new Widgets fairly frequently. More often than not they’re so tied to the current project they’re not worth making public. Recently though, I found myself faced with a task that I’ve dealt with a number of times before: including an image asset in a Widget.
To date, my most common way of accomplishing the task would be to use a simple text field and use it to populate the URL of an image uploaded through the Media library. That was always really cumbersome and with everything I’ve been doing with Attachments lately I thought now would be a good time to put in the effort and make this process easier.
The trouble with this goal is the way Widgets work, though. You build Widgets by extending a class, and it would be really cumbersome to try and provide this functionality based on that workflow. Instead, I’ve built a plugin that will act as a utility when you build your own Widgets.
I know already that the biggest assumption for this plugin will be that it’s a Widget itself, but it’s not. This plugin does not attempt to make new Widgets available, it aims to make it easier for your to include an image field in your built-by-hand Widget.
How to use it
The plugin has been added to the plugin repository and you can grab it there. You install and activate it in the traditional way, and it will be available for use within the Widgets area of the WordPress admin.
To explain the usage of the plugin, we’ll go ahead and build our own Widget to power the Image of the Month for a website. It’s going to have the following fields:
- Text field for a headline
- Image field
- Text field for an image caption
To begin, we’ll start with the instantiation of our Widget:
This is a pretty standard invocation of a basic Widget, the biggest difference being it’s inclusion being dependent on the presence of the Widget Image Field plugin. The other addition uncommon to most Widgets is the $image_field
definition. This was put in place to make the implementation of our image field more bulletproof by defining a consistency in our field ID.
The next thing we’ll tackle is the form()
for the Widget section in the WordPress admin:
We’ve now got the image field implemented and can see it in the WordPress admin.
The $headline
and $blurb
fields are common to Widgets so I won’t cover those, and our $image_id
stores the ID of our image, that’s the only thing that’s saved with this field, the plugin takes care of the rest.
Note: When we define $image_id
on line 6 in this snippet we’re making use of the $image_field
id we defined on line 10 from the first snippet and makes consistency more easy to manage as we go on.
It’s important to notice line 9 in the snippet, as it’s the first time we’re making use of the Widget Image Field plugin. We define $image
as our WidgetImageField
and pass the required parameters:
$this
: the current Widget object$image_id
: the ID of the chosen image
The plugin is again used on line 18 in the snippet, where the plugin is utilized to output the ‘Choose image’ button displayed in the screenshot.
The next step will be to implement the update()
function for our Widget, which handles data saving.
We’re again referencing the $image_field
we defined in the first snippet, but data sanitizing takes place here the the results are returned back to WordPress for saving. Our Widget now stores data.
The final piece to implement Widget Image Field concerns Widget output within your theme, which is defined within widget()
.
The first step is the standard call to extract()
which defines the necessary variables we’ll need for output, both those we have defined as well as those defined by the call to register_sidebar()
. In this implementation we’re only using $before_widget
and $after_widget
.
We’ll define our Widget-specific variables, including our image field which again makes use of the $image_field
defined in the first snippet. On line 11 we instantiate our WidgetImageField
. Line 20 encompasses retrieval of the image asset itself.
The plugin provides the location and dimension for those chosen image by passing the target image size as the only parameter (defaults to 'thumbnail'
). Using this information you can completely customize the output of your Widget.
Our final Image of the Month Widget consists of:
I’m not convinced this is the most elegant solution to accomplish my goal, so reading outside opinions about how to more gracefully ‘extend’ a custom Widget to achieve the desired result, I’d love to hear your thoughts!
Comments
This works great!
I did find an issue though. When we do not name our variable image_field and the value of the var image_field is something other than ‘image’, this does not work. Maybe changing the method function get_widget_field( $field_name ) to be a required arg and the input field id to be the field_name.
I found this issue when trying to use more than 1 image uploaded.
Thanks,
Howard
Love the image widget idea! But, has anyone had trouble getting it to show up on the Widget list after activating? Can’t find the dang thing! Reinstalled twice. Stuck. Thoughts?
Steve, as per the article it does not produce a Widget but instead makes it easier to integrate an image field into your Widget, you still need to build out the rest.
Thanks Howard I’ll surely look into that issue.
This is possibly the best thing in the entire world. I needed something to allow my clients to upload documents in a widget on the backend and this saved my project!
I’ve hacked it a bit to handle documents but it’s not pretty. I’m displaying the document URL in a tag in the backend widget by using the attachment ID, which means it only updates after I click “save”. Is there a way to dynamically update the URL after I click “Use this document” (which was your “Use this image”) in the media uploader?
Oops – meant to write “displaying the document URL in a p tag”
Jonathan, once again you are the man! This one plugin has made widgets about a million times more powerful, thanks for publishing.
Hi Jonathan,
just to let you know I had to change line 72 of script.js from
tb_show(jQuery(this).attr(‘title’), event.target.href, false);
to
tb_show(jQuery(this).attr(‘title’), href, false);
As it was erroring in IE – now works on all browsers for me.
[…] how to use: https://jonchristopher.us/20120206/wordpress-widget-image-field/ […]