A Comprehensive Guide to Supporting AMP in WordPress


AMP is a new technology that’s gaining the attention of online marketers in every field.  It formats content in a way that loads blazingly fast for mobile visitors, whose page load time expectations can be as little as three seconds.

In this post, we’ll discuss what AMP is, as well as how to wire up your WordPress themes to support AMP templates.  You’ll find a large amount of information and code samples in this post.

Quick Links:

All About AMP


AMP stands for “Accelerated Mobile Pages.” It is an open source project backed by Google that makes web pages load really, really fast.  There are also some huge benefits for publishers who take advantage of AMP:

  • AMP pages are cached and served by Google itself.
  • Two versions of the page are now available to search queries: HTML and AMP.
  • They receive Google’s “Mobile-friendly” or “AMP” label in search results, notifying users that the page will load quickly.
  • Google may use AMP as a PageRank consideration in the future (“mobile-friendliness” already is).

Example of the Google “AMP” label.  Don’t ask why I was googling Pokemon Go.

Further reading: Does Google AMP Affect SEO?

In order for Google to cache your pages and give it the AMP label, it must have valid AMP markup.  AMP HTML is very similar to regular HTML5, with just a few exceptions.


AMP HTML is quite simple.  In most cases, it’s nearly identical to regular HTML5, with the exception that certain element tags are replaced with an AMP version.  For instance, the <img> tag becomes <amp-img></amp-img>.

Further reading: The AMP Spec Document

AMP has very specific standards. These standards are in place so that it can render each page as quickly as possible.  Here are some highlights of the requirements for valid AMP documents:

  • The document <head> must contain specific scripts and styles.
  • Only inline styles are allowed (No external stylesheets)
  • The inline styles are limited to 50Kb in size
  • Slow-loading elements — like <frame>, <object>, and  — are prohibited.
  • No custom JavaScript is allowed (but there are several AMP extensions that provide common JS functionality for you)

AMP Extensions (or, “Components”)

AMP Extensions are helpful components that expand what AMP does by default.

Below are a few noteworthy examples, but there are many other Extensions available.

amp-sidebar (or “menu”)
The AMP Sidebar extension is what is commonly used as a menu in WP.  It allows for a button (or other element, like a hamburger icon) to trigger a menu that slides into the page from the side.  I’ll discuss this in detail below.

This element can only be used once on a page, and it essentially only allows text, images, and accordions, so keep that in mind.

So your site depends upon ad revenue (who’s doesn’t?).  Thankfully, AMP provides a format for including these in your markup with the AMP Ad extension.


Hey, who doesn’t love Brightcove content?  To support the need for this feature, AMP has created the AMP Brightcove Extension.  Note that even if you have a lot of custom parameters to pass into Brightcove, you can still do that.

AMP Social Share is really quite handy, as it takes care of integrating a bunch of sharing into your template by passing just some basic attributes.

The WordPress AMP Plugin


The good news for you is that the team at Automattic has created a very nice plugin to handle creating valid AMP documents in WordPress.  It’s simply called “AMP,” but for clarity’s sake, I’ll refer to it as “WP AMP” throughout this discussion.

To a user, the plugin simply makes an AMP version of a post is available.  This post is found at the same URL as the post, but with “/amp” tacked on to the end.

So if the URL is yoursite.com/hello-world, the AMP version is found at yoursite.com/hello-world/amp/.

For developers, WP AMP is basically a templating system.  It contains a basic AMP HTML template, and uses hooks and filters to ensure your content is rendered as valid AMP markup.  For example, the provided template includes the required code for the <head>, and it filters the post content to ensure your <img> tags are replaced with <amp-img>.

Further reading: WP AMP plugin documentation

Screen Shot 2016-07-21 at 10.43.13 AM

The default WP AMP post template.

AMP Template Customization for Themes

So, if you’re a theme developer, you’ll want to customize this document’s appearance to match the rest of your layout so that your users will have a seamless visual experience.  The rest of this post discusses how to do just that.

Customizing the WP AMP plugin to work with your theme takes a bit of work, but it will definitely be a big bonus to your users.  As this is a growing technology, there will be increasing demand for the fast page load times and Google recognition that AMP provides.  At this point, it will set your work apart from other WordPress themes.

