WordPress Menu Pages are all those pages that you are using inside the WordPress admin area. If you have ever tried to add a menu page in WordPress admin area then you are aware of the work that needs to be done for various menu pages. In this tutorial we will create those menu page in a object oriented programming way.
This tutorial was inspired by Carl Alexander who teaches OOP in PHP and also tackles various situations in WordPress in the OOP way. You can read his tutorials and articles on his website https://carlalexander.ca/.
You can go straight forward and jump to examples to see what we will build: jump to examples.
How are we going to build it?
We will create classes WordPressMenu, WordPressSubMenu, WordPressMenuTab and WordPressSettings. WordPressSettings will be an abstract class that will be extended by WordPressMenu.
WordPressSubMenu will be extend the WordPressMenu to get all the basic logic from WordPressMenu and WordPressSettings. WordPressMenuTab is the class which is going to build tabs on menus.
The code that will be built here can be used in themes or plugins to easily create your own menus. Since WordPressSettings is the largest class of them all then I will leave that class definition at the end of the tutorial.
First, we are going to look at how others will be defined to provide an easy interface to build your menu pages.
Let’s get started!
WordPressMenu Class to add WordPress Menu
We will define the class first and also define a few attributes that are specific to this class.
Attribute $defaultOptions contains every option that can be set when creating our menu. By providing a set of options when constructing our menu from this class, we will merge that options with default options so that any option that is not provided, will be set from the default options.
Attribute $parent_id will be used to store the parent menu object. This will be used to create sub menus. And the last attribute is $menu_options which is used to store the merged options. This attribute is then used in every method that has to to use menu options.
In the __construct method we are merging the provided options with the default options and after they are merged we are checking if there is a slug in the options. If there is no slug provided, then we will not go further and we will not create the menu.
Once we are sure that the slug is set, we are setting our attribute settings_id (which will be set in WordPressSettings). This attribute will be used for storing our settings in the database. After that we are calling a method prepopulate to populate some of the options that are needed when creating our menus.
The last part of our __construct method are the hooks. The first hook is used to create the admin menus and we are hooking the method add_page. The second one is a custom action hook that we are going to define in the page of our menu. It is used to call the method save_settings that is used to save any set setting. This method is also a part of our WordPressSettings class.
Prepopulate our options!
Let’s define our method prepopulate to populate our menu options:
This is a really simple method. It will check if there is a title set and if not it will use the menu slug to create a title out of it. The second check is to see if there is a page title set and if not, then the title will be used.
Adding our page
Let’s now define our method add_page:
In this method we are first getting the function name from the menu options. If there is none, then we are setting the method create_menu_page which is used to render our fields, save the settings and also render our tabs. If the function is provided, then it will call a separate function to render it as a page of our menu.
The method also checks if the attribute $parent_id is set and if not it will create a parent menu page. If it is set, then it will create a sub menu.
Create our menu page
I have mentioned the method create_menu_page which is used to create our page, so it is now the time to create this method:
The first thing this method does is to check if our settings are submitted. We are also setting a default tab in the variable $tab. After that, we are checking if there is a tab specified by the global variable $_GET. If there is, then we are setting the tab to the provided tab.
The next part is initialising the settings so that we can use those settings when rendering fields. This method is also a part of WordPressSettings.
The only thing left now is to render our form and fields so we do that by creating a simple form and by calling methods render_fields, render_tabs and save_button. The first method is part of our WordPressSettings class. The method render_tabs is used to render the tabs registered to that menu. The third method is used to render the button with the appropriate attribute name.
Let’s now create the last three methods in this class: render_tabs, save_button and save_if_submit:
In the method render_tabs we are checking if there are more tabs registered than one. If there is only one tab then there is no need to render that only tab.
In the method save_button we are rendering the submit button with the attribute name created from the settings_id and the suffix _save. By doing that, we are ensuring that our action used for saving the settings will be called only when that menu page is submitted.
In the method save_if_submit we are checking if the submit button was posted (clicked) and then we are calling our hook to save the settings. If you remember, at the beginning of this class, we have added our method save_settings to this hook.
Now that our class for creating menu pages is complete we can move forward.
Creating a class for WordPress Sub Menus
In the previous class WordPressMenu we did some ground work to prepare us for creating sub menus. That was done by defining an attribute $parent_id and the method add_page where we are creating a sub menu page if the $parent_id is provided.
Since almost everything is already define we only need to make sure that when creating WordPress sub menus, our parent menu is provided:
Yep! That is everything we had to do. With this simple class which extended the WordPressMenu class, we have everything that we need. The only difference here is that we request a WordPressMenu object to be provided when creating WordPressSubMenu objects (menus). The __construct method is calling the __construct method from WordPressMenu and after everything has been set, we are setting the attribute $parent_id by using the parents’ settings_id which is the slug of the parent menu.
Creating a class to create tabs in WordPress Menus
The last thing before creating our abstract class WordPressSettings, we will create a class to easily add tabs to the menu and also fields for that tabs. This is only a really simple class that will only be used as a factory to register our fields and tabs.
Of course this is for real! I said it will be simple :). When constructing a tab with this class, we are setting the slug and the title for the tab. Once that is done we are also setting our menu to the attribute $menu and then we are adding this tab to that menu by calling the method from the menu add_tab (This method is also a part of WordPressSettings).
We have also created a method that will be used to add fields to that tab. We are calling the method add_field from our menu to add that field to the menu but we are also providing the slug of our tab so that our menu knows which field to show on which tab. The method add_field from our menu is also a part of WordPressSettings.
Now that everything is done here, we can finally go to our backbone of WordPressMenu and WordPressSubMenu classes: the class WordPressSettings.
WordPress Settings in a Class
We will now create an abstract class with methods and attributes that will be used in classes WordPressMenu and WordPressSubMenu. This one is the longest class definition so please bare with me on this one. We will start small and fill the class with new methods as we learn together.
We could have used the WordPress Settings API here to make this class smaller and easier to handle but for the purpose of this tutorial I want you to see how everything can be easily done also by yourself.
Here we have defined our attributes and the comments above each one are enough to understand what they do. Let’s focus now on the database part. We will create three methods, one to get all the settings from the database and fill the registered fields with values. Second one will be used to save the posted settings and the third will be used to get a particular settings by providing the name of that field. So add this next to our class:
This method gets our settings from the database that are saved under the key of our settings_id. After that we are traversing our registered fields and if there is a saved setting for each field, that field gets its default value updated. We update the default value because we will use that value when rendering fields.
We are fulfilling the attribute posted_data with the global variable $_POST so that we can use that attribute alongside other validation methods. We are also checking if we got the settings from the database and if not, we call our method init_settings(). After that we are again traversing through our registered fields and then we are calling dynamically the validation methods for each field type. Those validation methods will return the right value (we will define those methods later).
By providing the name of the field, this method will return the value for that field. If there is a saved setting for that field, it will return that value. If there is no setting saved for the provided field name, we will return the default value for that field if set.
Now that we have learned how to save and retrieve settings, let’s define the validation methods that are called in the method save_settings().
Here we are validating each field by getting the value of that field using the method get_option(). If there is a posted value for that field, we will return the value for that field. Otherwise the value from the method get_option() will be returned. The only difference is with the checkbox where we do not need to check the value from the database because if that field is not posted then it is not set.
We can get our settings from the database and also save those settings to the database. We now need a method to register the fields. Since we are always checking for tabs when saving or retrieving field values, we will need also a method to add a tab. Add this code now:
First we check if the field to add has an allowed type defined. If not we will not register that field. Since there can be fields without a type set because there is a default field type (text), we are checking the allowed field type only when there is a field type already defined in the provided array. The second parameter tab is used to save that field under a tab.
This method is really simple. If the array is set with the slug and title, the tab is registered for those settings.
Great job! You are still reading? Then it must be something right! We have almost everything that our class is needing. The last part is about rendering. Add this method to render fields:
This method is used to see if there are any registered fields. If there are none, we are displaying a message that there are no fields registered. If there are any fields, we are rendering the fields for the provided tab by dynamically calling rendering methods for the field type. Add this rendering methods as the last bits of the code for our class:
So now all our classes are defined. But how to use them? Here are a few examples:
One menu with only one tab
One menu with more tabs
Menu with submenu
In these tutorial we have learned how to create menu pages in WordPress using OOP. OOP helps us decouple the code into several logical parts so that we can easily maintain the code and also change the code if needed.Become a Sponsor