13

This is a best practices question.

When designing the templates and content tree for a Sitecore installation, what determines whether a given field should be part of the "Page's" fields vs stored on a discrete Item and referenced as a DataSource?

I'm looking for a list of decision-making concerns, for example - Workflow behavior, or ease of translation.

3 Answers 3

12

I could get up on a soap box and speak for days on this. In fact I have. The Page Template Mistake.

The role of Information Hiding

The first concern you must address (from my viewpoint) is: You need to separate this decision making from your actual code build.

Or put differently: Your components should make as few assumptions about the Information Architecture as possible

In software engineering this loosely called Information Hiding. It's a good practice in software development, and it holds true for your Sitecore solutions as well.

In computer science, information hiding is the principle of segregation of the design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed. The protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change).

Translated into "Sitecore speak", this means you need to declare an interface between your Sitecore Information Architecture and your component - creating a clear definition of what information is the component is made aware of. Subsequently, everything else is "off limits".

Fortunately we have a method for doing exactly that - it's the Datasource Template

The shared interface

So, we've established that any component should have a clearly defined interface. We then connect the two, by setting the Datasource Template on your rendering item.

The Datasource Template looks like this:

the MetaHead template

And we reference the template on the MetaHead Rendering like this:

the MetaHead rendering

So far so good. You've established a basic "contract" between Sitecore and your component implementation. (As an aside, there are ways this can be overridden, so it's not a strict "guarantee". It's usually good enough however.)

The next step is to use this in your code.

The design pattern

One of the oldest principles in Sitecore Information Architecture, is how the code treats the Datasource it is given given. When Sitecore was originally envisioned, I suspect sites were being built primarily using XSLT. As such, it makes sense to pay attention to how the XSLT engine treats a Datasource sent to a component.

We find this in the Presentation Component XSL Reference:

A rendering can retrieve data from its data source item. The $sc_item variable represents the data source item for an XSL rendering. If the developer does not specify a data source item for a rendering, the default data source item is the context item, and $sc_item and $sc_currentitem are the same item.

Translated into technologies we use today, it basically says if a Datasource has been set, use it. If not, fall back to Context.Item

