The roots of DNN are in Webforms. In the early days of asp.net this was Microsoft’s evolution of the Active Server Pages technology. Since then the world has moved on quite a bit. Various alternatives to Webforms have been introduced on the Winstack and by and large PHP has grown more explosively than any .net based technology. In part, because the php-based cms solutions have been kinder to web designers. How else to explain the vast amount of skins (themes) available to them and the general disdain of any web design firm for .net? OK. Maybe this is not entirely accurate, but the feeling I get is that we could make progress by making DNN more design-centric. And in my opinion that translates to: ensuring a designer has a better grip of where the HTML and CSS is coming from and where to change this.
One of the complexities, here, is that due to the plethora of coding technologies/methodologies now available to us, no module is like another. This makes it harder for anyone to tweak a complete site as one needs to “get into” a new module countless times. Another is that with our in-line editing approach (as opposed to a management interface) to pages, it is not easy to understand what is going on just by looking at a page. Even in edit or layout mode. E.g. which modules are being displayed and which containers? Or if there are any tweaks to the containers in terms of HTML/CSS. This article proposes a solution consisting of two parts: a uniform approach to templating and a management part dedicated to design.
A unified approach to templating
I’ve already written at length about a specific solution for templating in DNN modules. In this post I’d like to focus on a broader strategy for templating. A quick research on the module I’ve used on a couple of recent sites I’ve worked on shows me there are 3 places where templates are stored:
- In one or more files on disk
- In the resx file
- In module settings
- In a custom format (e.g. NBStore uses xml files)
There are several disadvantages with having various methods mixed in a single system. For one it is hard for a designer to know where physically a piece of HTML is coming from. And secondly: the editing experience tends to be very different for each. We could gain a lot by having a single mechanism prevail and become “best practice”. And that standard should be in files on disk. Why?
Well, consider the resx file solution. It is quite commonplace in DNN modules to store templates in there (even the core modules do this) and it stems from using the resource file for email templates. The resource file is most commonly used to store texts that need to be translatable. There is a “cascade” to ensure that the best match text is retrieved. You can have a resource file at portal level and at system. So you can override a text in the portal for a specific language. Very useful. But templates operate at module level. In most application areas you must be able to apply/choose a template for a module individually. Maybe multiple modules share the same template, but by choice. So the resource file as storage for your template is not a good idea as it cannot cope with all these scenarios. I can see how it’s OK for email templates, but not for display templates.
Now to the module settings approach. A number of modules, such as Events for instance, get their templates from the resource file and then store them in module settings. With this mechanism, the advantage of localization of resource files is of course lost, but what is gained is the module level control of the template. But this system not only loses localization it also loses a lot of its portability. Sure we can use DNN’s IPortable, but preparing something in staging and porting it to production becomes a big hassle.
Finally the custom solution. I’m sure there are solutions that can’t be caught in one of the other approaches. But what you lose in this situation is that you require the designer to get familiar with your way of doing things. It increases the overall complexity of the system. There is a whole cottage industry of people that know how to skin module XYZ. In itself not too bad (everyone makes a buck) but it leads to the whole platform being seen as difficult to design.
My proposal boils down to this:
- Use a file based approach to templating
- Given that not all templates can be caught as a single file, let’s use a folder to group one template together
- Let’s agree on a standard way to store the templates, e.g. DesktopModules/MyCompany/MyModule/Templates/TemplateX
- Let’s agree on a standard cascading mechanism (system, portal, etc)
Of course we will also want to ensure that they can be localized which should/will be the topic of another post. Now, what are the biggest advantages we can gain with this approach?
- Designers will find it easier to find your templates
- Easy to move/redistribute
- We can make a generic template editor
- You could roll a template into a skin
- We can even imagine a “template exchange”
- A better template management
I’ll elaborate on a number of these.
A generic template editor
One thing that has bugged me is that as attractive as the use of templates is, it’s a drag to have to implement an editor in your module. It’s a lot of work and if you’ve done it twice you keep thinking to yourself: this should be centralized. And because the template editor is not necessarily “core functionality” of a module, it ends up being the “not so pretty part” of the application. It doesn’t get a lot of love. Most modules just implement a straightforward textbox on the main settings screen or rely on the core’s resource editor.
So how about centralizing that? How about a “core” template editor that can be leveraged by modules and the designer to edit the templates? The editor would be primed with just a path to the template folder and would be able to edit any file underneath this. And we could then make a really decent editor. I’m thinking of using the Codemirror library, for instance. This is used in the new SQL module if you want to see what that’s like. And we could define a standard for the module to communicate to the designer what is allowed and what isn’t. Specifically: the tokens and what they mean. The editor could then display these neatly alongside the editor. If done consistently by modules, then editors will get a consistent editing experience, making working with DNN a joy!
Templates as part of a skin
I’ve recently implemented this for the Blog module. The possible places where templates can be stored for the Blog module are:
- In the module directory (i.e. DesktopModules/Blog/Templates)
- In the portal directory (Portals/0/Blog/Templates)
- In the skin directory ({templateDirectory}/Templates/Blog)
Now this is not yet perfect. I’d like to add host level templates (so under Portals/_default) and we need to unify the path naming (so in all cases Templates/MyCompany/MyModule). But the important take-away, here, is that a designer could group all the work in the skin folder and redistribute that as a complete package that skins not just DNN, but also individual modules. That is a huge win, IMO.
A template exchange
Like skins, templates can be a lot of work to do nicely. So why not allow people to share their work. One of the ideas I’ve had for future development for the Blog module is to have some sort of central template repository where users can exchange their templates. Naturally, if we have a unified approach to templating we could make a more generic exchange.
Template management
The template editor, then, should be able to manage the templates. I.e. upload, download, and copy. With copying, you’d have the opportunity to copy a template from a distributed level (in the module directory for instance) to the portal level.
Baby steps
The first thing I need to do is to create the generic editor to show you the power of this idea. Rome wasn’t built in a day and for sure we’re not going to have all module immediately follow this pattern unless it is clear that the tooling is there and that there is a real advantage. Anyone is welcome to join this effort with me.
This post is cross posted from my blog at DNN-Connect