A few weeks ago I stumbled upon an A List Apart article titled “Managing Your Content Management System”. It gives recommendations on how to limit and tailor the users’ freedom in a Content Management System (CMS) back-end with the aim of making it as easy as possible to use.
Reading these recommendations and comparing them with the technical possibilities of the major players in the current CMS landscape, I see many limitations. Most of these CMSs simply don’t have these kinds of capabilities and can’t provide the level of options to ideally customize a back-end user interface. But working with ProcessWire for a few years now, I think I have found the sanctuary for developers and users who want exactly that.
ProcessWire is an up-and-coming, free, open source PHP CMS and Content Management Framework (CMF). At its heart it’s based on a few simple concepts and it provides tools that are super easy-to-use and extremely powerful at the same time. In this overview article I want to introduce you to some of these tools and concepts. Here are four reasons to choose ProcessWire as your next CMS.
1. It’s Based Upon Three Simple Core Concepts: Pages, Fields, and Templates
The input and output of data is based upon just three core concepts, and nothing else. This means that once you understand these concepts you basically understand everything about ProcessWire and the philosophy behind it. Pretty cool, right? So, let me introduce you to pages, fields and templates.
Pages
On the starting page of your ProcessWire installation you see a single, hierarchical page tree:
The links you see in the tree are called pages. Pages in the back-end usually reflect the page seen in the front-end. For example, the “About” page in the screenshot is accessible in the front-end by opening up your-domain.com/about/
.
But pages don’t have to have a counterpart on the front-end. They can also simply exist in the back-end and serve as data containers for other pages. Let the sentence you just read sink in: The concept of pages only available in the back-end is pretty powerful because it opens up endless possibilities in how to structure your website and interact with inputted data.
You can—and should—use pages for almost everything. For example, you can have a hidden settings page, where you save things like the main navigation or general text like the name, the slogan, the copyright notice, etc. of your website. Another example would be tags and categories of blog posts (equivalent to taxonomies in WordPress). You would just create pages for every single tag or category of a blog post. Let me quote Joss Sanglier with regard to pages in ProcessWire:
Pages in ProcessWire are used for all kinds of things. They can be used as a marker in your pages list. They can be used as a group parent for other pages. They can be used as categories, tags or lists or users. And they can even be used for simple drop-down selects – just to supply a label and value.
Let’s open and edit the aforementioned “About” page.
You are now looking at the next core concept of ProcessWire: fields.
Fields
Pages contain fields. But fields have to be seen from two different angles. Optically they are part of the page, because when you open a page you see fields which you can work with. Technically these fields are part of the page’s template. I will describe the concept of templates later; let’s first understand fields.
Fields in ProcessWire are the containers into which you put data or from which you select data, like text, textareas, numbers, e-mails, file uploads, other pages, etc. It’s totally up to you how many fields a page contains. It can just have one (e.g. a field for the page title), or no fields whatsoever (not very convenient), or more than 50 or 100 fields.
ProcessWire doesn’t have the notion of custom fields like WordPress does, because every field in ProcessWire is a custom field. You create a field and decide what type you want (see screenshot below). That’s it!
A field can be given a label, a description and some notes for additional information that appears beneath it. Every field type has its own settings. Let’s look at three field types and some settings you can make to get a feel for this:
- Textarea field type: You can decide if it is rendered like a plain textarea or like a rich text editor (CKEditor by default). You can decide which buttons should appear in the CKEditor toolbar and even input custom config options right in the admin GUI.
- Page field type: You can link one page with another page and thus create a relation between them. You can either link one page (one-to-one relationship) or multiple pages (one-to-many relationship). You can even allow the creation of new pages from a page field.
- Image field type: You can specify which image type (extension) can be uploaded. You can specify the minimum or/and maximum height and width it must have to qualify for uploading.
The bottom line is this: Every field you create is highly customizable to exactly fit your needs and the needs of the people who create and edit the content in the following.
But how does a page know what fields it has in itself? So, let’s have a look at templates.
Templates
When you create a new page you have to select a template. The template contains all the information the page needs to know about its contents (what fields it has, how those fields are rendered and how they behave).
Below you see the fields of the template basic-page
.
Clicking on a field opens a modal window, where you can modify the settings of the field precisely for that template.
A template can have a physical PHP file of the same name associated with it. These template files are located in /site/templates/
. In such a file you write the PHP code and HTML markup that eventually outputs the page contents and renders the elements a visitor sees on the page of your website.
If a template doesn’t have such a corresponding file, a page associated with it cannot be rendered in the front-end standing on its own. That doesn’t mean that you cannot get the data of that page and output it somewhere else—you can do that by using an existing template file of another page.
Let’s summarize the technical relationship between pages, fields and templates: You add fields to templates, and you select a template when you create new pages. The fields you see when editing a page are the fields you added to the selected template.
2. It Has an API to Fall in Love With
The code in your template files will mostly consist of a few basic PHP constructs like assigning values to variables, if
conditions, foreach
loops and HTML markup on the one hand, and working with ProcessWire’s API on the other hand.
You can think of the API as a jQuery for PHP. It provides methods, selectors, chaining (fluent interface) and traversing capabilities.
The API is probably the one thing that amazes me the most about ProcessWire: It’s easy to use, easy to understand, expressive, and powerful at the same time. But most importantly it lets you develop in a fast and uncomplicated fashion, and you actually have fun interacting with it. It just makes sense.
The API Cheatsheet is a great reference. It shows all available methods you can work with.
Now let me introduce you to the two variables exposed to the API that you will deal with most during template development: $page
and $pages
.
The $page Variable
The $page
variable contains all the fields specific to the page being viewed. This includes built-in fields, which are common to all pages, as well as the fields that are specific to this one page alone.
But how can you access the fields of a page? Let’s dive right in by looking at some simple examples.
Output the content of the text field named title
:
echo $page->get("title"); // or echo $page->title;
Display the name of the page’s template:
echo "This page is using the template: " . $page->template->name; // or echo "This page is using the template: {$page->template->name}";
Generate a breadcrumb navigation:
echo "<ul>"; foreach ($page->parents as $parent) echo "<li><a href='{$parent->url}'>{$parent->title}</a></li>"; echo "</ul>";
Since version 2.5.27 you can also write the above as following:
echo "<ul>"; echo $page->parents->each("<li><a href='{url}'>{title}</a></li>"); echo "</ul>";
Output an image only if it has actually been uploaded:
if ($page->image) echo "<img src='{$page->image->url}'>";
Note: You have to set your image field to contain just one image for this to work.
In the following are a few examples for when an image field is set to contain multiple images.
Grab and output the first image:
$image = $page->images->first(); if ($image) echo "<img src='{$image->url}'>";
Grab and output a random image:
$image = $page->images->getRandom(); if ($image) echo "<img src='{$image->url}'>";
Cycle through all the images, create a large image at 500 pixel width with proportional height, and a thumbnail at 100×100 with specific quality and cropping settings, and then have the thumbnail link to the large variant:
$options = array( "quality" => 90, "cropping" => "southeast" ); foreach ($page->images as $image) { $large = $image->width(500); $thumb = $image->size(100, 100, $options); echo "<a href='{$large->url}'><img src='{$thumb->url}'></a>"; }
Note: ProcessWire will create your images at any size on the fly and then keep a cache of them.
The $pages Variable
The $pages
variable is a reference of all pages in your site. This lets you access all of your site’s content and pages from anywhere you want.
For the next examples I’ll refer to ProcessWire’s standard demo site which provides a collection of skyscrapers in the United States.
Get a specific page and output its title:
echo $pages->get("/cities/chicago/sears-tower/")->title;
Note: /cities/chicago/sears-tower/
is the complete path pointing to the Sears Tower page in the hierarchy of ProcessWire’s page tree.
Find all skyscrapers with a height greater than 500 ft, and less than or equal to 1,000 ft:
$skyscrapers = $pages->find("template=skyscraper, height>500, height<=1000");
Note: height
is a field contained inside the template skyscraper
.
Find all skyscrapers built before 1950 with 10+ floors, sorted by year descending, then floors descending:
$skyscrapers = $pages->find("template=skyscraper, year<1950, floors>=10, sort=-year, sort=-floors");
Note: year
and floors
are fields contained inside the template skyscraper
.
Find all skyscrapers in Chicago with 60+ floors, sorted by floors ascending:
$skyscrapers = $pages->get("/cities/chicago/")->find("floors>=60, sort=floors");
Find all skyscrapers by architects David Childs or Renzo Piano, and sort by height descending:
$david = $pages->get("/architects/david-childs/"); $renzo = $pages->get("/architects/renzo-piano/"); $skyscrapers = $pages->find("template=skyscraper, architects=$david|$renzo, sort=-height");
Note: architects
is a field contained inside the template skyscraper
.
3. It’s Built Around a Modular and Easily Extendable Architecture
ProcessWire itself consists of a small core framework (consider this the essence of ProcessWire which enables the basic functionalities) and a set of pre-packaged modules, which come with every installation. Some of these core modules are installed, and others are uninstalled, by default. Think of ProcessWire modules as WordPress plugins: They extend and customize the system.
The modular nature of ProcessWire has a few nice advantages:
- The code base is more maintainable because core functionalities are isolated and decoupled from other parts of the system, which also greatly increases the overall security.
- The development of new features is being simplified, and bugs can be targeted and fixed much more easily and quickly.
- Upgrades to newer versions of ProcessWire or single modules are usually a no-brainer, and you don’t have to worry that after an upgrade everything is broken.
Installing Modules
Installing a module is as easy as dragging the module’s files to the /site/modules/
directory and then clicking Install in the admin GUI. But there are actually many more ways to install a module from the modules directory.
For example, you can install the Modules Manager, which enables you to browse, download, install and update modules right in the admin GUI.
Amount of Modules: Quality Over Quantity
At the time of writing, around 370 modules exist for ProcessWire. You may now compare that number to the approximately 40,500 WordPress plugins that are out there, and that comparison is indeed interesting and revealing at the same time. Following this, one can draw a few conclusions thinking about the general nature of ProcessWire and its modules, and how they compare to plugins of other CMSs:
- ProcessWire is not nearly as popular and widespread as WordPress, Joomla, Drupal, and others.
- ProcessWire modules are usually of a pretty high code quality. They do one thing and do that thing well.
- The ProcessWire core by itself is so powerful and flexible that it’s simply not necessary to add a ton of additional modules to extend it. For example, you don’t need modules for creating gallery slideshows, modules for getting the first child of something, modules for generating thumbnails, etc. All that (and much more) is already covered with the basic functionalities of ProcessWire.
Hooks
While hooks are a rather advanced topic, it is noteworthy and shows that the functionality of ProcessWire is meant to be super-easy to alter and extend. ProcessWire contains hundreds of methods that you may hook into, in order to modify the behavior of a method.
Let’s say we have built a simple contact form using the API or the Form Builder, and some of the fields are marked as required by the back-end. What we want to achieve is to also add the appropriate HTML5 front-end markup for required form fields. ProcessWire makes this pretty easy. We simply hook into the render method of input fields and define what we want to customize: Ask if the field is required, add the desired front-end attribute, and put an asterisk at the end of the input label.
$forms->addHookBefore("Inputfield::render", function ($event) { $field = $event->object; if ($field->required) { $field->attr("required", "required"); $field->label .= "*"; } });
4. It Doesn’t Get in Your Way and It Provides Tools to Create Tailored, User-Friendly Interfaces
One of the main things people like about ProcessWire: It doesn’t get in your way. It behaves in the way you want it to and adjusts to your style of developing a website.
For example, you have complete control over the output of markup and you are not forced into a specific way of developing a template on the file system. If you are familiar with the WordPress style of developing things, you can continue just as you are used to. Or if you want to create a more sophisticated architecture you could use a MVC-inspired approach, and it will work just as well.
As I mentioned earlier, pages don’t have a set of mandatory fields in order for ProcessWire to understand the structure of a page. (At least not visible ones. There are a few built-in fields like references to the page’s parent or the number of the page’s children, etc.) You can put 100 fields on a page if you want to, order them in any way you want, specify which are required and which aren’t, and you can put them in different field sets or tabs for a better UI experience.
The other main thing people like about ProcessWire: It naturally provides tools to create tailored, user-friendly interfaces. I gave you a glimpse of that in the previous paragraph. The level of customization for templates is mind-blowing. Once you’ve experienced this yourself, you’ll understand why ProcessWire is more a CMF than a CMS.
For example: Every field has a template-specific context attached to it. That means that you can specify that one and the same field has a certain label, description and behavior in one template, and a completely different label, description and behavior in another template.
Another example are inputfield dependencies: They enable you to specify the conditions under which a particular field in the page editor is shown or required.
And yet another example is the module PageTableExtended: it lets a user view, edit and modify the different parts of your website page (which you as a developer define) in a visual and intuitive way.
That to me is the definition of elegant and deeply empowering.
Conclusion
This article can only scratch the surface of what you can do with ProcessWire and what it has to offer. The list of great features is, simply put, too long and would go beyond the scope of this article. Let me give you a glimpse of some of these:
- ProcessWire has great caching mechanisms (e.g. template and markup cache or ProCache) and performs very well. Scalability is also pretty impressive. You can literally have millions of pages on a single installation.
- ProcessWire has a small but fantastic community. The discussion board is the central place to discuss any questions and problems.
- ProcessWire has stellar multi-language support. The multi-language modules are part of the pre-packaged core modules. It’s very easy to set up and maintain.
- ProcessWire has great built-in user management capabilities with settings that are very detailed and easy manageable at the same time. For example, you can create a role for users which have the sole permission to edit fields in French, and in no other language.
- There are a bunch of admin themes you can choose from to change the appearance of the admin GUI.
- Security is a top priority for ProcessWire.
- ProcessWire has a transparent roadmap and the development is very active. There are new minor releases nearly every week.
The more you use ProcessWire and the more you internalize the core concepts, the API and its modular architecture, the more you will have fun using it. You will realize how incredibly powerful ProcessWire’s tools and workflows really are. One could say that the only thing limiting you in achieving a certain goal with ProcessWire is your own imagination.
Let me finish by quoting the creator of ProcessWire, Ryan Cramer:
ProcessWire is a system that rewards you by being curious. We aim to show you how to fish so that you can catch the big fish.
Where to Go From Here
Useful links and tools around ProcessWire:
- The documentation section of ProcessWire’s website is a great way to start your journey to learn more about ProcessWire. You’ll find information about the API, the directory structure, template files, selectors, multi-language support and security.
- ProcessWire Weekly is the weekly source of ProcessWire news and updates.
- ProcessWire.tv is a searchable collection of ProcessWire tutorial videos.
- wireshell is a command-line interface for ProcessWire based on the Symfony Console component.
- Padloper is an e-commerce platform built on top of ProcessWire.
- ProcessWire Module Generator is a visual way to start module development with lots of module development best practices.
- ProcessWire Recipes is a directory that aims to collect mini-tutorials for common and not-so-common ProcessWire tasks and problems, presented in a concise and spot-on format to help you grow your ProcessWire mastery.
- ProcessWire Cheatsheet is a very useful cheatsheet for all available API methods.
- Visit grap.pw to download the latest stable version of ProcessWire.
- You will find a lot of useful and interesting content browsing through the most liked content of ProcessWire’s official discussion forums.
- See what others have to say about ProcessWire in the ProcessWire Reviews.
- Check out some sites powered by ProcessWire.
Comments