Before doing anything else, your code should ensure that the item you get from the process above actually implements the template you defined in the contract above. (I know Glass Mapper can do this. It's also what my own Datalift project is all about.)

Now implement your component; assume nothing about data outside your defined component template. No Context.Item, no Context.Database, nothing at all. That one item you end up with - will have all of that.

I like to call this item your ActionItem, simply to distinguish it from other terms that are used a bit loosely (like Datasource Item and Current Item.)

  • ActionItem.Database
  • ActionItem.Language
  • and so on.

You should essentially never need to touch Context.Anything using this approach.

We have now come full circle and I can explain how this relates to your question. (And more importantly, why you shouldn't spend a whole lot of time worrying about exactly this.)

Page Templates.

If you follow the above recommendations, you're largely free of constraints in your Page Templates - and you're also free to change your mind later on.

The role of the Page Template

So in your question you specifically ask for, where a field should live. I say; you don't make these decisions on field level. You make them on template level. Where each template matches a component. You don't want components cherry picking fields left, right, and center - you want Information Hiding so the components know nothing that isn't in the contract you've set up.

To demonstrate and visualize what I mean, I've set up a few more component templates:

Additional Component Templates

And to match it, I've added some matching rendering definitions. We'll pretend I've coded them as described above ;-)

Rendering Definitions

And now we're at the key question: "How should I decide, what goes on the Page Templates?". First, let's make a Page Template called Homepage.

Homepage template

I then say to myself; "Well for this type of page - I will always have at least one of each of my components on the page. (There may be additional promo spots, but I will always have one.)"

In that case, we're good to use our component templates as base templates for our page template. We go to the Template Builder ribbon, select Base templates, and add all of them.

Homepage template with all inheritance

And - this should come as no surprise - we end up with a Page Template that now has fields, for all of these components.

Fields of the Homepage template

And your code will work. Create new instances of this new Page Template, add your components to Presentation Details, and don't set a Datasource for them... everything works.

Let's create another one called Section Page. This time we're not so sure there's always a Promotion on it.

Section Page template

So, we won't use the Promotion template as a base for our Page Template itself. But you can of course, still add a promotion to your Presentation Details and set a Datasource for it. And so on.

See what I'm getting at? It doesn't really matter. You can create a hundred Page Templates if you want (you probably shouldn't) - and if there are certain types of pages in your solution that would need to be under Workflow? Well then you make "thick" Page Templates, like I just did here.

Do you have other types of pages that need to be as flexible as possible - an almost blank "canvas" for your editors to roam freely in? Well then make a thin one. Possibly not inheriting from anything other than maybe MetaHead, Header and Footer.

Need some pages to enter a translation flow? Inherit from the components that are part of this flow, and make a Page Template for that.

My point is; it doesn't really matter so much. As long as you're using solid implementation practices - you can freely mold your Information Architecture to suit your requirements. And not a single line of code in your solution should need to be changed in this process.

Which, I'm guessing, is the primary reason you're asking this question at all.

5
  • If I'm not mistaken, this is also the similar design approach that Habitat took, correct? Great answer Mark! Love the indepth background information. No Information Hiding here! Commented Oct 28, 2016 at 3:51
  • Mmmmhmmmm. Just like Helix. If I had to explain this in a TL;DR fashion: UI components should have a 1-to-1 mapping to respective data templates. And now you essentially have two vessels to bind the two: (1) inherit the component templates (contracts) from higher level page templates assuming you have good code (explicit data source or context item fallback) and it will render; or (2) as an author, manually set an instance of the component template (a data source item) as the explicit data source to the UI component. Commented Oct 28, 2016 at 18:50
  • Yep, I'd say that's a pretty accurate TL;DR :-) I have yet to study all of the Helix Documentation in minute detail to see if my approach significantly differs. I doubt it does. A further benefit from this approach is; you can run development on all components in parallel - long before you have full IA in place
    – Mark Cassidy
    Commented Oct 28, 2016 at 21:47
  • This is a great post, and I agree that you can use your interface templates on your page templates if you only have one rendering per page, as soon as you have more than one, this breaks down (assuming you want the content to be different). But doesn't take away from the fact, that your renderings should focus on the data source first. Commented Jan 31, 2018 at 18:08
  • Yes. But in my experience, the only truly "dynamic" part of a page is in what you could call the "general content area". Most pages will have a set of components that are global in nature. Top Navigation, Footer, Breadcrumb and so on. You can comfortably stick these on page level or go a bit further (which is also part of my Datalift project) and have them operate as "Datasource Or Site Root Item". Main point is, however, that none of this belongs in the component code - these are site and IA level concerns - which should be isolated from your component.
    – Mark Cassidy
    Commented Feb 1, 2018 at 8:13
8

Some concerns that I always take in to consideration when designing architecture and templates, and where the content should live.

  • Reusability - Is this content going to be used on more than one page? Some examples such as call to action boxes, focus areas, blurbs, descriptive copy about categories in the site, and so on. If the content is likely to be specific to the page and only the page, I tend to put it on that page's template. If not, I will consider making it a datasouce bound template.
  • Consideration for the Content Editor - How is a content editor going to consider this content? For example, will a content editor want this type of content on every page of this template, or discriminently here and there? When encountering something that may be optional (for a product page, for example, maybe an example video): I'll tend to make that a seperate template databound.
  • Personalization - Is this content likely to be visible/hidden/different based on a personalization facet I'm considering for this site? Perhaps I will hide e-mail sign up content if I know a user is logged in. Making these seperate components will make it easier to customize and replace the individual databound component rather than varying the whole page. (This also should be considered for multivariate testing: much easier to test a databound component than create and manage multiple page tests).
  • Globalization/Localization/Translation - Is this content something I would want different for segments of the population based on language, region or locale? I will usually put that content on it's own template.
  • Layout Considerations - Should the content always be in the same place on every page of that template? Should it take the same format? We sometimes would keep some content in a reusable data template independent of the page to make it easier for content authors to switch compatible renderings on the same content.

This is not an exhaustive list, just what I had top of mind! Looking forward to others thoughts here.

-1

The first aspect I would look at is what happens to the content if only the context item is published.

If the field is essential to the context item (eg. article content on the news page or price on the product page), then it should always be published along with the item.

In other words if the content comes from datasource and only the context item is published does the context item still makes sense?

Another case is reusability of the content.

Obviously if the content will be reused across the site it makes a good candidate to be stored in the datasource. That way it is possible to avoid content duplication and it helps to manage the content.

However there might be a case when the field can be used on a context item and as a datasource.

For example if there is a product page, the price of the product belongs to the context item but on the promo box the same product item can be reused as a datasource to keep the content consistent.

1
  • "If the field is essential to the context item...then it should always be published along with the item." I disagree with your "only the context item is published" argument. If you're using a structured modular approach to content, your may be using a series of discrete pieces of content (e.x. rich text, columns, accordion, forms) that are best represented as stand-alone items (with subitems even), but are also required for a given page to function appropriately.
    – zzzzBov
    Commented Oct 26, 2016 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.