WordPress Actions & Filters with Closures

Closures (also known as Anonymous Functions) can be called by WordPress Actions or Filters instead of specifying a named function and can lead to cleaner code and escape from callback hell.

Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses.

from the PHP Manual

You’re probably used to the slightly roundabout way in which many WordPress operations are performed; for example, you may add an Action to call a function to register a meta box and call another function which contains its content:

add_action('add_meta_boxes', 'add_my_meta_boxes');

function add_my_meta_boxes() {
    add_meta_box('meta-id', 'Meta Title', 'my_meta_box', 'page', 'side');

function function my_meta_box() {
    echo 'Meta box content';

Example 1. Standard example of code to add a meta box to post.php

Functionally, there’s nothing wrong with the above; it’s reasonably self-documenting if you’re familiar with WordPress and the nature of hooks and callbacks makes it very scalable, but if you “just want to add a meta box” and are wondering “why does it have to be so difficult” then there is an easier way:

add_action('add_meta_boxes', function() {
    add_meta_box('meta-id', 'Meta Title', function() {
         echo 'Meta box content';
     }, 'page', 'side');

Example 2. Refactored code from Example 1 using Closures

The code in Example 2 does exactly the same as the code in Example 1. but it’s simpler and looks nicer (IMO). Anything within the closures will run at the hook as if you passed a named function.

if (!shortcode_exists('my-shortcode')) {
    add_shortcode('my-shortcode', function($atts, $content) {
        $content .= '!';
        return '<div class="my-shortcode">'.$content.'</div>';

Example 3. Adding a Shortcode

The code in Example 3 checks if your shortcode has already been added and, if not, registers it by calling add_shortcode which has a closure as its function to call. The closure appends an exclamation mark to whatever is between the shortcode tags, wraps it in a div and returns it. Another super-simple example of the power of closures in WordPress!

The only caveat is that, not being a named function, you cannot reference closures with remove_action or remove_filter so they cannot be removed programmatically. I’ll let you weigh the relative merits, suffice it to say that a closure would be most appropriate in cases where no-one would want to remove the action/filter so long as the theme/plugin is active.

Leave a Reply

Your email address will not be published. Required fields are marked *