Harness the Power of WordPress Hooks: Actions and Filters Explained

Like any CMS, WordPress won’t always meet your every need right out of the box. Since it is open-source, you could hack it to make it conform to your business needs—but instead, you can use WordPress’ hooks to achieve your goals. Building with hooks is a winning strategy that frees WordPress developers to build just about any website feature imaginable.

WordPress Hooks: Actions and Filters

WordPress hooks are not just powerful customization tools, they are how WordPress components interact with one another. Hooked functions manage many of the routine tasks we consider to be part and parcel of WordPress, such as adding styles or scripts to a page, or surrounding footer text with HTML elements. A search of WordPress Core’s codebase reveals thousands of hooks in more than 700 locations. WordPress themes and plugins contain even more hooks.

Before we jump into hooks and explore the difference between action hooks and filter hooks, let’s understand where they fit within WordPress’ architecture.

WordPress Infrastructure

WordPress’ modular elements readily integrate with one another, so we can easily mix, match, and combine:

  1. WordPress Core: These are the files required for WordPress to work. WordPress Core provides generalized architecture, the WP Admin dashboard, database queries, security, and more. WordPress Core is written in PHP and uses a MySQL database.
  2. Theme (or Parent Theme): A theme defines the basic layout and design of a website. Powered by PHP, HTML, JavaScript, and CSS files, a theme functions by reading the WordPress MySQL database to generate the HTML code that renders in a browser. Hooks in a theme may add stylesheets, scripts, fonts, or custom post types, for example.
  3. Child Theme: We create child themes ourselves to fine-tune the basic layout and design that parent themes provide. Child themes can define stylesheets and scripts to modify inherited features or add or remove post types. Child theme instructions always supersede those of the parent theme.
  4. Plugin(s): To extend the back-end functionality of WordPress, we can choose from thousands of third-party plugins. Hooks in a plugin could, for example, notify us by email when a post is published or hide user-submitted comments that contain banned language.
  5. Custom Plugin(s): When a third-party plugin does not fully meet business needs, we can turbocharge it by writing a custom plugin in PHP. Or we can write a new plugin from scratch. In both cases, we would add hook(s) to extend existing functionality.

Pyramid showing, from base to top, five levels: (1) WordPress Core, (2) Theme, (3) Child Theme, (4) Plugins, (5) Custom Plugins.
WordPress Infrastructure Hierarchy

Given that we have access to the source of all five layers, why are hooks needed in WordPress?

Code Safety

To keep up with evolving technologies, contributors to WordPress Core, parent themes, and plugins frequently release updates to mitigate security vulnerabilities, fix bugs, resolve incompatibilities, or offer new features. As any consultant with emergency experience knows firsthand, failure to keep WordPress components up to date can compromise or even disable a site.

If we directly modify local copies of upstream WordPress components, we encounter a problem: Updates overwrite our customizations. How can we circumvent this when customizing WordPress? Via hooks, in the child theme and custom plugin(s).

Coding in Our Child Theme

A child theme is a safe space where we can customize the look and feel of our installed theme. Any code added here will override comparable code in the parent without the risk of being overwritten by an update.

When a child theme is activated, it links to a deactivated parent, inheriting and exhibiting the parent’s characteristics while remaining unimpacted by the parent’s updates. So as not to fall prey to temptation to modify a theme, best practices suggest that a child theme be activated as part of our setup.

Writing Custom Plugin(s)

When a plugin is activated, its functions.php file executes with each call on the server. WordPress, in turn, loads and sorts hooks from all active plugins according to their priority and executes these sequentially. To extend the functionality of a third-party plugin, we can write our own WordPress custom plugin.

Where to Place Our Hooks in WordPress

Goal Example Where?  
    Child Theme PHP Custom Plugin PHP
To modify the structure of a web page Adding a custom stylesheet to change the colors and fonts of website elements  
To modify the functionality of another plugin (i.e., create a plugin to enhance the functionality of a third-party plugin) Adding a subheading (e.g., “News”) to custom post types  
To add a new feature that goes beyond WordPress Core Modifying the workflow that takes place when a post is visited to include updating a counter in the database  

Pre-dive Prep: Definitions

To avoid conflating terms, we’ll stick to this terminology:

  • A hook is a sweet spot in WordPress where functions are registered to run. We may connect our functions to one of the many hooks in WordPress and its components or create our own.
    • An action hook runs actions.
    • A filter hook runs filters.
  • A hooked function is a custom PHP callback function that we’ve “hooked” into a WordPress hook location. Which type to use depends on whether the hook is meant to allow changes outside the function—e.g., adding directly to the webpage output, modifying a database, or sending an email. These are known as side effects.
    • A filter (or filter function) should avoid side effects by only working on, then returning a modified copy of, the data passed to it.
    • An action (or action function), in contrast, is intended to cause side effects. It has no return value.

Diagram showing functions paired with compatible hooks. Filter hooks have filter functions attached to them, and action hooks have action functions attached to them.
WordPress hooks can have multiple callback functions, but all callback functions have to match the type of hook they’re registered with.

With these distinctions in mind, we can begin our exploration of hooks.

Abstraction and Clean Code

When an action or filter is incorporated into a hook, as needed, we fulfill the objectives of writing just one function per task and of avoiding the duplication of code within a project. For example, say we want to add the same stylesheet to three page templates (archive, single page, and custom post) in our theme. Rather than overriding each template in the parent, then recreating each in our child theme, then adding stylesheets to individual head sections, we can write code in a single function and attach it with the wp_head hook.

Thoughtful Nomenclature

Proactively avoid conflicts by naming a child theme or custom plugin hooks uniquely. Having same-named hooks in a single site is a recipe for unintended code behavior. Best practices prescribe that we begin the name of our hook with a unique, short prefix (e.g., author’s, project’s, or company’s initials), followed by a descriptive hook name. For example, using the pattern “project initials plus hook name,” for the project Tahir’s Fabulous Plugin, we could name our hooks tfp-upload-document or tfp-create-post-news.

Concurrent Development and Debugging

A single hook may trigger more than just one action or filter. For example, we could write a web page that contains multiple scripts, all of which use the wp_head action hook to print HTML (e.g., a