Basic AMP Support Setup

Note that this tutorial is written for WP AMP version 0.3.2.

1. Set Up Your AMP Directory

To get started, create a directory in your theme called “amp/”.  Inside that directory, create “amp.php.”  We’ll add all of our backend code inside this file.

Now take a step back, and require the amp/amp.php file near the top of your theme’s functions.php:

require( dirname( __FILE__ ) . '/amp/amp.php' );

2.  Register Your Custom Templates

Here’s where the fun begins.  We’ll be adding your own template files so that you can customize them to match your theme.

After this following step, your theme’s file structure should end up looking like this:



Start by creating a directory inside of “amp/” called “templates/”.  Not surprisingly, this will hold your template files.

Next, create a file inside templates called “style.php” (note that it’s a PHP file, not CSS).  If you like, you can just copy the default style.php from the WP amp plugin: wp-content/plugins/amp/templates/style.php.

Now, go into the WP AMP plugin and copy the default single.php file (wp-content/plugins/amp/templates/single.php).  Place this in your theme’s “amp/” directory.  It’s important that you copy this one instead of starting from scratch, as there’s important data in its <head>, plus it also contains some of the actions we’ll be hooking into later.

3.  Register Your Custom Templates

Add the function below to include support for both your new “single.php” and “style.php”

Going Further

Support Custom Post Types

If you have Custom Post Types in your theme, you’ll need to tell WP AMP what they are so that those posts will have AMP versions available.

Next, we’ll add our CPT templates.

Custom Post Type Templates

Adding special templates for your custom post types is optional, but the previous step is not.  You’ll want a special CPT template if your CPT posts have a different layout or functionality than a typical post.

In your /templates directory, copy the single.php and rename it after the slug of your CPT.  For instance, you may have a “book.php” now.

Then, we need to tell WP AMP to redirect to this template.  Edit the function that I called jr3_amp_custom_templates() earlier.  It will now look like this:

Component Scripts

Each AMP Extension (once again, also called a “Component”) has a supporting JS resource.

If you’re using any other Extensions in your template files, like amp-ad, amp-social-share, or amp-sidebar, you must register the JS with WP AMP so it gets loaded correctly.

Customizing Your Template

Custom CSS

As AMP does not allow external stylesheets, all CSS must be found in the document’s <head>.  WP AMP gives us a tool for hooking styles into the <head>, which we’ve already set up.  As a reminder, it will use our our templates/style.php file.

The contents of that file are pretty easy to understand.  Open up the default WP AMP style.php and you’ll see that it’s almost all just plain text, except for a few places where colors and a few other settings are pulled in to render the desired CSS styles.

Keep in mind that the total size of CSS on the page cannot exceed 50Kb.

Here is an example of how the PHP interacts with the CSS:

Add A Nav Menu

A Navigation Menu is one feature that is glaringly lacking from the default WP AMP template.  Naturally, its authors are unable to know if you have a nav menu in your theme, and even if they did, they don’t know what location label you’ll give it, so it’s understandable why they left it up to you to customize.

AMP has an Extension called “amp-sidebar.”  This is a block of content that is triggered by a click that slides in from the side of the page.  We’re going to use this for our menu.

Screen Shot 2016-07-21 at 12.58.52 PM

Example of a basic Navigation Menu using amp-sidebar.

First, following the example code below, add two functions to your amp.php:

jr3_amp_sidebar_component_scripts() tells WP AMP to load the amp-sidebar JS into the template’s <head>.  (Check to make sure you didn’t already add this if you added the component scripts earlier)

jr3_clean_nav_menu_items() is a helper function I wrote to make a barebones list of menu items.  It skips adding all of the unneeded wrappers and classes to the nav menu.

Below those functions are two blocks of HTML to add to your single.php (and other template files).  The first is the HTML that holds our primary nav menu.  The next is the actual button that will trigger the opening/closing of the amp-sidebar menu.

By default, featured images are not included in the WP AMP templates.  Here’s how you do that, taken almost directly from the WP AMP docs.

Social Share Buttons

