MODX: The Best CMS You’ve Never Used?By Zack Wallace
MODX is a content management system that was first released in 2005 by Ryan Thrash, Raymond Irving and Jason Coward. They created it to give them freedom of design and yet retain robust security which they felt other CMSs didn’t allow.
In 2009, MODX was released as
Evolution and
Revolution. Evolution was built and maintained on the original codebase, while Revolution was entirely rewritten. This article is based on Revolution.
Within the MODX manager, you have access to a built-in package library which contains most of what any developer would need for common tasks. Creating your own plugins and scripts is quite trivial, and there are some good for-pay extras out there too.
Visit the MODX Home and about pages for more history and feature information.
Have We Met?
If you’ve never heard of MODX before now, just realize it’s a long-lived and pretty powerful engine that is often compared with the likes of Joomla and Drupal. Some also compare it to WordPress, but that’s not apples to apples. WordPress is meant to be usable out of the box by non-technical people. In fact, MODX has been described by some as
the best CMS you’ve never used.
More from this author
In general I would summarize MODX as a framework for developers to build with, and not an out-of-the-box, point-n-click website builder. MODX would not be the best choice of CMS for a person with no PHP or HTML skills. There are no
menu builders or lists of modules to drag and drop in predefined theme positions.
MODX may be better described as a CMF (content management framework) than a CMS. You could use just the API purely to control endpoints and scripts with no
pages or
posts at all, if you wanted.
Digging Deeper
MODX, like many popular frameworks, is built with PHP. It can run on popular servers such as Apache, IIS, Lighttpd and nginx. Its database of choice is MySQL, and it uses xPDO as an ORB (object-relational bridge). xPDO is built directly on PDO, and uses an active record style pattern for database access. It can be compared to the likes of Doctrine or Propel, for example.
The
Manager is built with ExtJS, Smarty templates, and MODX’s own API. Editing the manager itself and its dashboards, menus and other features is an ability built right in to the UI. You have fine control over everything in the Manager as far as what you want your clients to have access to.
Custom menus, and very fine-grained ACLs (access control lists) round out your back-end options. Security is probably one of the top features MODX fans love about it, though understanding it fully involves a significant learning curve.
MODX itself is backed by an LLC, which is MODX, LLC. They offer other products such as cloud hosting and consulting services. MODX is not an
SGP (some guy’s project); it has a bit more staying power than some other modern CMSs that just popped up, created by one person, managed in their spare time. You can be pretty confident that if you choose MODX for your projects, it’s not going to disappear any time soon, and good support is available.
Education and Documentation
MODX is well documented, including videos, books, and the standard community forums. The forums, incidentally, are built on MODX itself, using freely available extras, and you can find threads over 10 years old still lingering.
All in all, you will want to check out the Revolution Manager Tour, watch the Video Quick-Start Series, and browse the documentation such as the Overview to get well acquainted.
MODX also has a fairly active Slack channel where friendly people are always available to answer quick questions and gotchas.
The Installation
MODX is only currently installed by downloading the ZIP and extracting to your web folder.
As far as updates go, there’s no self-updater in the core product. However, there is an extra which does the upgrade for you just as easily. All of the extras themselves can be updated through the manager.
The project is managed on GitHub, which will always contain the latest snapshots of the project. You could install this way, but downloading from the main website is the preferred and normal method.
Why It’s Awesome
MODX is something of a power user’s CMS. Out of the box you get a blank template to design with, and hundreds of settings to change how things work. There are no wizards, drag and droppers, menu builders, widget organizers, template settings, strange forced file system hierarchy structures or magic functions to throw everywhere.
I was hunting for a CMS some years ago as a means of converting some older, hand-coded sites into a CMS. Nothing I found made this very easy without a lot of tweaking and learning complex template structures. When I installed MODX, there was this link to
BaseTemplate; I pasted my HTML in there, and it just worked, no fuss no muss, as they say, and nothing broke.
In fact, if you’re typically a hand coder, MODX may be the best CMS for you. The learning curve to creating hand-coded websites is extremely small.
When you want to develop multi-language, multi-site websites with separate paywalled content and a customized manager for your clients, then you’ll experience what MODX can do!
Everything about MODX is rather unassuming. For any given task you need to complete, there are typically multiple ways of getting it done.
From simple to complex, MODX can do it all. It’s been used to build API endpoints, forums, blogs, business sites, brochure pages and multimedia sites. It can handle languages, advanced security permissions, and customizing of the manager for client logins.
Assembling a Web Page
MODX uses a stack of pieces to assemble a web page. It uses what are called Templates, Snippets, Chunks, Template Variables, and its own template tag system. These are all called
Elements:
You can get any system data from within templates — such as logged in user data, current page data, metadata, system-wide settings, template variables, chunks, snippets and placeholders — by using tags.
The MODX workflow involves coding your HTML templates and parsing out reusable HTML into
Chunks and reusable dynamic PHP stuff into
Snippets. You can set up any custom fields needed for that template as well. Next you’d create a
Resource, assign it to the template, fill in the fields, and Bob’s your uncle!
A Resource is the basic definition of an endpoint; it’s something found at a URL. You could call resources
pages, but they can be used for much more than that. You can set the actual content type of a resource to be something other than HTML, such as PDF or binary data. Then you can set the content to either download from the browser, or display directly. A resource could even just point to a file, or link to an outside page, or be used as a symlink to other content on the site.
A Template is the frame around which your resource will be displayed. All resources are assigned a template.
A Chunk is reusable HTML or JS or whatever you need that isn’t PHP.
Snippets can contain PHP. They have access to the MODX core and all its objects.
A snippet can call a chunk, a chunk can call a snippet, templates can call either, and so can resources. Really they are the 4 horseman and can pretty much assemble any conceivable content required while maintaining darn good separation of concerns.
A Plugin can extend the core by hooking into one or more of many events.
A Template Variable is any custom data a template might need, and for which a resource is able to set. For example, it’s common to have a TV for a custom image like a page banner, but then each resource can assign a different image for the template to show. They would be like
custom fields in WordPress, but more powerful.
You can organize any of these elements by using Categories. Be sure to make use of categories so that your chunks and snippets don’t get out of hand and cluttered!
All nicely tucked in a simple tree that you just saw.
A Quick Look at the Manager
The manager is built with ExtJS. With that comes interesting abilities with drag and drop, form customizations, dynamic tables, right-click context menus, and more.
You can right-click resources for various options — including
Quick Edit — which will let you edit the resource in a popup while keeping another resource open under it.
A handy feature of media management is that you can set up media sources which are then controlled by security. The end result is you can have it be that when clients log in, they will only be able to see the folders you assign for them, and even assign read-only access.
The system settings are based on
namespaces. You can even create a namespace for yourself and invent arbitrary settings you may use elsewhere in your app. I’ve done silly things like create a
company namespace and settings such as
primary company phone so that I can use the same number through the site. Then if the number changes, it’s only changed in one location. I give users access to changing these settings.
All in all the manager is not complicated to get around in, despite the advanced features available.
Contexts
Notice the text
Website in the image above. This is a
Context, which basically means the context that viewers are in when they look at your website. When logged in to the manager, you are actually part of the
Mgr context. Different contexts can have completely different resource trees, user permissions, access controls, language — the whole nine yards. The
Mgr context is hidden from the tree by default.
Think of a context as being an entirely different website; even advanced sites may rarely take advantage of creating additional contexts. One common use of a context would be to create a type of
member only website within the main website for authenticated users. All you would have to do is not allow public (guest) access to the context, among other things.
I’ve also seen contexts used simply to organize similar resources like a set of static files, or when serving non-HTML content types. Use them however you like! One caveat is that if a user is logged in to one context, it doesn’t mean they have access to all of them. If you wanted a type of single sign-on for all contexts, it would need extra development.
A context could be used (without security) to simply separate site areas, like a message board, blog, or a store. Some use it for alternate content for different languages. It’s one of the relatively
hidden power features of MODX that many never even notice or make use of!
Templates and Tags
I mentioned that MODX has a built-in template tag system. Here’s how it works, briefly.
Each tag begins and ends with double brackets
[[ ... ]].
A character is used to denote if you are calling a chunk or a resource field or system settings etc. They are:
[[*...]]: An asterisk retrieves resource fields. That is, specific data entered for the current resource, such as the page title or even the main content. It also looks up template variables.
[[++...]]: This is looking up a system setting, such as
site_urlor a custom setting like
company_phone1if you’ve created one.
[[+...]]: This is a placeholder.
[[~##]]: This generates a URL to a resource by its ID, such as
[[~32]].
[[$...]]: This pulls in the HTML from a chunk.
[[...]]: No symbol at all will call a snippet.
[[%...]]: Pulls a language string.
[[-...]]: MODX comment.
[[!...]]: The exclamation point tells MODX not to cache the output of the tag; use it in conjunction with previous symbols. If you called
[[!$SomeChunk]]then the output would be parsed each time, rather than pulled from the cache. Sometimes caching can bite you! Learn about it here. Did I mention MODX has a powerful cache built right in?
Tag Parameters
Tags can use parameters and filters to customize their output. For example, you can add some parameters to an auto-generated URL like this:
<a href="[[~17? §ion=`food` &sort=`asc`]]">Here</a>
As you can see, the syntax of using parameters is not unlike parameters in a normal URL query string. A question mark denotes the start of a list of parameters, and each parameter starts with
& and places the value in backticks.
The output of the above would be:
<a href="yourpage?section=food&sort=asc">Here</a>
A snippet can receive extra data when called in a similar manner:
[[!MyCustomSnippet? &input=`something tasty`]]
Here, a snippet named
MyCustomSnippet is called, and given the extra data named
input, with a value of
something tasty. In PHP, you would get a variable automatically created called
$input, which you can access in the snippet.
Tags can be embedded within each other. A very common tag is this one:
<a href="[[~[[*id]]]]">Link to this page</a>
There’s a resource field
[[*id]] embedded in the link tag
[[~#]]. Inner tags are parsed before outer tags.
In another case, where you might be calling an HTML chunk and passing it some dynamic data pulled from a snippet, it might look like this:
[[$AChunk? &data=`[[!GetTheData]]`]]
The chunk tag is sending
data to the chunk, but uses a snippet to figure out what that data actually is.
Because the above tag is calling a chunk, which is only HTML, how does it read the
data values? They are automatically available with a placeholder tag like so:
<h2>A title</h2> <p>[[+data]]</p>
Placeholders are used most frequently in chunks like this.
Output Filters
Tags accept more than just parameters; they can also utilize
output filters. Filters run post-processing code against the output. Multiple filters can be chained together. The easiest example would be changing the case of a string.
[[SomeSnippet:ucase]]
A filter begins with a colon; it must come before your parameters. Here are a few chained filters:
[[SomeSnippet:ucase:replace=`this==that`? ¶m1=`Go big`]]
Here, the Snippet result is first converted to uppercase, then it runs a special
replace filter to change all occurrences of
this to
that. After the filters, the parameters are listed, starting with the question mark as usual.
There are quite a few default filters, so check them out here.
Even cooler than the built-in filters is that you can use any snippet as a filter. All you have to do is use your snippet name like a filter:
[[$CallingChunk:mySnippet]]
Whatever HTML is sent by the
CallingChunk code, your
mySnippet can access and change it however you like with your own PHP. The value of
$CallingChunk would be available in your PHP with an
$input variable, and you would simply
return the edited value. (See here for more details.)
Filters can be used for logic, with full
if then else flow.
If That Weren’t Enough
There are so many things not touched on: structuring the tree, handling repeatable content, accessing the database or creating custom tables.
You can categorize content, have parent/child relationships, create containers, publish/unpublish dates, group content for security purposes, create plugins to validate data your clients may enter.
The list goes on and on. You can edit your content types and MIME data, page extensions (use ‘.html’ or not), or create an Amazon S3 bucket as a media source.
You can edit in the default raw text/HTML or install extras that enable TinyMCE, CodeMirror, or ACE. There’s an editor for Markdown. And there are even extras for tracking revisions or exporting your custom code for use in other MODX websites or to share with other developers.
Elements have properties which are like system settings, but only for that element, so if you create an awesome snippet of amazing PHP, you can use properties as a way to create default settings for it, which users can then change with their own property sets.
Template variables can be assigned categories so that they can be grouped together when editing resources. Very handy stuff when creating custom content that clients can change.
Cons
The codebase of Revolution is showing its age, and doesn’t utilize some modern PSR standards such as autoloading and namespaces, nor does it use Composer for packaging.
The third rewrite of the platform, dubbed MODX 3, will move the core into modernity. Don’t let this prevent you from trying MODX though: with age comes wisdom, and the entire MODX platform is quite capable, mature, secure, and extensible. However, you’ll see developers criticize the older code patterns.
A second issue is the use of ExtJS. This framework is quite nice, but the issue is MODX is pretty much stuck using an older version of it. The current manager cannot be updated or it will break many 3rd party add-ons.
Future versions of the manager will likely not use ExtJS at all, or be locked in to any library for that matter.
Beside those issues, the only problems I’ve ever had with MODX stem from server configuration. This has caused conversation about who are the best
MODX friendly hosts, such as this MODX forum thread.
Conclusion
I’ve covered a lot here and hope I’ve sparked your interest to give MODX a try.
Like any tool, it has specific use cases where it fits best..
Since SitePoint has never really covered MODX, I’m curious who has tried it. Did you love it or hate it? Do you have any more questions about it? And would you like to see some more coverage of it? Let me know in the comments.
- Cracheur DeRat
- donshakespeare
- Zack Wallace
- Sal B
- Cracheur DeRat
- donshakespeare
- Marek Králík
- Zack Wallace
- Marek Králík
- Zack Wallace
- Marek Králík
- Mark Hamstra
- Marek Králík
- Mark Hamstra
- Marek Králík
- Murray @ Digital Penguin
- Marek Králík
- Michał Prochownik
- Zack Wallace
- Marek Králík
- donshakespeare
- Sal B
- Marek Králík
- Zack Wallace
- Anne Miles
- Todd Zmijewski
- donshakespeare
- Todd Zmijewski
- donshakespeare
- Joey Augustin
- Mark Hamstra
- Todd Zmijewski
- Zack Wallace
- Murray @ Digital Penguin
- Todd Zmijewski
- Murray @ Digital Penguin
- A mí no me pagan por opinar
- donshakespeare
- nico jacobs
- donshakespeare
- Zack Wallace
- Murray @ Digital Penguin
- Murray @ Digital Penguin
- Jonathan Haslett
- Zack Wallace
- Michael Regan
- Jonathan Haslett
- Zack Wallace
- Michael Regan
- Zack Wallace
- Zack Wallace
- benshu
- Zack Wallace
- Ty Cahill
- Zack Wallace
- Mark Hamstra
- Ty Cahill
- Michał Prochownik
- Anne Miles
- Ty Cahill
- Ty Cahill
- doomy
- Zack Wallace Is Sketch App with Atomic.io the Perfect UI Design Duo?
- 3 Build Your Own Dropbox Client with the Dropbox API
- 4 Quick Intro: PhpCompatibility for PHPCS - Are You PHP7 Ready?
- 5 Is It Possible to Write and Run PHP Code on an iPad?