An asset and template management module.

Spex 0.9.9

Warning: Starting with 0.9.9 Spex no longer requires AIOM+, but AIOM+ is required for .less support.

About Spex

Spex is an asset and template management module for the ProcessWire CMS/CMF.

This library was born out of a love of ProcessWire and the yucky feeling the use of a and left in my mouth. Spex uses jQuery and the AIOM+ Module.


The usual methods apply.

  • AIOM+ is required by Spex, so install it first.
  • Install the Spex Module

File Structure

Spex uses a three-level template inheritance model similar to how Symfony and Twig work by default. The first level is your regular ProcessWire template, the output from that is decorated with a "layout template", and the output from that is decorated with the base layout template which handles the head of your html document and more. You can find some boilerplate code in the example-site directory.

Below is the expected directory structure in a ProcessWire project using Spex:

  • layouts (directory)
    • _base.php
    • one-column.php (an example)
    • ...
  • partials (directory)
    • slider.php (an example)
    • ...
  • _init.php
  • basic-page.php (an example)
  • ...


This file is responsible for outputting the html, head, body, link (css) and script (js) tags.

This file will have a slot content that has the output from the layout.

layouts/one-column.php, layouts/two-column.php, etc...

Any file in the layouts directory that is not _base.php is considered a layout. If your site has one column and two column layout you will want to create one-column.php and two-column.php in your layouts directory.

This file will have a slot content available that has the output from your template (aka page render).


This file is run before the page render, this is the place to set template variables, set a default layout, and add global css, less and javascript.



The template management of Spex means setting a variable in your template doesn't mean it will be available globally. Rather than setting global variables use this function to make a variable available in templates:

$spex->addTemplateVar('homepage', $pages->get('/'));

If you want a variable to be available on every page then use addTemplateVar in _init.


If you have some JavaScript in your template, you'll want to wrap it in a docReady() like below.

<?php $spex->docReady() ?>
<?php $spex->docReady() ?>

The JavaScript will be wrapped in a $(document).ready(function(){...}); and found just before the &lt;/body&gt; tag.

docReady can also take a string parameter if you want to just pass it some javascript.

docReady('console.log("hey there!")');


To set a layout, call setLayout like the below:


That would result in Spex using the layout found at templates/layouts/one-column.php being used.

Should you want to disable the layout for an AJAX request or something along those lines, do so by calling $spex->setLayout(false);.


Partials contain reusable fragments of html like a sidebar or toolbar. The convention for partial files is that they are located in a subdirectory of templates called 'partials', i.e. templates/partials/sidebar.php. To call the partial sidebar.php you write the below:


You can also pass an associative array to partial() to make additional variables available in the context of the partial, i.e.:

$spex->partial('sidebar', array('root' => $pages->find('/xyz/')));

Would make a variable $root available in sidebar.php.

Partials can also be cached which might be useful if they pull content from an RSS feed or something like that.

$spex->partial('rssFeed', array('url' => '...'), 3600);

The above would cache the rssFeed for 3600 seconds. The caching is based on the name of the partial unless you pass a fourth parameter of true which would base the caching on the partial name and the URI of the current request.

$spex->partial('rssFeed', array('url' => '...'), 3600, true);

You can also specify a custom cache key like the below:

$spex->partial('rssFeed', array('url' => '...'), 3600, $user->id);

If caching a partial, Spex will keep track of assets added with addStyle(), addScript(), addImage(), lateLoad() and docReady(), and duplicate those calls if necessary.

slot / hasSlot

Slots are a way to store a string or value to be used later, perhaps to set a sidebar content or to indicate that a login button should not be shown.

$spex->slot('sidebar_content', '<p>Sidebar</p>')

To echo the contents of a slot:

echo $spex->slot('sidebar_content')

You can check for the existance of a slot with hasSlot:

if ($spex->hasSlot('sidebar_content'))

There is also a variable $slot available should you prefer to use it directly.

echo empty($slot['sidebar_content']) ? '' : $slot['sidebar_content'];


You can use the captureSlot helper to capture some output, so you don't have to build a string and pass it to slot().

$spex->captureSlot(); // Starts the capture ?>


<?php $spex->captureSlot('sidebar_content'); // Finishes the capture


This helper is used to preload an image, it also happens to return whatever is passed to it.



<div data-background="<?php echo $spex->addImage('big-background.png') ?>"></div>


This draws out any JavaScript captured by docReady(), and is usually only found in the _base layout.



This captures html and sets it up to be the last thing loaded on the page. You'd want to use this for third party code like social sharing code or ads.

lateLoad(); ?>

    <div class="addthis_toolbox addthis_default_style"></div>
    <script type="text/javascript" src="//"></script>

<?php lateLoad();

addBreadcrumb / getBreadcrumbs

These helpers are a convenience layer on top of the Breadcrumb/Breadcrumbs class available in ProcessWire.

$spex->addBreadcrumb('url/goes/here', 'The Title Goes Here');

foreach ($spex->getBreadcrumbs() as $breadcrumb) 
    echo sprintf('<a href="%s">%s</a>', $breadcrumb->url, $breadcrumb->title);


Use of this helper is not required, you can work directly with AIOM+ if you want.

This function adds a JavaScript file to the page. Spex assumes you want your script tags just before the &lt;/body&gt; tag. You can add javascript files one at a time like the example code below.


Or a bunch at once:

$spex->addScript(array('scripts/main.js', 'scripts/another.js'));

If you want to add scripts that are not on the same server as your PW site it's best to hardcode them in your _base template.


Use of this helper is not required, you can work directly with AIOM+ if you want.

Spex can handle .less or .css files. To add one stylesheet to the page at a time, use the below:


Or add a bunch at once:

$spex->addStyle(array('styles/main.less', 'styles/home.less'));

Procedural Helpers

Most of the class methods of the Spex class have procedural equivalents. To enable the procedural helpers, in your templates/_init.php set:


All the helper functions have the same signature as their equivalents documented above, i.e:


is equivalent to the below:


The list of procedural helpers is below:

  • addScript
  • docReady
  • addStyle
  • addTemplateVar
  • partial
  • setLayout
  • includeDocReady
  • addImage
  • slot
  • hasSlot
  • captureSlot
  • lateLoad
  • addBreadcrumb
  • getBreadcrumbs

Install and use modules at your own risk. Always have a site and database backup before installing new modules.

Latest news

  • ProcessWire Weekly #532
    In the 532nd issue of ProcessWire Weekly we'll cover the latest core updates, check out a couple of brand-new third party modules, and more. Read on! / 20 July 2024
  • Page List Custom Children module
    This simple module gives you the ability to customize the parent/child relationship as it appears in the admin page list, enabling child pages to appear under more than one parent.
    Blog / 28 June 2024
  • Subscribe to weekly ProcessWire news

“The end client and designer love the ease at which they can update the website. Training beyond how to log in wasn’t even necessary since ProcessWire’s default interface is straightforward.” —Jonathan Lahijani