• About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
  • About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
February 28, 2012

Using jQuery PJAX in Your WordPress Themes

Posted by Christopher Davis

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.

Detecting PJAX Requsts

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


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

Hijacking Template Includes

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.


<?php
add_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.

Creating Template Files

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.

Changing Elements Outside the Main Div

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!

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

ajaxjquerypjaxwordpress
Previous
Next

Latest White Papers

  • Shifting Plans for 2020 & Beyond
  • Game On: How Brands Can Log Into A Diverse Multi-Billion Dollar Industry
  • What CCPA Means For Brands
  • How Google is Improving Consumer Data Privacy
  • Ways to Prepare for the Cookieless Future
  • See all White Papers

Featured Posts

  • Ad Age Names PMG #1 Best Place to Work in 2021
  • MediaPost Names PMG Independent Agency of the Year
  • PMG Client Portfolio Trends During Amazon Prime Day 2020
  • A Closer Look at the Congressional Big Tech Market Power Report
  • What to Know About Reddit

Categories

  • Consumer Insights
  • Content
  • Creative Design
  • Data Analytics
  • Development
  • Digital TV & Video
  • Ecommerce
  • Industry News
  • Local
  • Mobile
  • Paid Search
  • PMG Culture
  • Programmatic & Display
  • SEO
  • Social Media
  • Structured Data
Fort Worth

2845 West 7th Street
Fort Worth, TX 76107

Dallas

3102 Oak Lawn Avenue
Suite 650
Dallas, TX 75219

Austin

823 Congress Avenue
Suite 800
Austin, TX 78701

London

33 Broadwick Street
London
W1F 0DQ

New York

120 East 23rd Street
New York, NY 10010

Get in touch

(817) 420 9970
info@pmg.com

Subscribe to the PMG Newsletter
© 2021 PMG Worldwide, LLC, All Rights Reserved
  • Contact
  • Privacy Policy
 Tweet
 Share
 Tweet
 Share
 Tweet
 Share
 LinkedIn
We and our partners use cookies to personalize content, analyze traffic, and deliver ads. By using our website, you agree to the use of cookies as described in our Cookie Policy.