This website uses cookies to ensure you get the best possible experience. See our Cookies Policy.

PMG Digital Made for Humans

Using jQuery PJAX in Your WordPress Themes

5 MINUTE READ | February 28, 2012

Using jQuery PJAX in Your WordPress Themes

PJAX is a jQuery extension that combines AJAX requests to HTML5 pushState. What this means is an AJAX website with a working back button. Think Twitter without ugly hash bangs (#!) in the URL**.

What AJAX, and by extension PJAX, does is allow for partial page reloads. The result is a much faster page load time – the browser doesn’t have to re-render the entire page. You can use PJAX out of the box in your WordPress theme, just specify which container is to be extracted from a full page request and the PJAX library extracts it and pops it into the page where you want it.

We’re going to go a bit beyond that here. Instead, we’ll hijack WordPress’ template system and include partial pages instead of complete pages – less stuff to send on every page load.

For this example, we’re going to create a Twenty Eleven Child Theme.

Using PJAX is very easy, and you can take a look at the docs to learn more. The JavaScript side of this tutorial is pretty unexciting.

jQuery(document).ready(function() {

jQuery('a').pjax('#main');

jQuery('#main').bind('pjax:end', function(){

if(typeof(pjaxy_page_info) != 'undefined') {

jQuery('body').attr('class', pjaxy_page_info.body_class);

jQuery('head title').html(pjaxy_page_info.page_title);

if(pjaxy_page_info.header_img) {

jQuery('header#branding > a img').attr('src', pjaxy_page_info.header_img)

.attr('width', pjaxy_page_info.header_width)

.attr('height', pjaxy_page_info.header_height);

}

}

jQuery('li.menu-item').removeClass('current-menu-item');

});

});

The first line inside our document ready call turns on the PJAX functionality. The rest of it is to replace various page elements outside the #main div with updated versions. We’ll need to update the <title> to let folks know they’ve moved to a new page. We also need to update the body class to make sure everything renders properly. I’ll explay the pjaxy_page_info JS object and how it gets generated a bit later on.

The PJAX library adds a X-PJAX header, which can use to detect whether a request was made via PJAX.

<?phpfunction is_pjax(){if( isset( $_SERVER['HTTP_X_PJAX'] ) && strtolower( $_SERVER['HTTP_X_PJAX'] ) == 'true' ) {return true;}return false;}

Next up, if we detect a PJAX request we want to ditch the normal templates and include a stripped down version. To do this we can hook into the various {$template_type}_template filters. If it’s the home page, for instance, the filter is home_template. Singular page templates are single_template.

Here’s an example.

<?phpadd_filter( 'single_template', 'pjaxy_singular_template' );function pjaxy_singular_template( $template ){if( is_pjax() ) {$post = get_queried_object();$temps = array( "single-{$post->post_type}.php" );$temps[] = 'single.php';if( $t = pjaxy_find_template( $temps ) ) {$template = $t;}}return $template;}

This is a blantant rip off of the WP core 

get_single_template
. As are the rest of the template filter functions in this file.

The difference is the pjaxy_locate_template function. Which is going to look for the correct theme file in the current child theme. If it doesn’t file one, it will fall back to the parent theme. We’re looking for our templates inside the pjax-templates folder of the child or parent theme.

<?php

function pjaxy_find_template( $templates )

{

$located = '';

foreach( (array) $templates as $t ) {

if( ! $t ) {

continue;

} elseif( file_exists( STYLESHEETPATH . '/pjax-templates/' . $t ) ) {

$located = STYLESHEETPATH . '/pjax-templates/' . $t;

break;

} elseif( file_exists( TEMPLATEPATH . '/pjax-templates/' . $t ) ) {

$located = TEMPLATEPATH . '/pjax-templates/' . $t;

break;

}

}

return $located;

}

This is, of course, ripped off from the WP core’s locate_template function.

PJAX templates will be a bit different than your normal WordPress template files. Basically what I did for the pjaxy theme was copy everything from the corresponding normal template files except the calls to get_header and the like. We don’t need all that extra stuff – just the content that will get plugged into the #main div.

You can view some examples on Github.

When a PJAX call completes it fires off the pjax:end event. You can use jQuery to listen in for this event (via jQuery('#main').bind('pjax:end')). With that done, it’s a simple matter of a bit of JavaScript to replace body classes and such.

At the top of every template file is a call to the function get_pjaxy_page_info which is just a wrapper around a require_once statement.

<?php

function get_pjaxy_page_info()

{

require_once( PJAXY_PATH . 'inc/page-info.php' );

}

If you want to use any of the above code in your theme, the page-info.php file will probably get changed. The only thing we’re doing here is creating a JavaScript object with the stuff we need to replace outside the #main div.

<?php

$header_src = get_header_image();

$header_width = HEADER_IMAGE_WIDTH;

$header_height = HEADER_IMAGE_HEIGHT;

if( is_singular() ) {

$post = get_queried_object();

if( $thumb_id = get_post_thumbnail_id( $post->ID ) ) {

$header_image = wp_get_attachment_image_src( $thumb_id, array( HEADER_IMAGE_WIDTH, HEADER_IMAGE_WIDTH ) );

if( $header_image[1] >= HEADER_IMAGE_WIDTH ) {

$header_src = $header_image[0];

$header_width = $header_image[1];

$header_height = $header_image[2];

}

}

}

?>

<script type="text/javascript">

var pjaxy_page_info = {

body_class: "<?php echo esc_js( join( ' ', get_body_class( 'pjax-loaded' ) ) ); ?>",

page_title: "<?php echo esc_js( wp_title( '', false ) ); ?>",

header_img: "<?php echo esc_js( $header_src ); ?>",

header_height: "<?php echo esc_js( $header_height ); ?>",

header_width: "<?php echo esc_js( $header_width ); ?>"

}

</script>

What all this boils down to is figuring out to change how WordPress acts when a PJAX request is received. It’s a proof of concept, but it certainly speeds up page load times on the client side – take a look at the demo. Worth a look if you’re building a new theme!

Insights meet inbox

Sign up for weekly articles & resources.

** Twitter is moving away from this at the time of writing.


Posted by Christopher Davis

Related Content

thumbnail image

Get Informed

SEO For ReactJS Websites

4 MINUTES READ | April 11, 2018

Get Inspired

How Progressive Web Apps are Changing the Mobile Web Experience

5 MINUTES READ | August 28, 2017

Get Informed

A New Strategy for Testing Google AMP

3 MINUTES READ | July 13, 2017

thumbnail image

Get Informed

Optimizing for Amazon Echo Search

4 MINUTES READ | August 8, 2016

Get Informed

Not a Publisher? AMP Pages for the Rest of Us

3 MINUTES READ | March 3, 2016

Get Informed

How SEO's Can Use Python

5 MINUTES READ | October 24, 2011

thumbnail image

Get Informed

SEO Auto Linker

2 MINUTES READ | August 23, 2011

thumbnail image

Get Informed

Crawl Rate Tracker & Multisite WordPress Installs

2 MINUTES READ | July 26, 2011

All POST