In this lesson of the WordPress theme tutorial for beginners we will learn about hooks in WordPress and add a few hooks in our theme that is required for a theme to work properly with WordPress and plugins. We will also start accessing dynamic content from WordPress in our header, such as automatically getting the current page title.

First we need to learn a bit about hooks in WordPress. Hooks are a core functionality you need to get familiar with. I am not a fan of just showing a whole bunch of code in which you need to copy+paste without knowing what it really does. If you are following this tutorial, you want to learn this properly, right?

Don’t worry, I’ll keep it short for now. We will learn more about these later on in this tutorial.

Hooks in WordPress

In short; as WordPress executes all code for loading and rendering a page, there are certain “checkpoints” – which we call hooks. These points is where WordPress allows developers to modify or add their own code. WordPress has defined a whole bunch of “checkpoints” where, each with an unique name. If you know the name of it you can add your own code at these checkpoints. And thus easily tell WordPress to run your code when it reaches that checkpoint as part of its process.

There are two types of hooks; actions and filters. Actions are points in the code where you can add custom code, for example outputting something or doing something for your own purposes. Filters are points in the code where you can modify a certain variable before it’s used or outputted. They are very similar, but filters are attached to one specific variable and actions are not.

Plugins, themes, and WordPress itself can “hook” their code using add_action() for actions, and add_filter() for filters. These two functions tell WordPress to run the hooked code whenever the execution reaches these hooks.

In order to define hooks you use do_action() for actions and apply_filters() for filters.

For anyone who is interested in knowing more, I have a another post that goes into detail about hooks in WordPress.

A WordPress theme must include some specific important hooks (actions). These hooks allow WordPress, plugins, and our theme itself, to hook onto and do critical things. Let’s look at those critical hooks we need to add.

The theme’s header and footer hooks

All WordPress themes must have two hooks in the templates. One action must be placed in the header (inside the <head> tag), and another in footer (right before closing </body> tag). These two hooks are absolutely necessary so that WordPress, your theme, and any plugin are able to add their scripts and styles code to your theme.

The hooks we need are wp_head and wp_footer for the header and the footer, respectively.

Normally when we want to run a hook, we would call do_action(<hook name>). But because these two hooks are so critical, WordPress has simplified them for us by putting them in a simple function call. So for these two hooks you can simply use wp_head() and wp_footer(). In the background these two run the do_action().

Let’s add these two hooks (function calls) to our header and footer templates, and see what happens.

<!DOCTYPE html>
	    <meta charset="utf-8">
	    <title>A White Pixel Theme</title>

	    <?php wp_head(); ?>
		<?php wp_footer(); ?>

Hit refresh on your frontend. If you are logged in, you should now see WordPress’ admin bar appear! This means WordPress is now able to successfully add its scripts and styles to your theme.

You can check your HTML source and see that your header now contains quite a bit of code. This is code you didn’t add to your theme. As you can see, WordPress itself are using the hooks we added to do its own stuff.

Let’s move on from hooks and start looking into how we can dynamically fetch content from WordPress and output these in our header.

Dynamic content in header

Let’s tell WordPress to dynamically set the document title (for the <title> tag). For this we will use a function, (which has a filter by the way), called wp_title(). As we learned above, because wp_title() is a filter, you, WordPress or plugins can modify the output. We will add a filter to this later in this tutorial.

The function wp_title() takes several arguments which you can adjust to your liking, but for now I’ll add an empty string so that it only displays the title of whatever page we’re at.

Switch out your <title> tag in header.php into this:

<title><?php wp_title(''); ?></title>

The keen of you might have noticed that the frontpage will not generate a title. This is standard WordPress behavior which we will fix later on in this tutorial (we will do this by help of the filter). If you visit a single post or page, you should get the post title.

WordPress has a nifty function that dynamically generates a bunch of classes for the <body> tag depending on which page we’re at; called body_class. Update the <body> tag in header.php into this:

<body <?php body_class(); ?>>

Refresh and take a look at all the classes added to the <body> tag. Take a look on different pages (frontpage, single, category). All these classes are very useful for styling and to differentiate different similar parts. You will most likely use a few of these in your CSS.

To follow good HTML practices, we should also inform about the site language in the HTML. For this we use a WordPress function to get the language from Settings; language_attributes.

<html <?php language_attributes(); ?>>

And finally I’d like to add some meta tags and such which are not WordPress-specific, but follow common web design practices. This is what the full header.php file looks like:

<!DOCTYPE html>
<html class="no-js" <?php language_attributes(); ?>>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?php wp_title(''); ?></title>

    <?php wp_head(); ?>
<body <?php body_class(); ?>>

For the next step in this tutorial we will leave header.php and dive into index.php to learn how to fetch more dynamic content, such as posts.

Documentation on methods used