WordPress Development – Actions (tutorial)
Actions
This is the first in a series of WordPress development tutorials we will be publishing. The subject will be divided by topics. You will need nothing more than a WordPress previously installed on your own server and some rudimentary PHP knowledge. Our intent is to spread knowledge about the platform as well as sharing some of the lessons we have been learning over time.

Figure 1: Functions.php location inside Twenty Seventeen theme.
In a future tutorial we will cover the development of plugins, but for now we will limit ourselves to creating functionalities using the functions.php file, way more convenient for our small experiments. This file, which exists at the root of each WordPress theme, in /wp-content/themes/(theme folder)/functions.php (figure 1), allows running auxiliary code that does not make sense to apply across a plugin.
It is important to point out that the functions.php is specific to your theme, so it only runs when the theme is active, leaving no effect when choosing a different one.
Let’s open the functions.php file in our favorite code editor (in the absence of one, a basic text editor such as Notepad works perfectly), and prepare to take the first steps through the cogs of WordPress.
Hooks
WordPress’s application programming interface (API) is mainly based on the concept of hooks. These hooks relate to a series of events that may occur in the platform’s lifecycle, and in which we can “hang” our own functions, changing WordPress’ behavior in response to them.
The biggest advantage of this hook mechanism is to allow modifying the platform without messing with the source code of WordPress itself, nor in themes nor in third-party plugins. The changes introduced through hooks are modular and agglomerated with those of other plugins or themes.
There are two types of hooks: actions and filters.
Actions are behaviours triggered by a specific situation, such as the presentation of the page header or footer, the publication of an article, or the creation of a new taxonomy.
Filters are similar, except they have the ability to receive data, transform it, and pass it through. Filters will be the topic of the next tutorial.
My first action
To code our first action, we need to create a function that implements it. At the end of functions.php file, we will type the following code that will outputs an HTML tag:
function tutorial_meta_greeting () {
echo '<meta name="greeting" content="Olá, mundo!"';
}
The tutorial_meta_greeting function, by itself, still does nothing. You must associate it with a WordPress hook that can invoke it by adding the following line:
add_action( 'wp_head', 'tutorial_meta_greeting', 10, 0 );
This line tells WordPress to execute our function whenever an event occurs with the wp_head label, a hook that is triggered when generating a page header. We are thus writing a <meta> tag in the headers of our pages. The result is visible by browsing the HTML of any page on the site:

Figure 2: Our first experiment result.
We can associate various functions to the same hook. Sometimes, however, it is necessary to ensure that certain functions take precedence over others. Here enters the third parameter of add_action function, which concerns the execution priority. That parameter is optional, but in our example we explicitly declared it to be 10. Another function associated with the same wp_head hook, but with a lower priority level would run before our function. With a higher value, it would run afterwards. In example:
function tutorial_meta_before () {
echo '<meta name="before" content="Before salutation.">';
}
function tutorial_meta_after () {
echo '<meta name="after" content="After salutation.">';
}
add_action( 'wp_head', 'tutorial_meta_before', 5, 0 );
add_action( 'wp_head', 'tutorial_meta_after', 20, 0 );
The fourth parameter, which is optional, indicates the number of arguments that the hook passes to the function. In this case, wp_head, no parameters are passed.
wp_head is just one of many actions. There is a Codex list of all actions support by WordPress, and it is also possible to create new actions and, of course, respond to others offered by themes and plugins. Also very useful is Adam Brown’s WordPress Hook Database, a service which contains a more technical reference of all the hooks supported by WordPress in each of its versions.
More and better
Actions can use a lot of WordPress data and are not limited to what they receive as an argument. In example, we can change our tutorial_meta_greeting to display a more friendly message:
function tutorial_meta_greeting () {
global $current_user;
if (is_user_logged_in()) {
echo '<meta name="greeting" content="Olá, ' . $current_user->display_name . '!">';
} else {
echo '<meta name="greeting" content="Olá, mundo!">';
}
}
The above function will verify if the user is authenticated using WordPress’ is_user_logged_in function, and having obtained the global variable $current_user, which contains the user’s data, displays a custom greeting. The remainder will receive a more generic message in the <meta> tag.

Figur3 3: Customised greeting.
Inserting a simple <meta> tag into the header may not seem like the most useful thing, but it’s a simple exercise to explain the essence of how WordPress hooks work.
For a more practical example, let us apply this knowledge to add an HTML block of Google Analytics to the footer of our pages:
function tutorial_add_google_analytics () {
$tracking_code = 'UA-XXXXX-X'; // Don't forget to define me
echo '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22http%3A%2F%2Fwww.google-analytics.com%2Fga.js%22%20type%3D%22text%2Fjavascript%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />';
echo '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%3E'%3B%0A%20%20%20%20echo%20'var%20pageTracker%20%3D%20_gat._getTracker(%22'%20.%20%24tracking_code%20.%20'%22)%3B'%3B%0A%20%20%20%20echo%20'pageTracker._trackPageview()%3B'%3B%0A%20%20%20%20echo%20'%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />';
}
add_action( 'wp_footer', 'tutorial_add_google_analytics' );
Other practical uses for actions include, for example:
- Sending emails every time a new article is published;
- Logging user’s authentications in a log file or a database;
- Inicialize or prepare data at the beginning of a page request.
Delete actions
As we associate functions with hooks, we also have the possibility to remove them with the remove_action. Let’s say we are only interested in authenticated visitor usage statistics, so we should ignore the tutorial_add_google_analytics functions for the rest.
if (!is_user_logged_in())
remove_action( 'wp_footer', 'tutorial_add_google_analytics' );
Again, we used is_user_logged_in to determine if the visitor is authenticated, and if not, we removed the tutorial_add_google_analytics function from the role of actions to be performed on hook wp_footer. Like add_action, we can indicate the priority and number of arguments if we just want to remove specific occurences of a function.
A simple and very practical application of remove_action is to eliminate some of the HTML tags that denounce old and potentially unsafe versions of malicious visitors. Like this one:
<meta name="generator" content="WordPress 3.3">
To hide this data, inserted in the header by WordPress’ internal function wp_generator, we need to append the following to functions.php:
remove_action( 'wp_head', 'wp_generator' );
New actions
Defining new custom actions is as simple as invoking them in any part of our code withdo_action. Adding the following to the end of functions.php:
do_action( 'tutorial_new_action' ); // Without arguments do_action( 'tutorial_new_action', $arg1 ); // With 1 argument do_action( 'tutorial_new_action', $arg1, $arg2 ); // With 2 arguments do_action( 'tutorial_new_action', $arg1, $arg2, ..., $argN ); // With N arguments
This line will activate all the functions that are associated with the hook tutorial_new_action, allowing zero or more arguments.
In the next tutorial, we will look at the second class of hooks, the filters. We will learn how to create functions to transform the presentation of WordPress’s content.