The basics of Wordpress plugin development

Everyone knows the usefulness and versatility of Wordpress and the best way to customize this tool is to create plugins. Develop a plugin is not so hard and allows you to have code that does not interfere with the behavior of Wordpress itself and at the same time creates code that is packaged and easily reusable in another Wordpress installation.

We will see in this short tutorial the creation of a plugin, i tried to maintain the code the simplest as possible but with all the basic elements of a more complex plugin, the elements are:

  • use of the database to configure the plugin;
  • administration configuration screen;
  • interaction with the public site;
  • use of css/js resources;
  • common code containing information about the plugin.

This short guide is intended as an introduction to the development of a Wordpress plugin by touching most of the basic topics in order to get an idea of the starting point of the development, and to avoid the initial difficulties that may arise.

There are many ways to organize a plugin, start from an existing framework or modify an existing plugin, in this case I wanted to be as simple as possible and reduce any unnecessary code structure.

First off this is the repository with the code if you want to get the whole code.

Let’s see the files organization:

.
├── admin-layout.php
├── content.php
├── static
│   └── style.css
└── timed-popup.php

The main files are:

  • admin-layout.php, is the php file that is shown in the Wordpress admin, the configuration page in the wp-admin;
  • content.php, is the php file used to modify the layout of the public site;
  • timed-popup.php, is the main php file, named with the same name as our plugin to avoid conflicts with other plugins when the plugin is installed; the file contains the common code and information about the plugin. In an even more minimal plugin it is also possible to have only this file.

Let’s see each of these files in detail to understand how the plugin works and see it in action.

The main file (timed-popup.php)

As you can see the first part of the file consists of a comment structured in a particular way containing different information that will be read by Wordpress and shown to the user in the admin.

A complete list of these meta-information is available in the Wordpress documentation.

Abort the code execution if the special constant WPINC is not defined, if is not defined it means that the code is called directly.

Now it is possible to define constants that can be reused within the plugin, containing version and directory of the plugin.

The function plugin_dir_url returns the absolute URL of the plugin and is helpful to quickly retrieving the URL to show static resources that will be used in our plugin.

We are going now to register the activation and deactivation functions of the plugin, which will be called at the time of installation and uninstallation of the plugin; it is a good rule to clean the database and any other no longer useful data at the time of uninstallation.

The function register_activation_hook register our function activate_timed_popup at the activation hook and register_deactivation_hook register our function deactivate_timed_popup at the deactivation hook.

A hook in the Wordpress context it is a function that is called at a determined time during Wordpress execution; it is this mechanism that allows developers to write Wordpress plugins. For example, in this case we execute custom code, that is the “behavior” of our plugin when the plugin is installed and uninstalled.

Note: There are two types of Wordpress hooks: actions and filters.

  • The filters are hooks that are executed by Wordpress and are used to receive data as input and then eventually return modified data or to modify the global state.
  • The actions are hooks that are executed by Wordpress and they have the task of executing code at a given moment; an example of actions are the functions that we are considering now.

In any case, here is a list of all actions available and of all available filters.

Normally actions and filters are registered with the functions respectively add_action and add_filter, used in this way:

Where example_action and example_filter are the predefined actions and filters of Wordpress to which we link our functions.

While register_activation_hook and register_deactivation_hook are wrapper functions that help you to register our activation and deactivation hooks, in any case we could have used add_action instead of these two functions.

Now let’s add the menu item of our plugin to the Wordpress admin. With the function add_theme_page we can add the menu item directly in the sub-menu Appearance of Wordpress, otherwise we could have used add_menu_page to add the item directly to the main menu.

The items of the function are, in order:

  • the text that Wordpress will show to notify the user of the current page when the menu is selected;
  • the text to show in the menu;
  • manage_options is the name of a capability that is the name of one of the standard permissions available to users who access the Wordpress admin. If a user does not have this capability available, he will not be able to access the plugin via this menu item;
  • the slug ie the identifier of the item within this menu;

Note: the function __ is used to translate a string through files .po, i refer to the site for further clarification on this concept.

The function that adds the menu item, that is ours timed_popup_admin_menu which in turn calls add_theme_page, is called when the admin_menu action is called by Wordpress.

For this reason we use add_action.

