Spiria logo.

ProcessWire on Trial

February 20, 2017.

Our impressions of an actual development experience with the brilliant ProcessWire CMS.

Some months ago, we had an opportunity to work with the ProcessWire CMS, on which I had already published a preliminary analysis. As I had used this platform on three occasions to develop personal sites, I was thrilled to finally be able to use it for a professional project.

The Project

The Zone de ski de l’Estrie is a not-for-profit organization “whose mission is to promote competitive downhill skiing […] and to foster the development of elite skiers from the region. Zone promotes the interests of its member clubs (Bromont, Orford, Owl’s Head, Sutton) and of its regional elite team on the provincial stage (Ski Quebec Alpin) and national stage (Alpine Canada Alpin).”

Zone’s Web site was outdated and its prime function, which was to post the calendar of events and race results, was no longer as user-friendly as it should be. The site managers were reduced to posting PDF files which appeared in random order and didn’t download well onto mobile devices.

Our task was to present this information as interestingly as possible, while promoting the regional elite team and facilitating the posting and management of race data.

Requirements and Results

  • Documentation
    Posting and managing numerous documents (rules, race notices, official results).
  • Photo albums
    Allowing selected users to quickly create photo albums of the various elite team events.
  • Race calendars and posting of results
    Quickly posting calendars with the fewest clicks possible. There are six age-based skier categories, familiar to the skiing set: U8, U10, U12, U14, U16, U18. Some parents have several children skiing in different categories. Zone wanted parents to be able to quickly access information for each of their children without having to plod through multiple sections. Calendars had to display all information on any given race, including notices and results, even though each race category has its own point system for overall ranking.
  • Overall ranking
    After importing race results, the site had to automatically update and post new rankings.
  • Autonomy
    Zone wanted to be able to manage its own Web site without having to constantly come back to us to change background images, add pages, photo albums, etc.

Why Choose ProcessWire?

Nowadays, Web site users expect to enjoy the same functions that major social media Web sites provide. Everything must be easy to do. As mentioned in my previous article, ProcessWire fit the bill on all fronts, including programming, integration and administration.

A CMS with a Short Learning Curve

Designers need have no knowledge of ProcessWire whatsoever. We were able to give the designer free rein to create the interface of Zone’s dreams. The only constraints were those inherent to the posting of a Web page. The rest was up to them, with only their budget to set the limit!

Once the design was approved, we began programming the Import module and integrating the Web site.

The team first had to get up to speed on ProcessWire. Our programmer, a Drupal guy, quickly familiarized himself with the API, which fits on one page. He was excited by the cohesiveness and robustness of the solution. FYI, ProcessWire is built in PHP and its API is jQuery-inspired.

As for integration, ProcessWire’s philosophy is to not be beholden to any template engine. ProcessWire does not inject its own HTML code in Web pages; it’s up to the developer to use what he likes. But first, here is a quick primer on ProcessWire.

Site Structure

The structure of Web site files is minimal in ProcessWire. The wire folder is reserved for the CMS, and it’s the only folder that is replaced during updates. The rest of the code, i.e. our own code, is found in the site folder. 

Within the site folder, the assets sub-folder holds any downloaded items (images, for example) and anything that is generated by ProcessWire compilations (the cache, for example). It could also hold our scripts and CSS files. As mentioned above, ProcessWire doesn’t meddle with our work methodology, as long as we work in the site folder and the config.php file calls the paths.

The modules folder is aptly named. This is where the programmer places the results import module and the general tools module. 

HTML integration takes place in the templates folder. There is just one template folder. Like most CMSs, ProcessWire uses one area for administrators and another for visitors. You can create an Administration area, but it will be placed outside of templates, in a different folder.

As for integration, we wanted to follow the MVC model, with separate data control and administration functions. To do this, we installed the Template Engine Factory module, which allowed us to choose between Smarty, Jade and Twig or keep the ProcessWire template engine. We went for Twig. Template Engine Factory expects to find the controllers and views folders under templates.

In theory, ProcessWire doesn’t require this separation, especially since the CMS only needs template or model files as necessary. Page templates, which contain x number of fields, can exist without being displayed.

ProcessWire is all about pages. Unlike other CMSs, ProcessWire doesn’t differentiate between classification, a displayed page or a variable. The site map is made up of pages associated with templates. These pages can be hidden from users in the parameters section, and used for programming and classification purposes. Need a list of race locations (mountains)? Just create a section, hidden or not, and create child pages under this section. Then, using a page field, list these pages elsewhere as a selection. This is like the node reference field in Drupal, except that tags and classifications are treated the same way in ProcessWire, since they are in fact pages.

The root page “Lieux de Course” (“Race locations”) has child pages that populate a selection list on other pages.

The beauty of it is that there is no reason you can’t create a display of these race locations. These pages can have any number of fields. These same race locations can be used to create a list as well as new pages describing these locations.

Pages Structured as a Relational Database

You can organize a set of pages as a relational database, with the CMS’s mission being to provide the tools to handle this data. Then, you can enhance these tools with control files. Each page has a template, which in turn contains fields. You can structure your site in such a way as to restrict the use of certain templates for specific parts of the site. For example, the photo albums section can only contain album-type pages. This hierarchy means that administrators can easily link pages to data, while users can’t confuse things when creating a photo album. Other parts of the site can be more flexible, for example by affording a choice of templates for creating the various parts of the site. But this flexibility will depend on the logic underpinning each installation. Once again, ProcessWire provides the tools to set up the pages, while designers organize the site as they see fit.

Example of a page template and related fields.


Example of mandatory links. The album_landing template can only contain album_page-type templates, automatically organized by descending order of the date_album field.

Since the whole point of the project was to import race results, the site was structured according to the following logic: if a skier doesn’t already have a page in the CMS, create a page under the Skiers parent page; then, post the race result under the Results parent page. This results page has a field linking the result to the appropriate skier. The table also has other, similar fields linking the page to other pages such as race, day of race, clubs, etc.

This way, you get pages that are both stand-alone and interlinked. They can be called up and displayed at any point in the code, or searched by code or by administration interface, then displayed on any given page.

Our site has the following race page structure:

  • Season (season_landing template)
    • Season (season template) => displays overall ranking
      • Race calendar (calendar template) => displays the calendar and other
      • Race days (day_race template)
        • Races (race template)
  • Skiers (skiers_landing template)
    • Skier (skier template) (information on Skier)
  • Results (results_landing template)
    • Skier results (result template)
  • Variables (invisible template)
    • Race locations (location template)

The pages in bold are the only ones to actually display data. Therefore, the calendar.php file is the control file for the calendar template and the page template engine is provided by calendar.html.Twig.

Each page is based on a template. Pages can be referenced elsewhere, on another page, by a reference field. Drupal programmers will note the similarity to the reference node module.

Since invisible pages are still pages, we can decide to display them later, for example for each skier. All you need to do is add a skier.php control page and a skier.html.Twig template file. ProcessWire will automatically recognize the new display.

As stated earlier, we used Twig, but could have used any other template engine. In fact, ProcessWire will soon be offering a regions-based approach similar to the blocks approach used in Twig and other tools.

Streamlined Code and Template Engine

Despite the apparent complexity of the process — and data will always be complex to organize, regardless of the tool used — the result is compact, concise files. This is made possible thanks to the efficiency of the API. My favorite example is the following query to modify the U16 elite skier list, where “U16” is the $category variable:

$skiers = $pages->find('template=skier, categorie_elite=1, team={$category}, sort=last_name');

Notice that nowhere is it stated that category_elite and team are fields. Since you can’t have two different fields with the same name, ProcessWire knows what does what.

The equivalent code in Drupal would look like this:

$query = new EntityFieldQuery();

$query->entityCondition('entity_type', 'node')

  ->entityCondition('bundle', 'skier')

  ->fieldCondition('field_categorie_skier', 'tid', $node->field_skieur[LANGUAGE][0]['tid'], '=')

  ->fieldCondition('field_equipe', 'tid', $node->field_equipe[LANGUAGE][0]['tid'], '=');

  ->fieldOrderBy('field_date_album', 'value', 'DESC');

$result = $query->execute();

$empty = empty($result['node']);

