Using namespaces in WordPress themes and plugins

I consider myself a relative newcomer to WordPress plugin and theme development, but I have programmed in PHP for more than a decade. That said, my first attempts to create a theme and plugin consisted of taking someone else’s work and tweaking it till it did what I wanted it to do. In short, the classic hacker’s learning process.

I’ve now moved on to the next phase of the learning process — applying ideas from work in other applications to WordPress. That means getting rid of stuff in my themes and plugins that I thought I needed but don’t really need, and tailoring each kind of project to their specific requirements.

One idea drilled in the WordPress documentation is namespacing. It’s not called that specifically because WordPress has been around long enough to predate PHP’s support of namespaces. But in exploring tutorials on theme and plugin development, I saw a lot advice about giving functions a unique prefix. In other words, use naming conventions to enforce a namespace.

Many enterprising developers have encapsulated their plugins with object-oriented programming, a practice to which I adhere myself. But the first versions of my plugins resulted in some unwieldy and oftentimes long-winded naming.

For example, the Musicwhore.org Artist Connector for WordPress prefaced class names with Musicwhore_Artist_Connector_, Musicwhore_ or some variation of the two. The file names followed suite, with such names as musicwhore_artist_connector_db_driver.php and musicwhore_artist_connector_post_meta.php.

To reign all this verbosity, I looked to the PHP Framework Interop Group standards for a bit of guidance. WordPress doesn’t follow the PHP-FIG recommendations, but it doesn’t mean there aren’t any good ideas there. One of them is the use of PHP namespaces.

The WordPress plugin environment is rightly concerned about naming collisions — my function named setup should have no effect on someone else’s similar function named setup. At the same time, something cryptic as mwac_setup is hardly readable.

PHP namespaces allows me to carve a place where my readable names won’t collide with anything else, perhaps even WordPress core itself!

This example is a very abbreviated form of what I use in the Musicwhore.org Artist Connector.

namespace VigilantMedia\WordPress\Plugins\Musicwhore\ArtistConnector;

Setup::init();
Settings::init();
Rewrite::init();

I’ve encapsulated my initialization tasks as methods in individual classes and gave them simple names. Without namespacing, I would have had to resort to a naming convention.

Musicwhore_Artist_Connector_Setup::init();
Musicwhore_Artist_Connector_Settings::init();
Musicwhore_Artist_Connector_Rewrite::init();

A classic WordPress example would forgo namespaces and classes altogether.

function musicwhore_artist_connector_setup() {
     add_action('init', 'musicwhore_artist_connector_init');
}

function musicwhore_artist_connector_settings() {
     add_action('admin_init', 'musicwhore_artist_connector_settings_init');
}

function musicwhore_artist_connector_init() {
    // Initialization tasks go here.
}

function musicwhore_artist_connector_settings_init() {
    // Initialization tasks go here.
}

The example with namespacing demonstrates an idea common to web frameworks: don’t repeat yourself. Time-honored WordPress naming conventions tend to be very repetitive.

Namespaces work well with organizing widgets, template tags and the functions.php file in a theme. The twentyfifteen WordPress theme, for example, uses traditional naming conventions to emulate namespacing.

function twentyfifteen_entry_meta() {
    // ...
}

function twentyfifteen_categorized_blog() {
    // ..
}

Object-oriented programming can simplify this organization.

class TemplateTags {

    public static function entry_meta() {
        // ...
    }

    public static function categorized_blog() {
        // ...
    }
}

Now say you have a child theme based on twentyfifteen. You can still create a TemplateTags class without having to use naming conventions to distinguish itself from the parent theme.

namespace WordPress\Themes\TwentyFifteen {
    class TemplateTags {
        public static function entry_meta() {
            // ...
        }

        public static function categorized_blog() {
            // ...
        }
    }
}


namespace WordPress\Themes\TwentyFifteenChild {
    class TemplateTags {
        public static function entry_meta() {
            $output = \WordPress\Themes\TwentyFifteen\TemplateTags::entry_meta();
            // ...
        }
    }
}

Namespaces have been available in PHP since version 5.3, which reached end-of-life support back in August 2014. So they should be very well supported on servers keeping up with PHP upgrades.