Now through the action wp_enqueue_scripts let’s add the css/js resources, so when Wordpress calls the action wp_enqueue_scripts it means that it needs to get the css/js resources from the plugin to add to the public page. We add them with wp_enqueue_style for the css and wp_enqueue_script for the js resources. The arguments of these functions in order:

  • a unique identifying string of the resource that Wordpress will use;
  • the url of the resource, in this case built by adding the absolute url of the plugin declared earlier.

Now we register the action wp_footer which is called when the body of the html is closed.

When this action is executed our plugin executes the require of our content.php page, that is, it adds our personalization to the public layout of the website.

The plugin executes require, however, only when certain conditions are valid, configurations that I get from the db, through the function get_option. The value we get is deserialized, that is, from a string representation we get a PHP data structure, an array in this case. Reference to the function unserialize on the PHP site, being unserialize a native PHP function.

The menu item of the plugin in the admin
The menu item of the plugin in the admin

La grafica dell’admin (admin-layout.php)

From here on the explanation touches only the topics that concern Wordpress concepts directly; the logic of the code is linked to the goals of this particular plugin, you can take it as a starting point to organize the customizable parts of your plugin.

I put at the top the php logic that insert and retrieve the data from the database, and the html part of the page at the bottom.

We get the configurations from $_POST.

Since $timed_popup_text contains html and will be shown in a wysiwyg editor you need to run some filters on the input:

Now we save the configurations in the database with update_option with the arguments:

  • configuration name;
  • configuration string we transformed from php array to string with serialize and we will transform back again after with unserialize.

We get the configuration regardless of whether it has just been saved in db or not.

Set some configuration variables.

<div class="wrap">

    <h1><?php _e('Timed popup settings'); ?></h1>
    <p>
        <?php _e('Customize the data to display your timed popup.'); ?>
    </p>

    <form id="timed_popup-admin-form" method="post" action="">

        <table class="form-table">
            <tbody>
                <tr>
                    <th scope="row"><?php _e( 'Popup active' ); ?></th>
                    <td> 
                        <label >
                            <input name="timed_popup_active" type="checkbox" id="users_can_register" <?php echo $timed_popup_active ? 'checked' : ''; ?>>
                            <?php _e( 'Check to enable' ); ?>
                        </label>
                    </fieldset></td>
                </tr>                
                <tr>
                    <th scope="row"><?php _e( 'Display delay in seconds' ); ?></th>
                    <td>
                        <input name="timed_popup_time" type="text" value="<?php echo $timed_popup_time; ?>" class="regular-text" /><br>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php _e( 'Text content' ); ?></th>
                    <td>

And I show the configuration panel in the Wordpress admin, the class names and the structures are standard and allow to have a uniform layout with the rest of the admin.

The function _e print the translated string, once again i refer to the Wordpress site as far as plugin translations are concerned.

                        <?php wp_editor( $timed_popup_text, 'timed_popup_text' ); ?>
                    </td>
                </tr>
                <tr>
                    <tr>
                        <td colspan="2">
                            <button class="button button-primary" id="timed_popup-admin-save" type="submit"><?php _e( 'Save', 'timed_popup' ); ?></button>
                        </td>
                    </tr>
                </tbody>
            </table>

        </form>


    </div>

The function wp_editor shows the default wysiwyg editor of the Wordpress installation with arguments:

  • html to be displayed;
  • html id of the editor.
The plugin administration screen
The plugin administration screen

The public site layout (content.php)

The last part is simple and consists of javascript code that shows a popup with the style given by the css included in the current Wordpress template (see wp_enqueue_scripts above).

<div class="timed-popup-modal-body">
    <?php echo isset($timed_popup_option['timed_popup_text']) ? $timed_popup_option['timed_popup_text'] : ''; ?>
</div>

I show the popup text, the $timed_popup_option variable was declared at the time of require of this file (the content.php) when the wp_footer action was performed (see above).

<script type="text/javascript">
setTimeout(function(){
    modal.style.display = "block";
},<?php echo isset($timed_popup_option['timed_popup_time']) ? $timed_popup_option['timed_popup_time'] : '0'; ?>*1000);
</script>

With this variable I execute javascript code that shows the popup.

The plugin in action
The plugin in action