How to limit WordPress’ compatibility, and why you should

As web designers, it goes against our nature to restrict access to our code. We’re taught to maximize compatibility of our websites and strive for backwards compatibility wherever possible; to create progressively enhanced and gracefully degrading sites. If we can make it work on IE1, that’s no bad thing…

The problem, at least for WordPress developers, is that WordPress is a monster; it will swallow you and your lovely little project whole if you let it.

When you’re producing a WordPress theme, either as a bespoke job for a specific client, or to resell on one of the many WordPress marketplaces, your goal can never be to cover everything that has ever been part of WordPress. Instead, your goal should be to use the key functions, features and filters in the best way possible to maximize the current codebase.

As a professional, your time is money, the longer you spend on your development the less profit you make; it’s a simple equation. The size of WordPress means that you can easily spend 80% of your time catering to 20% of the market. Far better to spend 80% of the time catering to 80% of the market. In terms of quality product and your own bank balance, it’s the surest approach.

In 14 key WordPress functions to jump-start theme development we went through some of the functions that, without fail, I include in my starter theme’s functions.php. In this article, we cover another crucial function that should go on your list of key WordPress functions. It will save you both head, and heart, aches down the road.

 

WordPress already limits backward compatibility

When an avoidable exploit brings your client’s site (that runs on your theme) down to its knees, who do you think they’ll call? Let me save you the guesswork: its you, m’kay? It doesn’t matter that whatever’s causing the problem isn’t at all your fault, to the client, it only matters that you’re the closest link to the possible problem. The last thing they remember doing is hiring you to build a new theme for them.

If upon inspection you find that the client’s site still runs on WordPress older than the current stable version, take a few seconds and slap yourself across the face: left cheek first, then right cheek. Your theme should not allow them to do that!

If you’ve been paying attention, as of about Version 3.6 of WordPress, you’ll have started to notice a function pretty high up in the default theme’s functions.php that restricted use of the default theme to versions of WP newer than 3.6. In fact it’s the second function defined in Twenty Fourteen’s functions.php!

That function looks something like this:

/**
* Twenty Fourteen only works in WordPress 3.6 or later.
*/
if ( version_compare( $GLOBALS['wp_version'], '3.6', '<' ) ) {
    require get_template_directory() . '/inc/back-compat.php';
}

We’re interest in the contents of that back-compat.php file. The functions defined there are what we’re after for use with our own themes.

 

No country for old WordPress

It almost doesn’t matter what features you’re implementing but if possible, limit the use of your themes to reasonably new versions of WordPress. That’ll make sure the end user updates their installation (all the better for them in terms of security) and ensures that you’re spending the majority of your development time on the majority of users.

Defining the function

To achieve this, we use the PHP version_compare() function to check the currently installed version of WordPress against the latest available version making sure that the latest installed version isn’t lower than 3.6—make your own selection on what version to test for, 3.6 isn’t a recommendation, just an example. That function looks something like this:

if ( version_compare( $GLOBALS['wp_version'], '3.6', '<' ) ) {
    // do (or do not) something
    function butter_never_get_old() {
        switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME );
        unset( $_GET['activated'] );
        add_action( 'admin_notices', 'butter_step_your_game_up' ); // we add some admin notices here (we haven't defined this function yet)
    }
    add_action( 'after_switch_theme', 'butter_never_get_old' );
}

What this function does is define an action function butter_never_get_old() that will only run when the after_switch_theme() core function is called. So far, the butter_never_get_old() function, which sits inside our version check, does the following:

  1. Checks what version of WordPress is currently installed
  2. Makes sure that version is newer than Version 3.6
  3. Runs the cosmically relevant If/Else:
  4. If it is: Activate the theme.
  5. If it is not: Do not activate the theme. Instead re/activate the default theme and, to be nice, output a nice little message that instructs the user to upgrade their ridiculously old installation. Come on, Grandpa!

Nudge, nudge! Upgrade that s#%*

Next, we need to define the butter_step_your_game_up() function which prints out our admin notices if something should go awry which would ostensibly mean that the WP version is older than we’d like.

function butter_step_your_game_up() {
    $update_message = sprintf( __( 'This theme requires WordPress version 3.6 or newer. You're currently using version %s. Please upgrade.', 'butter' ), $GLOBALS['wp_version'] );
    printf( '<div class="error"><p>%s</p></div>', $update_message );
}

The above butter_step_your_game_up() function sets our translatable error message string in the $update_message variable as defined (this theme requires… etc) which is then printed and displayed to the user (from within the earlier defined butter_never_get_old() function ) and visually, inside a div with class of ‘error’. This message, you can then style as desired.

So, all told, our function should look like this:

if ( version_compare( $GLOBALS['wp_version'], '3.6', '<' ) ) {
    // This function deactivates our newly activated theme if WP isn't newer than 3.6
    // It then re/activates the default theme
    function butter_never_get_old() {
        switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME );
        unset( $_GET['activated'] );
        add_action( 'admin_notices', 'butter_step_your_game_up' );
    }
    add_action( 'after_switch_theme', 'butter_never_get_old' );
    // This function, called from within the above function
    // outputs the relevant message that nudges the theme's user
    // to upgrade
    function butter_step_your_game_up() {
        $update_message = sprintf( __( 'This theme requires WordPress version 3.6 or newer. You are currently using version %s. Please upgrade!', 'butter' ), $GLOBALS['wp_version'] );
        printf( '<div class="error"><p>%s</p></div>', $update_message );
    }
}

With that in place, you’re ensuring that your theme cannot be activated on WordPress installations older than version 3.6.

Keep it clean

As far as possible, you should keep your functions.php clean. It should be clean in the sense that you should be able to quickly scan and immediately discern what each function is doing. To that end, we might want to move our function into an includes folder.

If you haven’t already, create a folder and name it ‘inc’ inside your theme’s directory. Inside that, create a php file and name that back-compat.php. Copy and paste the contents of the function we just created leaving only the version_compare() in functions.php:

if ( version_compare( $GLOBALS['wp_version'], '3.6', '<' ) ) {
    require get_template_directory() . '/inc/back-compat.php';
}

Inside the /inc/back-compat.php file, paste the functions we defined earlier:

function butter_never_get_old() {
    switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME );
    unset( $_GET['activated'] );
    add_action( 'admin_notices', 'butter_step_your_game_up' );
}
add_action( 'after_switch_theme', 'butter_never_get_old' );
function butter_step_your_game_up() {
    $update_message = sprintf( __( 'This theme requires WordPress version 3.6 or newer. You are currently using version %s. Please upgrade!', 'butter' ), $GLOBALS['wp_version'] );
    printf( '<div class="error"><p>%s</p></div>', $update_message );
}

 

Conclusion

It’s always a tough sell to tell a good developer that they have to limit the compatibility of their code. But the sheer size of the WordPress codebase, especially when you focus on backwards compatibility, makes limiting the scope of your theme a practical necessity. WordPress themselves doing so should highlight its validity.

And now, freed from the constant obstacles presented by out of date code, you can focus your energies where they belong: on harnessing the awesome power of WordPress.

Featured image/thumbnail, uses compatibility image via Shutterstock.

  • Zsolt Revay

    Good point & technique! In my experience clients can be lazy when it comes to keep their website updated so this can be a good example for them why they need to keep attention on updates. Buy a theme and find that the theme doesn’t work with you old wp. Well … it can light up a bulb that wp is a software like any other and it needs to be kept in good shape otherwhise you will face some anoying consequences like code malfunction and security issues. Thanks for the usefull tip!

  • http://w3blender.com/ w3Blender

    I have to say here that it’s a bad habit to use global variables. The correct and proper way to get the version number is to use the “get_bloginfo api” function.