Since social share buttons often require JS to function, AMP has added support for them via its amp-social-share Extension.  The code below can go directly into your template file.  Don’t forget to register the amp-social-share component script with WP AMP.

I’ve found that Facebook requires an App ID, so be sure to add yours into your code.  Naturally, you’ll need to add some PHP support for this to draw the Fb App ID from wherever you have it in your theme’s settings.

Bonus: Handling Shortcodes

As AMP has very specific rules about what markup is allowed, we need to be careful to only allow valid HTML to our templates.

Shortcodes are a way that unintended output can be slipped in to our content and render the page invalid.  One simple (but not preferable) way to prevent this is to remove shortcodes from the content altogether.

Unfortunately, this approach is pretty brutish.  You should really use another solution for this issue, as you may want to allow certain shortcodes, or even filter the content to replace the shortcode with custom formatting.

Here’s an example of how I modified a hypothetical shortcode called “podcast” to accommodate <amp-audio>.  You’ll note that I also include a helper function to grab the shortcode attributes that we need so we can add that data to our <amp-audio> tag.

Final Thoughts

AMP is going to be a big deal, and soon.  In my experience, clients are already asking us at XWP to integrate it into their WP sites.

If you want to stay ahead of the competition in the WP theme world, or offer your clients another valuable service, you definitely need to integrate this into your themes.

I hope that my experience in this speciality will help you on your way.

Happy coding!



Simple Custom CSS Turns Three!


This month, 0ur Simple Custom CSS WordPress Plugin turns 3 years old, and it has made the GoDaddy Top 100 Plugins of the week!

As you can imagine, I’m quite proud.  This plugin began a quick four-hour project to solve a development problem I was having.  Now, it’s used in over 300,000 active WP installs.  Wow!

Thanks to everyone who has commented in the support forums, both asking and answering questions.  Also, a huge thanks to those who have contributed by issuing pull requests in our GitHub repo with code improvements and translations.

It’s crazy to think that something I cooked up in my home office is now used by so many people in so many diverse places.

I love being part of the open source WordPress community, where our work benefits people all over the world, and with all of us working together to make the internet a better place to communicate and share ideas.

Featured Image via GoDaddy.

Practical Tips for your WordPress Job Application


I’ve been increasingly involved in hiring at my company, and I’ve learned a lot about the job hunt from being in the seat across the table, so to speak. I’d like to pass my experience and perspective on to you to help you get an interview.

I’ve come up with some tips to help you land a job, specifically in the development field, and even more specifically if your application comes my way. Most of these tips would apply to any job search, and I’ve also included some more information on what development employers are looking for.

These are all things I wish I would have known earlier in my career. I truly hope this helps you put your best foot forward with your prospective employer!

Perception is Everything

Perception is everything. It’s not fair, but it’s a psychological fact: employers get a “feel” about who you are based on your communication. And, for as hard as I try to overcome that bias, it’s just naturally going to happen. “You never get a second chance to make a first impression.”

Rock your Initial Email

Your initial contact email to an employer is critical. You must make a statement as quickly as possible, and this means attaching examples of your best work in that email; don’t just send a written message.

It’s easy for an employer to make assumptions about you based on that initial contact, and you want to give me access to as much information about you as you can provide to help with that first perception.

It goes without saying that you must ensure you’re using good grammar and spelling in your email. This speaks a lot to your professionalism and attention to detail.

Attach a resume, functional code sample, and links to your best work. Having quick access to these items will help me have an objective view of what type of developer you are.

Bonus points for links to WP community contributions, including core patches and your own plugins and themes.

ProTip: don’t use your KurtCocaine@SofaKingCool.com email address to send this.

Your Resume

Make this look sharp!

It’s impressive to have a great design. You can find some great help with this on GraphicRiver.

Include a cover letter with a bit about yourself and your personal philosophy about development and what you are doing to grow.

Avoid overly general and/or convoluted wording about your former responsibilities. It just looks like filler or complete BS to me.

Outline relevant work experience. It’s irrelevant to me if you were a cashier at Wal-Mart, so in my opinion, you can ethically leave that off. These minor facts don’t take points off with me (unless you used to work for Comcast), they just add more data to scan through. I only use relevant development work experience in my own personal resume.

