Adding a Custom Widget to Any Page, Post or Template in WordPress
Widgets make WordPress really flexible. By adding widget areas to your themes, you let users insert their own custom content without having to write a line of code.
They’re most common in sidebars and footers, where they’re often used to hold widgets such as the search widget, latest posts widget, or maybe a custom menu. But if you add them to your page and post templates you make them even more powerful.
You can add widget areas to any template file you like. I like to add plenty of them to my themes, in places such as the header, before and after the main navigation, and before and after the content. You can either add them to a template part (such as the header) that’s being used by every page in your site, or you can be more specific and just add them to template files for a given content type.
In this post, I’m going to show you how to do just that. I’ll create a child theme of the default Twenty Seventeen theme and then within that child theme, I’ll create some new template files: a custom page template file, a category archive file and a single post template file.
In each of these I’m going to add a widget area specific to that content type, so users will only see it when they’re viewing a page using the page template, a category archive or a single post, respectively.
Note: I’ve added the code for this post to GitHub so you can check it if you’re working along with this tutorial.
Continue reading, or jump ahead using these links:
Setting up the Child Theme
I’m going to be using a child of the twenty seventeen theme: if you’re working with your own theme you can edit that directly instead of creating a child theme. But if you’re using a third party theme, you must create a child theme. This is because when you update the theme, any changes you make to it will be lost.
So, in your wp-content/themes folder, create a new folder with the name of your theme. I’m calling mine wpmu-template-widgets. Within that, add a style.css file and add this to it:
Remember, if you’re working with your own theme you can skip this step. And if you’re using a different parent theme, you’ll have to edit the stylesheet to reflect that. If you’re not sure, check out our post on creating child themes.
Registering the Widget Areas
Before we can add the widget areas to our template files, we need to register them in the theme’s functions file. Open your functions file if your theme already has one, or if it’s a new child theme, create a file called functions.php.
Let’s start by adding the empty function to register the widgets, and hooking it to the
widgets_init hook. Add this to your functions file:
Within that function, we’re going to register four widget areas: one each of the single post and category archive templates, and two for the custom page template.
Start by registering the first widget:
This uses the
register_sidebar() function, with an array of parameters as follows:
- The name of the widget area, which will appear in the Widgets admin screen and the Customizer. I’ve made this translatable.
- A unique ID for the widget area.
- Markup for before the widget, which uses placeholders for internationalization.
- Markup for after the widget.
- Markup for before and after the widget title, which is enclosed in a
So that’s the first one. Now, still inside your function, add the other three:
So we now have four widgets:
- One after the content on single posts.
- One before the content on a category archive.
- One before and one after the content on our widgetized page template.
If you want to move your widget areas (e.g. putting the category archive one after the content or the single post one before the content), you should rename them appropriately. This is so that you know what’s going on when you come to edit your code in future, and your users know where the widget areas will be output when they add widgets to them via the Widgets admin screen. Remember that if you do alter this, you’ll need to place the code to output the widgets in the correct place in your template files in the next step, which might be different from where I’m putting mine.
Now if you open your Widgets admin page, you’ll see your widget areas, ready for widgets:
But if you add widgets to your new widget areas, they won’t show up in your site’s front end. They still need to be coded into the template files.
Adding Your Widget Areas to Template Files
Now we add the code to output the widget areas. If you’re working with your own theme you may just need to edit your existing theme template files. If you’re working with a child theme (or your theme doesn’t already have the relevant template files), you’ll need to create new files.
Let’s start with the widgetized page template file, as your theme won’t have that either way.
In your theme folder, create a new file. I’m calling mine page_widgetized.php. Open that file and add this to it:
This tells WordPress that it’s a custom page template. If you want to know more about them, check out our detailed guide.
Note: Don’t use page-widgetized as your filename. This is because page- is a reserved suffix in WordPress. Use an underscore instead of a dash, or just avoid using page at the beginning altogether if you prefer.
Now below that commented out text, copy everything from your theme’s (or the parent theme’s) page.php file. An alternative is to make a copy of the file and add the commented out text, it’s up to you.
You’ll now be able to select this template when editing a page in your site:
Select it for one of your pages so you can try out the widgets. Here’s my page:
It doesn’t look very exciting right now as I haven’t added the widget areas to the template file. Let’s do that.
In your template file, add this code immediately above the page content, for the above-content widget area:
This checks if the widget area has been populated, using the unique ID that you created for the widget area when you registered it in your functions file. If it has been populated, it outputs the contents of the widget area.
Now add the widget area below the content. After your content (and inside any enclosing element), add this:
Save your page template file.
Here’s the full code of my page template file, so you can see where the widget areas before and after the loop:
Now to test it out. I’ve added a widget to each of the new widget areas:
And here’s how they look on my page:
So that’s the custom page template set up. Now you need to edit the other two page template files (or create them if necessary). Follow these steps:
- If you’re working with a child theme, create a file called category.php. Copy the contents of the category.php file from your parent theme (if it has one) or the archive.php file (or index.php if it doesn’t have that).
- If you’re not working with a child theme, but your theme doesn’t have a category.php file, make one by copying the archive.php file (or if you don’t have one of those, the index.php file).
- Add the widget area above the content in your category archive file – again, immediately before the loop.
Here’s the code for the widget area:
Now repeat this for the single template:
- Create a single-post.php file if your theme doesn’t have one (or you’re using a child theme). Copy the contents from your parent theme’s single-post.php file into it, or from the next template file up in the template hierarchy (single.php, singular.php or index.php).
- Again, add the widget area – this time after the content.
Here’s the code:
Now if you add widgets, they’ll show up on your site. Here’s mine showing a list of recent posts after a single post:
Adding Widget Areas to Templates Gives You Flexibility
Widget areas make it possible for your theme’s users to add extra content without having to write code. But they’re not just for the sidebar. Adding extra widget areas to your template files gives you targeted areas in your site that you can add widgets to, with fine control over where they’ll show up.
You can take these examples further if you like, adding widget areas to all of your files, or even using different versions of the sidebar.php file for different content types. The world is your oyster!Tags: