AMP Up Your WordPress Site with Google’s Accelerated Mobile Pages

#

You’ve probably heard about Google’s new Accelerated Mobile Pages project, or AMP. If you haven’t, it’s a specification akin to Facebook’s Instant Articles for the open web. The project is open source and has already been embraced by some big players, Automattic being the most notable for our purposes.

The AMP project provides a specification for building web pages that load incredibly quickly and are optimized for mobile devices. As Google puts it, “AMP is a way to build web pages for static content that render fast”. An AMP page needs to be built using AMP HTML, which is a subset of standard HTML with a few tags replaced with AMP-specific counterparts like <amp-img>. Google also requires pages to include the AMP JS library which performs optimizations on your page.

One of the main goals of the AMP format is to make pages easy to cache and (though the details are fuzzy here) Google plans to offer a free to use CDN-style cache for valid AMP pages.

AMP and WordPress

Automattic announced support for AMP back in October 2015 and has released a plugin for .org sites called AMP. The AMP plugin is available from the WordPress Plugin Repository now, but it’s a pretty spartan affair. After installing the plugin, you won’t notice any new administration screens or options, the only changes will include a new <link> tag added to your <head> HTML on single post pages and the addition of an /amp/ URL endpoint for single post pages.

I have a site running the default Twenty Sixteen theme and some sample content. Here’s how one of the posts looks in Mobile Safari – the standard post is on the left and the /amp/ version is on the right:

amp-out-of-the-box

The Twenty Sixteen theme already loads pretty quickly on mobile, but it’s worth mentioning that the AMP version of the page loaded and rendered noticeably quicker. That’s where the excitement ends though. The AMP page looks nothing like the rest of my site and what’s worse is it looks just like almost every other site out there that’s using the AMP plugin. As I mentioned, there are no options in the wp-admin for customizing the look of your amp page, so we’ll need to dive into some code if we want to make any changes here.

Customizing the AMP WordPress Plugin’s Output

The plugin’s readme has full instructions for customizing your AMP pages, so I won’t go too deep here, but I do want to cover some of the basics that WordPress theme and site developers will need to become familiar with if you want to incorporate support for AMP pages in your projects.

I’d like to at least make sure that AMP pages on my site still feel like my site, so I’m going to need to modify the general color scheme, and probably tweak the way that the header looks. There are a few options for doing this:

  1. Add a folder called amp to your theme and place override files in there. In this case, we’ll create a style.php file to completely override the AMP plugin’s default styling.
  2. Use the amp_post_template_file filter to specify a custom file to use instead of the default style.php file. This method is useful if you’re writing a plugin or don’t want to modify the theme for whatever reason. Similar to the amp folder in your theme file, you can use this filter to override any of the AMP template files. The code would look something like this:
    // Override AMP CSS with custom file 
    add_filter( 'amp_post_template_file', 'dbawp_amp_set_custom_template', 10, 3 );
    function dbawp_amp_set_custom_template( $file, $type, $post ) {
        if ( 'style' === $type ) {
            $file = dirname( __FILE__ ) . '/inc/amp-style.php';
        }
    
        return $file;
    }
    
  3. Finally, the AMP plugin provides the amp_post_template_css filter for appending CSS to the existing amp stylesheet which can be used alone or in addition to the previous methods. Since the whole point of AMP is to be as slim as possible, you’ll probably want to use one of the previous methods if you’re overriding a lot of the plugin’s existing styles. On the other hand, if you’ve just got a few tweaks, or the majority of the styles you’ll be adding will be additions and not overrides, the amp_post_template_css filter is probably the preferred method. It’s what I’ll be using to quickly fix up the look of my AMP pages. Here’s the code I’ve added to a functionality plugin:
    add_action( 'amp_post_template_css', 'dbawp_amp_my_additional_css_styles' );
    function dbawp_amp_my_additional_css_styles( $amp_template ) {
        // only CSS here please...
        ?>
        body {
            background-color: #425259;
        }
        nav.amp-wp-title-bar {
            background-color: #616a73;
            font-size: 30px;
            font-weight: bold;
        }
        .amp-wp-meta, .amp-wp-meta a {
            color: #CBD0D4;
        }
        .amp-wp-title {
            color: #fff;
        }
        .amp-wp-content {
            color: #fff;
        }
        <?php
    }
    

And here’s how that same AMP page looks now:

custom-amp

The AMP plugin’s readme file provides quite a few more filters that can be used to modify small bits such as the site icon or override entire template files as I outlined earlier, so make sure to check that out if you’d like to dive deeper into customizing the AMP plugin’s output.

Beyond Posts

One of the first things that you may notice after installing the AMP plugin is that it only provides AMP output for posts. The plugin’s description on the plugin repository explicitly states that “pages and archives are not currently supported.” It looks like that support will be coming in a future release of the plugin, but the same cannot be said for custom post types, so let’s look at how that might be accomplished.

For that purpose, I’ve added a custom post type to my site called profile. Profile posts will have a title, profile picture, and short bio. The title is the standard WordPress title that’s stored in wp_posts.post_title, but the other content will be stored in custom fields using the Advanced Custom Fields plugin. I’ve created a single template to show these profiles, but now I need to add an AMP HTML version of these pages as well.

First we’ll need to add the /amp/ route to our custom post type. Since we’ve already got the AMP plugin installed, we can add the route by piggybacking on the one that it already created:

add_action( 'init', 'dbawp_amp_init', 20 );
function dbawp_amp_init() {
    if ( ! defined( 'AMP_QUERY_VAR' ) ) {
        define( 'AMP_QUERY_VAR', apply_filters( 'amp_query_var', 'amp' ) );
    }
    add_post_type_support( 'profile', AMP_QUERY_VAR );
}

Adding the above code to a functionality plugin will utilize the route that the AMP plugin has created by enabling it for profile post types. If the original profile page existed at /profile/jenny-johnson/ the new AMP version of that profile will be available at /profile/jenny-johnson/amp/. This will also cause the AMP plugin to add the <link rel="amphtml"...> tag to the <head> of single profile pages, making the AMP version of the page discoverable by clients and search engines.

Finally, we need to coax AMP into actually rendering the page for us the way we want it to. To do this, we can use AMP’s amp_post_template_file filter to override the single template, but only when the post type is profile.

add_filter( 'amp_post_template_file', 'dbawp_amp_set_custom_template', 10, 3 );
function dbawp_amp_set_custom_template( $file, $type, $post ) {
    if ( 'single' === $type && 'profile' === get_query_var( 'post_type', false ) ) {
        $file = dirname( __FILE__ ) . '/inc/profile-template-amp.php';
    }

    return $file;
}

Now we’ll need to create the /inc/profile-template-amp.php file. Since we’re completely overriding the default single template, we’ll need to implement the entire AMP HTML file. We copy the AMP plugin’s /templates/single.php file and strip out everything within the <div class="amp-wp-content">...</div> tags and replace that with our custom template markup.

Here’s the stripped down single.php AMP template:

And here’s the code that we’ll add to render our profile posts, utilizing Advanced Custom Fields’ get_field() helper function:

<?php
$img     = get_field( 'profile-photo' );
$bio     = get_field( 'bio' );
$img_src = $img[ 'url' ];
$img_w   = $img[ 'width' ];
$img_h   = $img[ 'height' ]; 
$img_alt = $img[ 'description' ] ? $img[ 'description' ] : $img[ 'title' ];

$srcset = '';
foreach ( $img[ 'sizes' ] as $key => $val ) {
    if ( strstr( $key, '-width' ) || strstr( $key, '-height' )  ) {
        continue;
    }
    $srcset .= $val . ' ' . $img[ 'sizes' ][ $key . '-width' ] . 'w, ';
}
$srcset = substr( $srcset, 0, -2 );
?>
<div class="profile-content">
    <amp-img src="<?php echo $img_src; ?>" alt="<?php echo $img_alt; ?>" width=<?php echo $img_w; ?> height=<?php echo $img_h; ?> srcset="<?php echo $srcset; ?>" layout="responsive" class="profile-image"></amp-img>
    <p><?php echo $bio; ?></p>
</div>

The only material difference between this and the non-AMP template for our Profile pages is that we’re using the <amp-img></amp-img> tags in place of the standard <img /> tag. It’s worth noting that we’re also utilizing AMP’s layout="responsive" attribute and it’s stellar support for the srcset attribute to deliver an optimized, responsive image.

Again, despite the non-AMP theme and template being incredibly lightweight, the AMP version loads quite a bit faster and, thanks to our modifications, looks great as well. Check out the original (left) and AMP (right) versions of the page as rendered in Mobile Safari below:

amp-custom-post-type

Wrapping Up

It remains to be seen whether AMP will become mainstream, and it’s not without its critics. The fact that the project is open source and has already been embraced by the likes of Automattic, Buzzfeed, and even the New York Times means that it’s definitely worth paying attention to. The AMP plugin for WordPress also makes it easy enough to enable for WordPress blogs and not too much harder to enable and customize for all of your custom content.

Personally, I’m on the fence about AMP. I’ve been a huge fan of the web since the late 90s, and the steps forward that we’ve taken since then have been huge. Writing AMP HTML actually reminds me a bit of writing HTML emails, which feels like a big step back. I think it will be important for the AMP project to make clear what AMP is really for: if it’s just for long form articles and it can evolve a bit more to provide beautiful reading experiences that are responsive and load instantly on mobile devices, then I’m on board. But if AMP is meant to drive the next evolution of the web–what are we on now? Web 4.0?–then I’m not sure I’m on board.

What’s your take on AMP? Is this a specification that you’ll be embracing? How do you plan to integrate AMP into your WordPress site? Let us know in the comments!

About the Author

Jeff Gould

Jeff is a problem solver at heart who found his way to the web at an early age and never looked back. Before Delicious Brains, Jeff was a freelance web developer specializing in WordPress and front-end development.