In our field, a solid portfolio of work is much, much more important than degrees or awards. List those, to be sure, but be aware that your actual work experience and quality is much more important.

Code Sample

Attach a code sample in your initial email. Make sure this is functional code that I can install and test, not just a few code snippets. I know how easy it is to pull some fancy looking stuff off of StackOverflow, and you don’t want me to even have that thought in my mind when I’m looking at your work.

Do some advanced stuff in your code sample. For Front End folks, use CSS3 transitions and keyframes. I also like to see Object Oriented Javascript. On the Backend, I like to see WordPress-flavored Ajax, API interaction, and Object Oriented Programming.

Whether Front End or Back End, all of your work should adhere to WP Coding Standards, including details like proper spacing on all code, as well as docblocks.

Online Presence

It’s been my personal mission to find out everything I can about a prospect before writing a response email to either set up an initial interview with the developer or writing the dreaded (but kindly worded) rejection email.

Even more than what you say about yourself, I want to find out who you really are. Having a positive, teachable team player is even more important to me than dealing with a snobby but talented code-jockey.

I’ll be all over the internet to find out everything I can about you. I think I’m reasonable enough to know that all of your online interaction isn’t going to be “professional” or development-related, but I will be looking for insight into your personality.

Google Yourself

30 Rock Google YourselfWhen researching a prospect, the first place I go is Google — sometimes before even digging deeply into their code. Your online activity says a lot about your personality, and to me, who you are is more important than your skillset.

Take some time and check out what Google has to say about you. I’m not saying you should try to have Google wipe undesirable facts about you, but if you have an old personal site that would look bad to a potential employer, you might want to take it down, edit your SEO settings in your robots.txt, require authentication to view the site, or even use Google Webmasters to block certain pages of the site from being crawled.

ProTip: I usually start with a search on “John Smith Developer,” or “John Smith Kansas City.”

Focus on beefing up the sites that are the top results for your name. This means things like your personal site, WP profile, LinkedIn account, etc.

By the way, I understand if I find an ancient Blogger site that was barely used at all. Don’t sweat it; I have those myself.

Social Media

The next thing I do is stalk you on social media to gauge your personality and interests. You don’t have to post a lot about development, I just want to get a feel for you.

Start by maintaining a social media presence. If you don’t have one, it looks like you live under a rock, and that’s not going to work in a media-driven field.

Remember that prospective employers will read everything you post. You don’t always have to be dressed in a suit in your pictures, but be mindful that your overall personality will be revealed by your tweets and posts.

Facebook is a common place I search. I like being able to read about your daily life. If you have questionable activities you don’t want me to see, change your privacy settings; if there’s a bong on the table in the background of a pic, I’m going see that.😉

ProTip: Don’t let me find your Reddit username. We both know you don’t want me to see that.

Your Personal Site

Keep your site up to date. It doesn’t matter if it’s about your passion for N-scale model railroading. I just want to get to know you.

Remember that perception is everything to get that first interview. The design of your blog is a reflection of your work and attention to quality, even if you didn’t build it yourself. You get major bonus points if you did build it yourself. It doesn’t have to be fancy, but the code needs to be tight.

You don’t have to update your blog regularly; we all understand how hard it is to maintain a personal blog. However, if your posts are focused on your development, include some stuff about your passion for the work. Post helpful code snippets and your opinion about development tools and issues.

Also, it looks really good to host examples of your work, even if they’re not linked from the main blog. Full demo sites are great. They give you the power to make your own decisions about sweet design and technical features that you may not have on sites built for clients and picky designers.

If you’re not a designer, go and download a PSD or HTML template then build it out yourself. There’s no shame in that at all. Ultimately, I care more about your code than visual appeal, but once again, keep in mind that initial perceptions are important.


I love to see activity on your GitHub and/or Bitbucket accounts. This shows me that you’re developing your own personal projects, and that’s a big plus. These serve as code samples that you haven’t polished up before submission to an employer, so they reveal how you typically work.

Smarterer Score

