Musings of a Sitecore Developing Man

April 25, 2014

Prologue

This article is about the theory of template development. A topic, which at its best, is dry and wonkish. My goal is to provoke thought and discussion but mostly to prevent others from having to continuously wander through this hedge maze until they invariably come to the same end. Besides that, there may be a better solution still that someone else has come up with.

Act I

Recently, on a particularly frigid night in Boston, while milling around after the New England Sitecore User Group, I was speaking to Rick Cabral about his ORM Diamond. I mentioned that I thought he was right to conclude in using interfaces to describe datasource data types in sublayout controls. My reasoning was that fields should be grouped into templates by use, then inherited into pages. Each grouping would then lend itself to being defined by an interface which could be implemented on any page class and then many different page types could reuse or interchange code and presentation elements as needed.

Act II

Let me back up a bit and explain where I began when I came to my conclusion. I was thinking a bit about an article I read discussing the page template mistake which discusses better ways to build templates for the page editor. I really wanted to follow up with my own thoughts on page templates because there are a lot of constraints when building a multisite solution including template reuse.

When you're trying to share templates between two or more sites, you're going to hit page template dilemma. Let's say you have three sites in your system and two of those three will share the same presentation but will differ in content and language. The third site, however, will need to have a separate design and as a result will need a different set of presentation details. If you've already created a page template with fields and presentation set, you have two options: inherit from the page template that already exists and get with it all the standard values baggage (insert options, default tokens, and presentation details) or create an entirely new page template and duplicate all the fields. Both prospects are disagreeable.

Inheriting may leave you with fields you don't need and if the presentation of the base template gets updated, the changes may or not make it through since your customization will break the chain of inheritance. What you're left with is needing to reset the presentation details now and again to get the changes to pass through, then re-adding any changes you've made. Even now, I'm left with a foul taste in my mouth from when I had to do this.

On the other side of the coin, is creating a duplicate set of templates and fields which has the drawback of limits with respect to scale. One thing I hate doing is repeating myself. I have a particular distaste for duplicating templates and their fields since, with just over a hundred site in my system, the thought of a creating a hundred sets of templates, just so I can change the presentation, makes me ill.

Act III

This presentation problem has been with me for longer than I care to remember. Even back when it was only two or three sites in a system, there was a need to share template fields and separate the presentation by site. At first I thought about customizing Sitecore to support having multiple standard values and then setting up a custom Standard Values provider that could choose which to use depending on the site settings. Not entirely a bad solution but when you customize built-in template behavior you're asking to get your system wiped out when you upgrade.

I've also inherited a solution that modifies the path to the layouts and sublayouts during page load to look in the physicalFolder path of the context site and check for the file there before defaulting to a global folder. It's really brilliant but still creates a lot of customization to pipelines that a future change to Sitecore could break.

Denouement

To solve this problem in a way that's a bit more future-proof, you have to find a way to work with the system. The realization I then came to, was that you need to think of page templates as non-field, presentation only. This allows you to create more than one copy of the same generic page template but with different presentation settings and without duplicating the fields. The next logical step is to see each group of fields in their own templates that can be inherited by these page types. To clarify I'll show an example. Let's say we want just a home page, regular page and a form page across these three sites I've mentioned previously. Here's how I'd structure the templates:

Example template tree

To start I'm using a global pool of "Page Groups" that define fields for specific uses like meta data, page content and form handling. I've also created an intermediate layer with the "Page Base" and "Form Base" templates that then inherits these groups. Nothing up to this point has any type of presentation associated with it. They only relate fields to a use and groups of fields to a page type.

The presentation details are defined for each specific site on the matching "Page", "Home Page" and "Form Page" templates in those specific site folders. From the earlier example, the first two sites would use the "Default" set of page templates. The third would use the "Site 1" templates. Both "Form Page" templates will inherit from the "Form Base", "Home Page" and "Page" from "Page Base". Now there's no duplication of fields and you can specify the presentation for each site uniquely. From here you can create IFormBase and IPageBase interfaces that will allow you to build reusable web controls and methods in a core library and globally reusable sublayouts. And ultimately that is the goal; reduction, reuse and modularity.

Addendum

After reading through this a second time, I realized I forgot to mention how this affect insert options. This is a good place to add them because the root structure of what you'll be creating in sites, are pages. Or more explicitly, the items with the presentation set on them. You could brush some broad stroke with the insert options on the standard values here. Then in the event an individual site needed them, you could manage insert options on a site level as well.