Those of us who are WordPress theme developers, are all too familiar with the wp_enqueue_script and wp_enqueue_style that are default WordPress functions for appending scripts and styles, respectively, to our themes.
However, the recent updates to WordPress enables developers to provide different Post Formats. According to the Codex:
Post Formats is a theme feature introduced with Version 3.1. A Post Format is a piece of meta information that can be used by a theme to customize its presentation of a post. The Post Formats feature provides a standardized list of formats that are available to all themes that support the feature.
This is perhaps an attempt to level with Tumblr which is build around this very concept. However, WordPress provides very little guidelines as to how to work with the different Post Formats. I suppose the core team is leaving the details to the large ecosystem of designers and developers to figure out what to do with this new feature.
The Basic Structure
Post Formats have opened a world of opportunities for designers and developers. We are no longer limited to the mundane blog posts that WordPress is so darn good at publishing.
For the purpose of this tutorial, let’s say we are supporting the gallery, audio and video Post Formats. This can be done with a quick snippet in the functions.php
add_theme_support( 'post-formats', array( 'gallery' , 'video' , 'audio' ) );
However, developers have been struggling to keep their implementation of Post Formats clean and bloat-free. The most common approach seems to be using if/else conditions within template files and providing the markup for each Post Format – all within a single document. This is, of course, very inefficient and can get very bloated very quickly.
I find the most efficient manner of integrating Post Formats is this code snippet in the index.php and single.php templates:
<?php if ( have_posts() ) :
while ( have_posts() ) : the_post();
get_template_part( 'content', get_post_format() );
endwhile;
endif; ?>
For each Post Format you support in your theme, there must be a separate template containing the markup. For instance, for the gallery format, the filename would be content-gallery.php and likewise for all the other formats you choose to support.
In case your theme does not have the appropriate template, it will fall back to the default content.php.
Functions.php
Firstly, we create a function within functions.php with the only parameter being Post Format:
function enqueue_post_format_resources($format) {
if( in_array($format, array('gallery')) ) {
wp_register_script('galleria', get_template_directory_uri() . '/js/galleria/galleria.js', false, false);
wp_register_script('galleriatheme', get_template_directory_uri() . '/js/galleria/classic/galleria.classic.js', false, false);
wp_register_style('galleriathemecss', get_template_directory_uri() . '/js/galleria/classic/galleria.classic.css', false, false);
wp_enqueue_style( 'galleriathemecss' );
} elseif( in_array($format, array('audio', 'video')) ) {
wp_register_script('mejs', get_template_directory_uri() . '/js/mejs/mediaelement-and-player.min.js', false, false);
wp_register_style( 'mejscss', get_template_directory_uri() . '/js/mejs/mediaelementplayer.min.css', false, false );
wp_enqueue_style( 'mejscss' );
} else {
return false;
}
}//end function
We are checking if the given format matches a certain criteria. Firstly, we check if it is a gallery – in which case, we will register and scripts and stylesheets of the fantastic Galleria javascript library.
Secondly, we check if the Post Format is either audio or video. In this case, we register the resources of MediaElement.js – which is an outstanding library for handling HTML5 Audio and Video in all browsers.
You have the liberty to add any library or polyfill as you see fit and set conditions for a particular Post Format.
One curious thing about the code above is that only the stylesheets are being enqueued, but not the scripts. This is because we are going to lazy-load the scripts within the theme using Modernizr (discussed below). However, this step is entirely optional. You can go ahead and use wp_enqueue_script for each of the registered scripts above. That will directly print the code in your theme’s wp_footer.
We will need a custom script that displays the enqueued script:
/*
* Display the enqueued scripts
* URL: http://jamesfishwick.com/2011/modernizr-and-jquery-and-wp_enqueue_script-oh-my/
*/
function registered_scripts( $handles = array() ) {
global $wp_scripts, $wp_styles;
foreach ( $wp_scripts->registered as $registered )
$script_urls[ $registered->handle ] = $registered->src;
foreach ( $wp_styles->registered as $registered )
$style_urls[ $registered->handle ] = $registered->src;
if ( empty( $handles ) ) {
$handles = array_merge( $wp_scripts->queue, $wp_styles->queue );
array_values( $handles );
}
$output = '';
foreach ( $handles as $handle ) {
if ( !empty( $script_urls[ $handle ] ) )
$output .= $script_urls[ $handle ] . ',';
if ( !empty( $style_urls[ $handle ] ) )
$output .= $style_urls[ $handle ] . ',';
}
$output = substr( $output, 0, -1 );
echo $output;
}// end function
I will allow the original author of this snippet James Fishwick explain the functionality of registered_script().
content-{format}.php
Now that we have set up a script that registers and enqueues scripts and styles based on the post format that is passed along as a variable, we can now include this snippet at the beginning of each content-{format}.php file:
<?php enqueue_post_format_resources( get_post_format() ); ?>
Hence, when the Post Format is video, the function will be called to enqueue all the necessary resources appropriate for this format – which is, in this example, the components of MediaElement.js.
Loading Registered Scripts with Modernizr
In functions.php, I only loaded the stylesheets using wp_enqueue_style but left out the javascript files. The purpose for this is that we are going to be using Modernizr for loading the script resources.
<script type="text/javascript">
Modernizr.load([
{
load: '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js',
complete: function () {
if ( !window.jQuery ) {
Modernizr.load('js/jquery-1.7.2.min.js');
}
}
}
<?php if( wp_script_is('galleria', 'registered') ) { ?>,{ load: '<?php registered_scripts( array('galleria') ); ?>' } <?php } ?>
<?php if( wp_script_is('galleriatheme', 'registered') ) { ?>,{ load: '<?php registered_scripts( array('galleriatheme') ); ?>' } <?php } ?>
<?php if( wp_script_is('mejs', 'registered') ) { ?>,{ load: '<?php registered_scripts( array('mejs') ); ?>' } <?php } ?>
,{ load: '<?php registered_scripts( array('behaviour') ); ?>' }
]);
</script>
Firstly, we make a query to the Google CDN for hosted version of jQuery. There is a fallback in case the CDN file fails to load. The fallback is self-hosted within the theme’s own directory structure.
Once it has been ensured that jQuery is loaded – by whichever means – we are going to load the resource files necessary for the Post Format.
We are using lesser-known wp_script_is function to check if a particular script is registered. The scripts for the audio and video Post Format are only registered when such a post is being rendered. If the script is registered, it definitely means that an audio/video post is currently being rendered – so we load the necessary script using Modernizer.load().
Limitations
The stylesheets loaded using wp_enqueue_style are, by default, added to the wp_footer, meaning that your stylesheets will end up at the bottom of your document. This is bad web design practice.
You could also load your CSS resources just like the Javascripts, but you will need to add CSS Prefix to your copy of Modernizr. WordPress happens to have a function wp_style_is which serves the purpose of checking whether a stylesheet is registered. Instead of enqueueing the stylesheet directly from functions.php, you can load them using Modernizr in the same manner as the scripts.
Conclusion
Post Formats are still uncharted territory for a lot of WordPress developers. I have demonstrated a method of keeping the code itself and the final markup as squeaky-clean it is supposed to be. Instead of loading all the resource libraries, only load them when they are needed – and do so in the most elegant fashion possible.
After all, code is poetry.
You are using a function registered_scripts() but you never say what it is or what it does.
Thank you for spotting that! The article has been updated.