There is debate about the reliability of a Smarterer score in relation to actual development skills, but it helps people like me get a feel for your knowledge of WordPress. Take the quiz on CodePoet and work to get your score over 700. I’ve known some incredible PHP/JS developers who I’ve been unable to hire simply because they don’t know the WP system. This score will give us both a quick glance at your proficiency.

Final Thoughts

Your work and online persona are an opportunity for you to shine before a prospective employer. I’ve included this “insider” information to help you make a great impression when you first reach out for a new position.

These are all things I wish I’d known several years ago, and I hope they will help you make a powerful first impression to those considering you as a new member of their team.

By the way, if you’re interested in working with me and my teammates on big projects with lots of fun challenges and opportunities to grow, hit us up at xwp.co. I’d love the chance for us to get to know each other!

OOP with WordPress – For the Total Newbie


Object-Oriented Programming (OOP) is a common method used to encapsulate code. Although it can be used for techniques much more advanced than we’ll discuss here, it can be used for basic plugins quite easily so you can learn its basics.

In this tutorial, we’ll create a short plugin that creates a Custom Post Type called “Books,” and an associated taxonomy called “Genres.” This is a fairly common operation in WordPress, and can certainly be created without using OOP, but since you’re probably already familiar with that process, it will serve as a good base for this tutorial.

Skip to the full code »

The primary “element” of OOP is the Class. For our purposes, it’s a wrapper that holds all of the internal functions, which in the context of OOP are called methods.

Creating a Simple Class

We start by creating our Class.

