Selectively Include Javascript Files

A recent client had a particular requirement to use the Lightbox library for displaying full-sized images within certain posts. While Lightbox is popular and produces an attractive result, because of its dependencies on Scriptaculous and Prototype, its a seriously heavyweight addition to any page the first time its loaded. The lightweight Thickbox alternative was designed in response to the size of these libraries, and is even considerably more flexible. However, Lightbox looks prettier.

The solution to minimise the overhead of scripts is to only load them when strictly required by the page content. Unfortunately WordPress makes that a challenging exercise. While a lot of theme designers like to include all the required javascripts with the files they ship (usually in a js directory) and then link to them in header.php, this is not the correct method. The correct procedure is to add scripts using wp enqueue script.

Wp_enqueue_script is handy because WordPress now comes pre-installed with most scripts you’ll commonly use. However, its a problem for the theme designer because, due to the way the script queueing system works, its not possible to use it anywhere within the theme – by the time the template loader starts loading the required template files, its too late to add scripts to the queue.

The most logical place to use wp_enqueue_script is in a plug-in, which usually means one must be written everytime you need specific javascript included on the page. Unfortunately, the system doesn’t allow selective queueing by page type or content – everything queued gets output in the header.

Selective use of wp_enqueue_script

There are two choices for testing the page type and/or page content prior to the template getting loaded: the template_redirect and get_header events. Both work.

Here’s an example of prototype only being loaded for single post pages:

function insert_prototype() {
  if (is_single()) wp_enqueue_script('prototype');
}
add_action('template_redirect', 'insert_prototype' );

For the Lightbox problem, I only wanted to include the scripts if a rel=”lightbox” reference was actually within the post, since it was being used infrequently. All that was required was a simple test of the content; ie:
if ( is_single() && (strpos($post->post_content, 'rel="lightbox') > 1)) .. etc
(Note, the test looks for ‘rel=”lightbox’ to allow for the rel=”lightbox[group]” format).

There’s a secondary problem with Lightbox: it uses a custom CSS file unless you copy its contents into your style.css. Even though the WordPress developers allowed for stylesheets to be associated with their pre-registered scripts, they didn’t extend that option to the rest of us.

The answer is to use a global variable which gets set when the script is enqueued. Hook another function to the wp_head event which occurs while the header is being output and then echo the stylesheet link if the global variable is set.

Here is the full code to insert the Lightbox scripts and stylesheet, if required, on a single post or page, with an option to include it on every page.

<?php
/*

Plugin Name: Lightbox Inserter
Version: 1.0
Author URI: http://www.mikoder.com.au/
Description:  Installs the Lightbox JS library on a per-needs basis
Author: Michael Little, Mikoder

This plug-in will cause the lightbox JS library to be loaded when the
current (single) post or page contains a lightbox reference.
*/

$needlightbox = false;  //=true to install lightbox on every page regardless
$lightboxpath = '';

function lb_insertlightbox() {
  global $post, $needlightbox, $lightboxpath;
  $needlightbox = ($needlightbox || ((is_single() || is_page()) &&
 (strpos($post->post_content, 'rel="lightbox') > 1)));
  if ($needlightbox) {
    $lightboxpath = get_bloginfo('wpurl').'/'.PLUGINDIR.'/lightbox/';
    wp_enqueue_script('prototype');
    wp_enqueue_script('scriptaculous-effects');
    wp_enqueue_script('scriptaculous-builder');
    wp_enqueue_script('lightbox', $lightboxpath.'lightbox.js');
  }
}
add_action('get_header', 'lb_insertlightbox' );

function lb_insertlightboxcss() {
  global $needlightbox, $lightboxpath;
  if ($needlightbox)
   echo '<link rel="stylesheet" href="'.$lightboxpath.'lightbox.css" type="text/css"
   media="screen" />';
}
add_action('wp_head', 'lb_insertlightboxcss' );
?>

To use this code, save it in a file (I used “lbinsert.php”), create a “lightbox” directory under your plugins directory, then copy this file, lightbox.js and lightbox.css and its navigation images (prev, next) into it. Note that lightbox.js assumes the close and loading gifs are located in the images subdirectory under the root. Then activate the plugin within WordPress.

This code assumes you are using a current version of WordPress (tested on 2.8) that comes pre-installed with prototype and scriptaculous. Check wp-includes/js to ensure you have them.

You can see the effect of this plug-in by looking at the page source – all js files other than lightbox.js are WordPress includes. Here’s an example of the Lightbox effect

Notes: in lb_insertlightboxcss(), the echo statement should be all one line, and end with a newline added, ie .”\n”

Download lightbox.zip

This entry was posted in Plug-in, Wordpress and tagged , , .

One Response to Selectively Include Javascript Files

  1. Melvin Tasch says:

    Hello, I found this blog post while searching for help with JavaScript. I have recently changed browsers from Safari to IE. After the change I seem to have a problem with loading JavaScript. Every time I browse page that needs Javascript, my browser does not load and I get a “runtime error javascript.JSException: Unknown name”. I cannot seem to find out how to fix the problem. Any help is greatly appreciated! Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>