Creating The Automatic Template Plugin

In this tutorial I am going to walk you through the creation of the automatic template display plugin that I created using Pods Extend. The plugin Pods Frontier Auto Template adds a tab in the Pods editor to all custom post type and custom taxonomy Pods for the plugin’s settings. Then, based on those settings, it automatically outputs a template when that Pod is being displayed.

I am doing this walk through for several reasons:

  • Give a concrete example of using Pods Extend, the Pods Plugin starter plugin.
  • Encourage you to contribute to this plugin or create your own.
  • Show how to retrieve Pods settings using the Pods API.
  • Show how to output Pods templates in the front-end without using this plugin.

This is an advanced tutorial that presumes an understanding of object-oriented PHP development. It covers how this plugin works “under the hood.” If you are looking for simple instructions on how to use the plugin, see this tutorial.

Setting Up The Options

Adding An Options Tab

To add an options tab to the Pods editor for post types and custom taxonomies, but not any other type of Pod, I added two filter hooks. Both filters use the same callback. For post type Pods I used ‘pods_admin_setup_edit_tabs_post_type’ and for taxonomies I used “pods_admin_setup_edit_tabs_taxonomy”. To add the tab to the editor for all content types I could have used ‘pods_admin_setup_edit_tabs’ instead.

These filters have three parameters, $tabs, $pod and $addtl_args. In the callback function, I only used $tab. This variable contains all of the tabs set by default in the method admin_setup_edit_tabs in the PodsAdmin class. That means that this filter could also be used to remove a default tab from the editor, or one set by another function hooked to this filter, using unset().

In the callback, I added one new key to the $tabs array, like this:

$tabs[ 'pods-pfat' ] = __( 'Frontier Auto Display Options', 'pods-pfat' );

The name of the key is important as it must match the key in in the options field array. The value of the key in this array sets the name of the tag.

Adding Option Fields

In order to add options to the tab I added another filter, ‘pods_admin_setup_edit_options’. This filter type also supports adding content type, as well as the pod name to the end in order to target specific content types or specific Pods. For this filter I chose to address all content types and then use the variable $pod that is provided by the filter to determine the content type and modify the $options array separately for post type and taxonomy Pods.

The variable $pod is an array that has a key ‘type’ that contains the cotnent type of the current Pod. In the callback function, I created a conditional that if that key equals ‘post_type’ it adds a key of the same name that I added to the $tabs array, with three new fields. If that key’s value is ‘taxonomy’ I add two fields, and if it is neither, I add nothing.

Retrieving Pods Settings With The API

Now that all of the settings fields are added, it’s time to use the Pods API to get those settings back, in order to use them to output the Pods Templates.

Getting The Names Of All Pods

If you look in the front-end class of the plugin you will see it has only four methods, besides the __construct() function. This class is really a three step process as the last method, load_template() exists to eliminate redundant code in that third step.

The first step is to get the names of current post type and taxonomy Pods. The Pods API offers a method, load_pods(), that can be used to load the names of all Pods. The example code below shows how to use the function pods_api()to load the PodsAPI class, without specifying a specific Pod, and then use the load_pods() method to load just the names–using the “names” argument–and only taxonomy and post type Pods–using the “type” argument.
[gist id=”9879725″]

Getting and Working With Pods Settings

The second step is to build an array of Pods that have a the auto display mode enabled, along with the name of the templates to use for single and archive view. This method, auto_pods(), starts with the array created in step one and then passes the array through a foreach loop.

That loop builds a Pods API object for each Pod and then, if auto templates are enabled, uses pods_v() to extract the values we need from one of the arrays in the Pods API object. All of the Pods’ settings that we need are in the array ‘pod_data’ in the options key. I explained in the previous article in this series why pods_v() is the best tool for this sort of job.

Using it allows you to skip using isset() to check if a key exists, which in this case it will not if the setting has never been set. It also allows for a default value to be set, simplifying both the construction of this method’s output array and working with it. Since the array is built using variables, and those variables are created with pods_v() if no value has been set, the variable, and therefore the value in the output array is false.

Using Transient Caching To Improve Performance

The two previous steps are necessary in this process, but doing them on every single page load doesn’t make any sense, since the results will be the same every time, until the settings are changed. For this reason, I used the transients API in both of these methods to cache the results in the database.

As a result, after the first time these methods are called, instead of building a Pods API object, which involves a fair number of database calls, the plugin just gets the cached results from the database.

If you are new to the Transients API, I recommend you read this series of articles about using it. The article mainly uses WP_Query in its example code, but you can easily substitute other classes, like PodsAPI or Pods, like I do in the first two methods in the front-end class.

Of course, whenever Pods settings are updated, it is possible that the cached values are no longer valid. For this reason it is important to clear this cache whenever updating Pods settings.

This is accomplished in the main plugin class, not the front-end class, since that class isn’t active when in the admin. The plugin uses WordPress’ ‘update_option’ hook and a callback function that checks if one of the options that is always updated when Pods settings are updated is being updated. If so, the transients set by these two methods are deleted.

Outputting Pods Templates In The Front End

The result of the first two steps is an array containing the names of each Pod that has auto templates enabled, and the names of the templates to use. The third step is to use that data to retrieve and output the Pods Templates.

Using A Content Filter To Output Pods Templates

The method that creates the output for this plugin, front(), is hooked to the_content filter. It determines the current post type and if a single or archive view is called for, and then it attempts to load a template to append to the post’s content. The template loader method simply takes the $content variable from the filter, the template name, and the current Pods object and uses pods::template() to retrieve that template. In order to prevent errors, the result is checked to ensure it is not null before returning it. You can how this works here:

[gist id=”9923700″]

How It Works In Pods Frontier Auto Display

For one of my screencasts, I wrote an example plugin for appending a template to the  post content. It served as the genesis for this project. It is very simple, as it has the post type name and template name hardcoded. It also does not differentiate between the single or archive view. The front() method in the front-end class of Pods Auto Display does essentially the same thing as this simple plugin, just with a lot of conditional logic.  It’s a good place to start, both for understanding how the more complicated version works and for doing your own version.

[gist id=”7540721″]

If you look in the source you can follow the conditional logic. I will not walk you through it here, as determining what post type or taxonomy is currently being displayed is a different topic and the logic should be obvious. It simply determines the current content type being displayed, and if it is a single or archive view of that content, and then attempts to load the template set by the plugin, if one was set.

Doing This Manually

This plugin is designed to make it very easy to output Pods Templates in the front-end and every effort has been made to make it as efficient as possible, but if you didn’t need the flexibility and interface you could implement the same functionality more efficiently with hardcoded values. If you only had a few post types and templates, you could create one function to handle each condition. With a lot of post types and templates that would create a lot of redundant code. Instead you could turn the front-end class into its own plugin for your site, remove the the_pods() method, and turn the auto_pods() method into an array of the post type and templates. This would greatly increase the efficiency of the plugin.

Also keep in mind that the same system could work without using Pods Templates. Instead of appending Pods Templates to the content, you could append the value of another function where you outputted the custom fields using pods() or get_post_meta(). You might even want to add a views folder and instead of conditionally appending Templates, append the files in that folder, using file_get_contents()