class JR3_Books {
     static function setup() {}
add_action( 'plugins_loaded', array( 'JR3_Books', 'setup' ) );

Our Class is “JR3_Books.” Each word in a Class’s name is capitalized, and underscores represent spaces.

Inside of it, we place a method that we’ll call setup(). You’ll note that you usually want to prefix your functions in WordPress to avoid conflicts, but since this is within our Class, it isn’t necessary.

You’ll note the word static before the method setup(). This is important for the way that we will be calling our methods in this tutorial, but the reason why isn’t important right now.

Firing the Class

Finally, we called the plugins_loaded action after the class. This is an important thing to note, as we’ll use a similar format within the Class.

Note that usually, an action looks like this:

add_action( 'plugins_loaded', 'setup' );

However, we have to let the add_action() know that setup() is located within our Class.

This is done by turning the second argument from a simple string into an array that includes the name of our Class, which gives us this:

add_action( 'plugins_loaded', array( 'JR3_Books', 'setup' ) );

Note: There are a lot of ways to instantiate a Class, and some are more appropriate than others. For the sake of simplicity and consistency in this tutorial, I’m taking the simple add_action() route

Adding A Method

Now, we add our method to register the post type. This will be done very similarly to how we commonly use register_post_type(), and we’ll use an action to fire this off in just a minute.

For now, this method goes within the Class, just like our setup() method.

static function register_books_cpt() {
     register_post_type( 'jr3_books', array(...) );

Note that I haven’t filled in the register_post_type() function completely here for the sake of clarity.

So, right now, our plugin doesn’t do anything. As I said above, we need to use an action to make this new method fire off. We do this by adding the appropriate action within our setup() method.

static function setup() {
     add_action( 'init', array( __CLASS__, 'register_books_cpt' ) );

Once again, you’ll note that we’re using an array as the second argument in the action. This time, however, we aren’t using the Class name, “JR3_Books.” Within a class, you use the Magic Constant __CLASS__. Also, the second value in the array is the name of our new method.

To translate this action into words, it tells the code to, on init, look inside of this Class for the method register_books_cpt.

In the code snippet below, you’ll see that I’ve also added a method for adding a custom Taxonomy (called, “Generes”), using the same technique.


What we’ve done here is we created a Class to hold our code. Inside of it, we added a setup() method to maintain the actions we’ll fire during our plugin. Then, to kick things off, we added the add_action( 'plugins_loaded' ... ) to tell WP to load our Class.

Naturally, this is a very high-level view of OOP. These can do extremely intricate and complex functions for you on your projects, and I hope that this will get you on your way to understanding how they work!

BONUS: The code below is a partial example of what we’ve covered. Here’s a fully-functional example this code that you can place in your wp-content/plugins directory to play around with.

Further Reading


Basic Example of this Tutorial

Please Change Your Genesis Favicon


I love the Genesis framework* for WordPress. It is an amazing tool for speeding up the development process, and I even use it on my personal site.

Its wide acceptance across the WordPress world is unfortunately highlighted by the proliferation of Genesis favicons on these sites.

The Genesis Favicon is a black square or circle with a white capital “G” in it. It is a dead giveaway that you’re running your site on Genesis.

If you’re developing custom sites for your clients, you probably don’t want that visible. Your client would probably prefer to have their own branding in their favicon.

The fix for this is pretty simple, thanks to the hooks that Genesis offers.

What is a Favicon?

A favicon is that little square icon that appears in your browser window (or tab). It’s actually not a typical image, but an .ico file type.

The black circle in this browser tab is an example of a Genesis favicon.

The black circle in this browser tab is an example of a Genesis favicon.

To create your own favicon, create a square logo image with your brand of any size larger than 16x16px (you can even use transparent .pngs). Then, go to a site like favicon-generator.org and convert it to an .ico.

Including Your Custom Favicon in a Genesis Child Theme

Typically, this file is named “favicon.ico,” but you can call it whatever you want. The name “favicon.ico” is used in my code sample, so you may have to adjust that as needed.

Add your favicon to your Genesis Child theme’s directory, and add the following code to your child theme’s functions.php.

Note: Browsers are pretty stingy about caching these favicons. This means that you’ll need to open your site in a private/incognito window to see the changes take effect. New visitors to your site won’t need to do this.

*Not an affiliate link

New WordPress Plugin: Send System Info


When providing support for WordPress do you waste time going back and forth with the client asking for information about their website? Information like versions of WordPress, PHP and MySQL, as well as configuration of each can be invaluable to diagnosing a problem quickly and accurately.

After some work with the team on the Stream Plugin, I realized the need for users to easily gather information about their site’s configuration. This idea gave birth to the Send System Info Plugin for WordPress.

This plugin not only displays the site information, it allows the user to send this data to you in three forms:

  1. A downloadable plain text document, handy for archiving for later comparison
  2. An email generated within the plugin
  3. A URL that allows secure remote viewing of this data

My favorite feature of this plugin is the remote viewing URL, which points to a plain text page of the site information. The cool thing is that this URL can be regenerated, wiping out access to those who have the previous URL.

This is especially handy for posting site information in support forums, where you have no contact email address with those providing support, like the WordPress.org Support Forums. This link can be posted to the forums, and when you are done getting the support you need, simply regenerate the URL and later visitors to the forum will have no access to your information. This is a much more secure method of getting help than simply writing your server information into the forum.

I’ve had some great help from Frankie Jarrett and Luke Carbis and Pippin Williamson on Send System Info. You can help out, too! I have a GitHub repo available at https://github.com/johnregan3/send-system-info, and contributions are always welcome. I want this plugin to be as useful as possible for the WordPress community.

I invite you to download Send System Info and give it a test run. I think you’ll be surprised at how much information is available, as well as it’s simplicity and how easy it is to use. Give it a shot!

Adding Support for Vertical Featured Images in WordPress Themes


Here’s a quick and easy way to add support for Vertical Featured images in your WordPress themes.

How it Works

Using a filter hook, we’re going to add a class to the Featured Image markup if the image’s height is greater than its width. Then, using CSS we’ll float it to the right. Pretty simple, huh?

The Script

In your functions.php file add:


This code floats the image to the right and adds some margin to separate the image from the post’s content. Be sure to include it in your CSS file.

.vertical-image {
	margin-bottom: 1em;
	margin-left: 2%;
	max-width: 33%;


Your Post title will need to be clear: none; if this happens:

Screen Shot 2014-01-02 at 2.13.46 PM

You may need to add overflow:hidden to your post’s CSS to prevent this from happening in case the post excerpt is too short:

Screen Shot 2014-01-02 at 1.59.06 PM

The Result

This is what it should look like if the Feature Image has a vertical (portrait) orientation:

Screen Shot 2014-01-02 at 1.53.14 PM


When researching this, I had a hard time finding resources on this topic, so I hope this helps! If you find this post helpful, be sure to pass it on, including a link to this post!