if (!$empty) {

  $pages = $result['node'];

    foreach ($pages as $page) {

    $ski = node_load($page->nid);


But let’s get back to ProcessWire. The result is an array of pages containing information about each page: no need to load pages to extract page data.

The result, queried in the control page of the U16 elite team, allows us to code the rest in Twig. The skiers variable contains all the required information:



 {% for skier in skiers %}


  • {{skier.firstname}} {{skier.last_name}}


     {% endfor %}



The controler part allows you to change the information and to assign it to a personalized variable. Just call up the $view object and add the change.

// set template variables

      $view->set('extra', $calendar['extra']);

      $view->set('season', $calendar['season']);

      $view->set('months', $calendar['months']);

      $view->set('races', $calendar[‘races']);

The extra, season, months, and races variables will now be recognized by Twig.



 {% for month_key, month in months %}


 {% endfor %}




Since ProcessWire was developed in the PHP programming language, you’d expect to be able to use tools like xDebug. In theory, it is indeed possible, but in practice, we had some trouble in phpStorm. When the breakpoints were respected, they provided little or no valid data, and ProcessWire objects seemed to disappear when the program was interrupted. We didn’t look into the problem any further, but it seems we’re not the only ones to have experienced it. Happily, there is a Tracy adaptation that makes things a whole lot easier.

The Tracy development bar

The Backend

The best programming would be worthless without a user-friendly backend interface. Once again, ProcessWire makes users happy. See my previous article for further details.

To that, I would add that the administrator can easily grasp the structure just by looking at the page tree, which is the first thing you see when logging in as an administrator. The tree shows both visible and structural pages. And since we work under the Agile philosophy, our client was able to follow the various stages of the site’s construction and validate our choices as we went along. Further, we provided the client with a brief overview of our procedures, explained in plain language, right in the site.

We took special care with the import procedure. Thanks to the tools provided by ProcessWire, we were able to develop a drag-and-drop procedure for importing files. Each time a file is dropped, a validation script ensures that its name respects established protocols. The file name provides information to direct the import script; it is based on various keywords about the races, so that the administrator has no trouble naming files properly.
decorative decorative decorative

The page tree can also adjust itself to each type of user. For example, users responsible just for the photo albums only see the photo pages.

Addition of Paid Modules

ProcessWire is a free, open-source system; however, its developers also offer paid, but very reasonably-priced, solutions. We bought two paid modules. The first, ListerPro (US $49), allows the complex posting of any type of data, making searches that much easier. You can set default ListerPro filters, and allow the administrator to change the filters.

A ListerPro result. Fields at the top of the page are 100% configurable.

The second module we bought is ProCache (US $49). ProCache converts site pages to static pages, making the site very reactive.

While working on a personal site, I’ve also used the FormBuilder module (guess the price!). It was pretty powerful!

Other Pro modules have been developed over the last year. We are hoping to try them out, especially the profiling module, which maximizes performance, and another module that greatly extends field capacity.

In Conclusion

We experienced very few problems using ProcessWire. Any CMS will have its flaws, but the quality of the framework can be gauged by the support given by its developer community. ProcessWire is no exception, and reaction time to our questions was always very short.

The Zone de ski de l’Estrie site seemed easy to develop at first glance. However, the complexity of the rules underpinning the way points were tallied, and the challenge of presenting the results in a logical, user-friendly manner, did give us some headaches, and we were grateful to not have to fight a rigid or heavy CMS over the bargain.

Next step: using ProcessWire on a larger site. The on-line demonstrator leads us to believe that it’s up to the task.

The CMS developer, Ryan Cramer, is a chatty fellow, and provides weekly updates on his progress. None of his solutions ever stray from the elegance which is now ProcessWire’s distinguishing feature. Very reassuring for developers!

ProcessWire is a very professional, tidy CMS, supported by ingenious developers. The solution’s ease of use takes nothing away from its power, quite the opposite! Though the number of contributor modules is limited, this did not hinder us in our development; in fact, we believe that it is wiser to code yourself than to try to deconstruct modules designed to fix any and all problems, many of which are irrelevant to your project.

The verdict: we would do it again!