WordPress – Adding Widgets to Child Themes
Once you've been experimenting with WordPress for a while, and become familiar with how to configure things, there frequently comes a time when you realize that you need to be a little more creative in getting your site to look exactly how you want. That's usually when you'll realize that a creating a child-theme is needed.
And, soon after that, often one of the next things you want to do is to create your own widgets to accomplish something specific for your website. We'll assume that you know what child themes and widgets are, but in brief:
Child theme:
A child theme is one which is derived from an existing theme. One of the main reasons in creating a child theme is so that modifications may be made without fear of losing them whenever the main (parent) theme is updated. Never modify core WordPress files or theme files - there's always a better way.
Widgets:
Widgets are easily-created additions to WordPress which you may incorporate into your site to (usually) display information. You might create a widget, for example, to display all of your posts which have certain keywords. Widgets are commonly used to display additional bits and pieces in the sidebar areas of a theme. Widgets are not plug-ins. Plug-ins generally add some additional tool or function to your site, which may only be visible in the Admin area.
Now, creating a child theme is not what this brief article is about, as there are plenty of tutorials available to do that, and it's pretty simple anyway. Nor is this really about creating widgets, per se, but more about how to implement one in a child theme having already created a widget.
So, the code for a very simple widget might look something like this:
class my_widgy extends WP_Widget { function __construct() { parent::__construct('my_widgy', __( 'My First Widget', 'my_widgy_domain'), array( 'description' => __( 'Cool stuff with my first widget', 'my_widgy_domain' ) ) ); } // ... a bunch of code in between here, for doing the widget logic and back-end, etc. // Class my_widgy ends here } // Register and load the widget function load_my_widget1() { register_widget( 'my_widgy' ); } add_action( 'widgets_init', 'load_my_widget1' );
Of course, you'd also have quite a bit more code in a real widget, with the main logic and also the parts for the back-end configuration. This is just for demonstration purposes.
The Real Point ...
So, the real point about all of this is that there are many tutorials online which offer useful tips and guidance for how to create widgets, but many of them encourage you to put all of your widget code inside your child-theme's functions.php file. This might be okay just as a starting point, but it quickly becomes unmanageable, and your functions.php file soon looks a mess. It then becomes more difficult to quickly find or modify other things which you may need in the file. And, of course, if you want to create additional widgets, then even more mess.
A Better Way ...
However, if you've tried to separate your widget code from your functions.php file and gotten into a pickle, with the widget no longer working, then you won't be the first. Here's what you need to do:
a) First of all, make a back-up of your functions.php file, before you do anything at all.
b) Now, take out all the code for your widget, from functions.php, and save it into a separate file. Let's imagine you call it my_widget1.php. Remember to add the opening and closing PHP tags in the file: <?php at the very top, and ?> at the very bottom.
c) On Linux, make sure you have the correct permissions on the widget file (644 is fine). If you quickly want to see the numeric permissions on files in Linux, rather than the rwx permissions, then the following command will do just that:
$ stat -c '%a %n' *
d) Now comment out, or delete, the "add_action( 'widgets_init', 'load_my_widget1' );" line in my_widget1.php (or in whatever file you decided to name your widget file)
e) Now open up functions.php, and we have two lines of code to add. These two lines can go at the top of the file, a line or two beneath the opening php tag:
require_once get_stylesheet_directory() . '/my_widget1.php'; add_action('widgets_init', 'load_my_widget1');
Now save functions.php. (Note that 'load_my_widget1' is what we named our widget register function in what is now my_widget1.php)
In this case, my_widget1.php is saved in the base directory of the child theme (i.e. in the same directory as functions.php). However, it doesn't necessarily have to be there; you might want to keep it in a /inc/ directory for example - just remember to change the file location accordingly, in the require_once line.
If you forget to comment out the add_action line in the my_widget1.php file, then you'll probably get an error, so be sure to do that.
There are other ways to provide the path to the require_once directive, but the get_stylesheet_directory() function is likely to prove the most reliable way of doing so.
If you omit the add_action(...) line in functions.php, and figure that it will still work if you keep the same line in my_widget1.php, then unfortunately you'll find it won't work. You won't get any errors, but the widget will not load properly and won't function.
Your widget should now work perfectly, with your code now separated into more manageable files. And, of course, now you can add multiple widgets and have multiple widget files, which will all be much easier to maintain and debug.
Be sure to go back into the Admin area, just to be certain that your widget is being registered; you should refresh the widget admin area, so you can see it's being recognized.
Hopefully this information will save you some headaches and make your WordPress site more easily manageable.
Even more ...
You may wonder why use require_once, rather than require, or include_once, or include. It's a fair question!
Well, it probably would still work just fine with any of those other choices too, but there are reasons you'd be more likely to want to use require_once. Firstly, if either require_once or require fail to locate the file you need, then the program will end with a fatal error (since the file should, presumably, always be where you say it is, then this is probably what you'd want to happen). If you use include_once or include, instead, then if the file is not located then the program will continue anyway (but, of course, there may be other things which rely on your widget working, so this may not always be the best idea).
Also, you'd use require_once, rather than require, since you'll only ever want your widget file to be loaded into memory once. If you used require you could end up with it being loaded multiple times, which would cause unnecessary overhead in terms of time, memory, and resources.