Creating Custom WordPress Administration Pages, Part 1

In a previous series, I provided an in-depth guide to working with the WordPress Settings API. For those who are new to WordPress or who have been using other tools such as The Customizer to handle various options, it may be something that you have not had to use in your theme or plugin development.

As stated in the Codex:

The Settings API, added in WordPress 2.7, allows admin pages containing settings forms to be managed semi-automatically. It lets you define settings pages, sections within those pages and fields within the sections.

I don't think it's something that's required to learn, but it's something that you should know exists and know how to work with it if you find yourself needing to introduce option pages into the WordPress administration area.

It's a powerful, albeit somewhat complex, API that provides us with a lot of functionality. Ultimately, it allows us to do a lot of work on the server side and minimal work on the client side.

But what about the times when we're working with a custom solution for clients and we need a little more flexibility than the Settings API provides? For example, say we need to build a plugin that will have a settings page but needs a more flexible set of options and tailored validation functionality?

In those cases, it's possible to write our own custom WordPress administration pages. In this series, we're going to take a look at how to do exactly that.

Before We Start

As with most tutorials like this, it's important to make sure that you have everything in place to follow along so that you can work with the source code that we cover throughout the series.

For this tutorial, I'm assuming:

  • You have a local development environment setup relative to your operating system.
  • You have a copy of WordPress installed and ready to be used for installing a plugin.
  • You're familiar with WordPress plugin development practices.
  • You're comfortable working with PHP and HTML.

If you're not familiar with how to set up a local development environment that includes WordPress, please see this series for how to do just that. 

And if you're relatively comfortable with PHP, even if it's just reading the language, then I'll do the best I can to provide clear instructions and comments for each bit of code that we share.

Once all of this is in place, we're ready to begin working on our plugin.

Custom WordPress Administration Settings

By the end of this series, we're going to have a plugin that meets the following requirements:

  • Adds a new submenu item to the existing WordPress menu system.
  • Adds a new settings page that corresponds to the new submenu item.
  • Sanitizes and serializes options on the page.
  • Validates and returns the values that were saved and renders them accordingly.

Furthermore, we'll make sure that we approach this in the most modular way possible using the WordPress Coding Standards and similar practices to make reading, writing, and maintaining our plugin as easy as possible.

1. The Plugin Bootstrap

The first thing that we need to do is to create the plugin bootstrap. This will include creating a directory to house the plugin's files, a basic README, a copy of the license, a bootstrap file that will eventually be used to start the plugin, and a directory that will be used to hold the classes related to the administrative functionality.

The files are available for download as an attachment to this post but, in the meantime, you can see what my directory looks like below:

The plugins directory structure

Furthermore, the contents of the plugin bootstrap are simple. Review the following code for the single PHP file custom-admin-settings.php, and then I'll discuss it in more detail below the block.

Notice that in the code above, there's actual very little code. Instead, it's a lot of comments. The main block of comments at the top of the file explains what the file does.

The area below the @wordpress-plugin tag is what WordPress will read in order to generate the plugin's title, description, and relative links in the plugin dashboard of WordPress.

Next, we prevent anyone from accessing the file directly. And, finally, we create a custom function to be fired with the plugins_loaded hook. This function is what will be used to start the plugin.

At this point, you should be able to log in to WordPress, navigate to the Plugin's Dashboard, and then see the plugin available to activate. Go ahead and click Activate.

Nothing will happen yet, but we'll start adding functionality as we work throughout this tutorial.

2. Creating the Submenu Item

In order to begin working on the plugin, let's first introduce a submenu item. To do this, we'll need to take advantage of the WordPress API function add_options_page. This function will require five parameters:

  1. the text to display as the title of the corresponding options page
  2. the text to display as the submenu text for the menu item
  3. the capabilities needed to access this menu item
  4. the menu slug that's used to identify this submenu item
  5. a callback to a function that's responsible for rendering the admin page

Note that we'll be using classes to organize our functionality, so much of what we're doing is going to be object-oriented.

First, let's create a class in the admin directory called class-submenu.php. Since this class is responsible for introducing a new submenu, we'll have it named descriptively.

The contents of the class should look like this:

At this point, the plugin will still not do anything. We still need to create the actual Submenu_Page class, and then we need to wire the classes up to the bootstrap file.

3. Creating the Submenu Page

Let's start with the Submenu_Page class first. Create another file in the admin directory and call it class-submenu-page.php. Then, in the file, add the following code.

When this page renders, it will simply display the text: "This is the basic submenu page." We'll eventually get into adding new options. But first, let's bring this plugin to life by instantiating it within our bootstrap file.

4. Rendering the Menu and the Page

Next, open the custom-admin-settings.php file that we created earlier in this tutorial. Let's go ahead and write the code necessary to introduce the new submenu item and its associated page.

Remember, the Submenu class requires that an instance of the Submenu_Page class be passed into its constructor, and then we need to call the init method on the Submenu class to set the whole thing into motion.

In code, this looks like the following:

At this point, you should be able to refresh your installation of WordPress, activate the plugin (if it's not already activated), and then see your new page rendered within the administration area.

The custom WordPress administration screen

In the next article, we'll look at how we can begin introducing actual settings into the screen. Additionally, we'll look at some best practices in terms of working with our template and our template partials, and then we'll see how they will be wired up to the APIs responsible for not only saving them but how we will sanitize and validate them.

But before we go that far, I want to talk a little bit about the class design that we've seen in this tutorial. Generally speaking, I want to talk about why we have a class for the Submenu and the Submenu_Page and how it relates to the bootstrap file.

A Word on Class Responsibility

For those of you who are familiar with the Single Responsibility Principle, this section may not be of any interest to you. But if who need a refresher or want to hear more, then read on.

Gather together the things that change for the same reasons. Separate those things that change for different reasons.

There's more much to this, but if you were to look at each of our classes (at least the two we have thus far), then it's clear that the reasons our classes may change are as follows:

  • The contents of the submenu may change. Anything from the page title to the menu slug and everything in between.
  • The way the page renders its contents may (and will change). Specifically, right now it does nothing but echo a string. Soon, it will include a particular file. After that, it may need to include multiple files.

The above two reasons are two very different reasons that classes may change, so keeping them together in the same class would violate the above principle.

Ultimately, I bring this up not only to help shed light on greater software engineering principles that can be applied in WordPress, but also to help prepare you for some of the reasons we're going to be breaking apart certain things that are usually large files within the context of plugins.

The nice thing about learning principles is that they can be applied in multiple projects and not just in single projects. You learn them, you practice using them, and you get better at architecting solutions for other people. 

The learning curve may be steep, but once you begin that uphill climb, it gets easier and easier to incorporate the principles into your day-to-day work. Then, the work you're providing for others becomes much easier to maintain over time.


Don't forget that you can download the plugin in its current state from this post. As we progress through the series, I'll make the latest version available on each post so you will be able to follow along with the code covered in each tutorial, tinker with it, and prepare questions that you may want to ask in the comments.

As a side note, if you're looking for other utilities to help you build out your growing set of tools for WordPress or for code to study and become more well-versed in WordPress, don't forget to see what we have available in Envato Market.

Remember, you can catch all of my courses and tutorials on my profile page, and you can follow me on my blog and/or Twitter at @tommcfarlin where I talk about various software development practices and how we can employ them in WordPress.

Finally, don't hesitate to leave any questions or comments in the feed below. I do my best to participate and answer every question or critique you offer as it relates to this project.




Related Articles