TL;DR: I’m going to be working on a series that looks at how to achieve a useful task with taxonomies, likely categories, then refactor it into an object-oriented plugin that will serve as a utility plugin for taxonomies, in general.
A Brief History of OOP Posts
Some time ago, I did a lengthy series about the principles of object-oriented programming (and tried to share a decent amount as to how to achieve certain things within the context of WordPress).
I’ve also written a bunch of articles about the whole paradigm over the years for those who are interested in catching up on some of those articles.
And I’d be remiss if I didn’t share that a good friend of mine has literally written a book on the topic, too.
And thus, as I’ve been thinking about various topics to write about (after taking an admittedly longer period of time off than I planned), thought that it might be worth talking about practical things we can do with normal APIs and hooks and then refactor that into a type of utility plugin.
Add a Custom View
For the purpose of the work I’m going to share in this demo, I’m using the following:
- Local by Flywheel with a
https://sandbox.local
domain - TablePlus for Database access
- Visual Studio Code as my IDE
- And the WDS PHP Coding Standards for all the PHP that you’re going to see.
If you want to follow along with what I’ve got going on, use all of the above (I don’t know if I’ll be sharing everything but if you see screenshots and code snippets, you’ll know where it comes from).
With that, here’s a short digression on views
in WordPress (and it’s not like Views in the sense of MVC or MVVM).
WordPress Views
At the time of this writing, there doesn’t appear to be a clear, concise statement as to what a WordPress view is. In terms of the available hook, we have views_edit-post
.
So if we take that particular hook and what it does, perhaps something like this would suffice:
A WordPress view is a a page where we can view all posts that conform to a set of specified criteria.
Out of the box, this criteria usually includes posts like:
- Published,
- Drafts,
- Trash,
- Scheduled,
- And so on.
But what if you have another post that has some other criteria by which you want to filter? Sure, you can filter by the dropdown box that’s present on the screen (say, by category), and that’s fine, but what if you want to use a custom criteria for [any given reason]?
For example, what if you don’t want to have to click through a certain element, then filter, then view the posts? Instead, you want to see a link to the criteria, the number of posts that fit the criteria, and then filter by them?
This is where the ability to edit views comes into play.
And for the purposes of this post, I’m going to cover how to introduce a new anchor at the top of the page that will list out the number of posts for a specified category.
What’s Our View?
In this case, we’ll use Uncategorized because a default installation already has an uncategorized post available and we can easily tweak certain changes around this.
To do this, we’re going to write an mu-plugin
so it’ll be placed in the mu-plugins
directory. If your installation doesn’t have one, add the directory and then add add-custom-view.php
to the directory:
From there, the initial plugin file may look something like this:
Initially, we’re doing the following:
- Setting a namespace,
- Adding a filter,
- Then setting up the function that will accept the default set of
$views
and return the array of$views
after they have been altered.
So what do we need to do from here?
The Set of Requirements
To achieve what we want, we need to be able to:
- Specify the name of the category,
- Add the link to the category along with the number of posts with that category to the list of views,
- The ability to determine if we’re on the category page to properly style the list
- The ability to filter by post type,
- And a way to test it.
All of the above will be covered in code later in the article but the fifth step requires that you manually create a category so we can easily test if the rest of the code is working.
So go ahead and do that. The category can be named anything (I used Sample Category). Once done, let’s write code from the rest of the plugin.
Determine Our View
First, I’m going to share a function that will determine which page we’re on and will do one of two things:
- If we’re on a page that has the same query string parameter for the ID of our category, I’ll provide a class name; otherwise, we’ll return an empty string.
To do this, the function should:
- Accept a category name,
- Initialize a variable for attributes,
- Compare the query string variables
- Determine if the category name and category ID are same,
- And return the proper value, if not.
This is what my function looks like:
This could also be simplified with a ternary operator, but to keep it as readable as possible, I’m leaving it as is for now.
Determine The Category Name
This particular feature is actually really easy and although we’re used to taking input from users in much of what we do, we’re going to be hardcoding this value.
To do this, we’re simply going to be storing this in a variable that’s passed throughout the rest of the code.
You saw the variable previously passed into the above function and will see this used in the final version of the source code, as well.
Retrieve Results of Posts with the Category
For this, we need to do two things:
- Retrieve all of the
object_id
records that have the ID of this category, - Filter out the content that are not for these posts.
There are a couple of things I want to mention here: First, we’ll be using the get_cat_ID
function that WordPress provides. This retrieves the ID of the category based on the incoming name.
Secondly, I’m using two functions – one of which is a loop – to examine the post status of an element. This is not the most efficient way to do this. Instead, we could use a more elegant query to retrieve only posts; however, the first iteration of this is meant to show how to not only do this from the ground up, but also for an audience who may not be as comfortable with other aspects of writing code.
With that, here’s how we get all of the records in WordPress that are marked as Uncategorized.
And with that, we take the results and send them into this function that will return the number of elements that are only posts.
With that, we have most of what we need to begin putting together our view anchor.
Generate a View Anchor
Now that we have all of the function’s necessary to generate a view anchor, we need to put them together in the place of sprintf
for safe string formatting.
The goal is to generate an anchor that:
- Looks like the rest of the anchors,
- Shows the number of posts,
- Is bold whenever you’re viewing said posts.
To do this, we need to build the link and add the proper query string arguments. This means, we’ll set up a link to edit.php
with arguments for:
- the category’s ID,
- the post type of post,
- and all posts that have this category.
Next, we’ll need to include:
- any attributes to style the link,
- the name of the category,
- and just the content of the post
post_type
.
To do this, we can use the following function:
This does several things:
- Accepts the standard array of
$views
from WordPress, - Adds our custom anchor as outlined above,
- Pushes it into the
$views
array, - Returns it to WordPress to render.
And that’s it!
Testing It
To test this, load up your browser and you should see a new Uncategorized link next to the rest of the anchors such as All, Published, Mine, Trash, Scheduled, etc.
After that, change a posts category and remove Uncategorized then revisit or refresh the All Posts page and you’ll see that the link is active and styled, depending on how you’re viewing it, and it includes the number of posts that are categorized as such, too.
Now, To GitHub
I’ve loaded the first iteration of this plugin on to GitHub so you can download it and place it into your mu-plugins
directory for testing.
In upcoming posts, I’d like to begin by changing this into an object-oriented paradigm so those are the changes that are coming to the plugin and the content coming in future posts.