In my previous article I explained that django CMS was immediately attractive to us - Cardiff University School of Medicine - because of its restricted feature-set. If that sounds like an unusual thing to find attractive in software, maybe you should have a look at my explanation.
In fact that's only half the story, and of course any idiot could create software that lacks useful features. Some idiots manage to do this with remarkable success.
The other half of the story: is getting right the features that are provided, and leaving out features in the right way.
I won't discuss the features that django CMS gets right, because plenty of people have done so already, and most users of django CMS know what they are.
The right way to leave out features
Instead, I want to discuss how django CMS leaves out features in the right way.
The key point is this:
By design, django CMS will often omit a particular feature.
In its place it will provide a general, uncommitted solution to the problem.
- it avoids the very common problem of providing a feature that is somewhat like what's required, but not quite right, that obliges you to restructure your information and content around someone else's ideas of it
- you get to choose how your information and content are represented, managed and published
django CMS's Application Programming Interfaces
django CMS does this through its numerous APIs, which by the way are consistent, well-documented and have proved to be very flexible.
Example one: the plugin engine
The most obvious examples are provided by the plugin engine.
django CMS actually abstracts from all content types, and only handles plugins. It's the plugin, not django CMS, that touches the actual data. django CMS itself is content-agnostic.
Even though django CMS ships with a number of fully functional plugins that can be used without any further ado, they are just plugins like any other, and can be replaced or removed - or simply ignored - without breaking anything.
In fact, django CMS doesn't know, and because of the plugin engine doesn't need to know, about content. What it does is provide you with structures and hooks for you to use as suits you best.
What is an image?
Let's look at a concrete example. Almost everyone who needs a web CMS needs to be able to publish images. Well, django CMS has no concept of an image. In fact, there is literally no built-in way to handle images in django CMS.
"That's ridiculous," the person who hasn't used django CMS will say. "What kind of a CMS has no way to handle images?"
"That's ridiculous," the person who has used django CMS will snort. "I use images in django CMS all the time. Daniele's obviously some sort of idiot."
But it's true. There are plenty of ways that images can be seamlessly incorporated into a django CMS system, but the point is that none of them are built-in - none of them are unremovable, fixed parts of it. They can all be removed , changed, switched out or ignored without disturbing django CMS in the slightest.
Given all the different ways django CMS projects want to present images on the web, and all the different ways they manage images at the back end, there is no possible way that a single concept of an image could work for them all.
So, different people have created various different image-handling plugins for django CMS. I didn't even know whether django CMS shipped with one by default (it does - I checked just now, and it comes with one in the box). I use my own, but I didn't need to remove or disable the one it ships with - django CMS meant that it simply wasn't something I needed to worry about.
All I needed to be concerned with was my own image plugin. I didn't have to work around the image plugin the system came with, or fight it or hack it. It didn't get in my way or even make me think about it.
This is a very liberating approach. If I were starting out with django CMS, I'd find it came with a plugin to handle images. If I wanted something else, there are numerous alternatives out there to choose from. But since I have very strong ideas about how my image plugin should work, I was able to create my own without even thinking about what anyone else had done.
This was only possible because the creators of django CMS resisted the temptation to decide to build in image-handling features, which would have committed it to a certain idea of the information structures, workflows and presentation related to images.
You'll find this approach everywhere in django CMS. It might not be immediately apparent why it matters so much, but the more you work with it the more grateful you are for it, because you'll find yourself benefitting from it at every turn.
Example two: the menu system
django CMS's menu system is actually an application of its own, and it too is deliberately uncommitted and abstracted. It doesn't represent pages, but nodes, and the pages system - just like any other application - communicates with it via an API.
This means that when it comes to the menu, your own applications are equal citizens in a django CMS system. They don't have to hack their way in to the menu; if they need to influence it, they do so through the nice, orderly, democratic API that is provided.
Example three: the placeholder system
django CMS is not only democratic, it's pretty generous too.
Plugins get inserted into placeholders in pages, which is how your django CMS pages have content. The plugin architecture really is a superb piece of work. But django CMS doesn't keep it to itself, it makes it available wherever you want them. Your own applications and templates can make as much use of them as they need, and as soon as you use a placeholder, you get to use any plugins too.
Even better, you find that django CMS has encouraged you to adopt the same approaches.
In my previous article, I described django CMS as a good influence that helped improve our own applications - well, this is one of the ways it does just that.
Since incorporating the plugin system - which was hardly more difficult than adding a placeholder field into a few models - I have not only been able to ditch a remarkable amount of fussy, restrictive and dead-end code, but have also seen ways to make it simpler and more flexible, and not make those mistakes again.
What this means for you
This isn't the place to describe all the rather numerous ways in which django CMS takes this approach (I doubt I have discovered them all anyway). There are several others, and by their nature, they tend to be things you won't encounter (and if you're like me, won't even understand) until you're deep in your programming work and discover that you need to integrate something into a django CMS-based system.
That's the point at which you'll discover that django CMS not only doesn't get in your way, but hands you the tools you need to do it and provides the documentation too.
Developers [heart] django CMS
While developing Arkestra, I have had reason to be thankful almost daily for the foresight and wisdom of django CMS's designers. The openness of its architecture means I have not been constrained by their decisions: I have never been forced down someone else's road or painted into someone else's corner.
Instead, I've been able to make my own applications integrate effectively and easily with django CMS, and make the whole system work the way I need it to.
I've been saved vast quantities of effort, because django CMS offers its frameworks so effectively for use in those applications.
And merely by going along with django CMS's approaches, I've found that it has improved my own applications too, helping me keep them open and flexible, in a way that has directly benefitted me, and has made my software attractive to other developers as well.
All of these advantages have come directly from the intelligent ways in which django CMS omits features and doesn't do things. You won't see them listed amongst the bullet-points of the software's capabilities.
But, particularly if you are a developer, you will appreciate them. What's more, you will continue to appreciate them long after people using other systems have simply resigned themselves to working according to dictates imposed on them by the way someone else decided a particular content-related feature should be implemented.blog comments powered by Disqus