Constellation.Foundation.Datasources is an opinionated Information Architecture framework for Sitecore. This library ships with a small set of Sitecore Data Templates along with some Rules and Rule Actions to enforce the Information Architecture provided.
This particular data architecture approach is extremely common, having evolved separately at many Sitecore partners as one of the more efficient and flexible ways to organize content. (SXA, for example, uses a similar setup) Constellation’s approach is not explicitly compatible with other similar approaches. It can be bootstrapped onto them with a minimum of hassle to ensure cross-compatibility.
Key Taxonomy Concepts
Constellation.Foundation.Datasources helps you organize your content tree in a manner that complements the Sitecore Experience Editor. This strategy provides the following benefits:
- Easier to find and filter content programmatically based on context and semantics.
- Easier to configure Renderings with context-sensitive datasource paths.
- Explicitly defines what Items constitute “Pages”; and therefore identify them as Items that have browsable URLs and Presentation Details.
- Explicitly defines whether content is intended to be “shared” across pages and/or sites.
This is achieved by having user-defined Data Templates inherit from “flag” Templates that represent the following key semantic concepts:
Items that inherit from “Context Datasource” are meant to represent traditional “Web Pages” in the content management system. Anything that is a “Context Datasource” should implicitly be expected to support the following:
- Item must have a URL that can be put into a browser and resolved by Sitecore’s HttpRequestPipeline via the Item Resolver step.
- Item must have Presentation Details, and support for Placeholders, Sublayouts, and Renderings.
- Item must be loadable and editable in Experience Editor.
The above does not exclude alternative delivery options. Explicit support for Sitecore’s Device output is implied. For example, Context Datasources should generally be compatible with JSS without breaking any of the rules defined here.
Items that inherit from “Subcontent Datasource” are meant to represent page fragments where the content of the fragment is unique to a given URL and is not intended for re-use.
In practice Subcontent Items are intended to be explicit datasources for subscribing Renderings, These Items are created when a given Rendering is added to the page.
The exclusivity of the datasource is the key fact.
Take the example of a photo gallery installed on a landing page. Although the photos may be re-used on multiple pages, the gallery itself is unique to the page and would not appear elsewhere. The gallery is a Rendering, which needs, an Item that allows the user to select Images (and maybe provide a heading and bracketing text). That Item would be a Subcontent Datasource, because it would be exclusive to that Rendering instance, as defined on the hosting Landing Page.
To help visually identify exclusivity, Subcontent Items should be stored in a “subcontent” folder that is a child Item of their hosting page Item. The includes rules to achieve this are detailed later in this document.
Items that inherit from “Widget Datasource” are meant to represent page fragments that can be shared across multiple pages, and possibly multiple sites.
In practice Widget Items are intended to be explicit datasources for subscribing Renderings, where the Widget Items are stored in a centralized location specifically to facilitate sharing.
A textbook example is a call-to-action or advertisement card. This card may appear on the Home Page, any appropriate landing pages, and on relevant product details throughout a given site, as well as on the company’s regional sites. (The widget will be translated). Wherever it appears, the same content is to be displayed, although there may be a few Rendering variants to “spice up” the design options. The Item representing the content for the card (the Widget) is stored in a ~/widgets/ads folder near the root of the Content Tree to permit users who typically edit only one site to see the Items and assign them to Renderings when building pages.
Architectural Impact of this Approach
In Helix/SXA fashion, this semantic model favors a page-centric approach to the content tree, where tenants have sites and sites have pages. The content tree will usually accurately reflect the URL structure as viewed by search engines and site visitors.
Sitecore “pages” will tend to consist of a page Item that contains very little content beyond presentation details. Instead the visible content will be collated from a small collection of “Subcontent” Items below the page Item in the content tree.
Renderings should favor the assignment of a Datasource Item rather than dynamically retrieving content to be displayed. This serves several purposes:
- Datasources can be adjusted by content authors using Sitecore’s Personalization rules or A/B testing.
- Renderings have content that can be easily isolated via Workflow and Publishing Restrictions.
- Renderings can be cached by Datasource, allowing for more predictable publication and cache clearing.
Developers should favor renderings that have a fixed, explicit appearance and source content. Avoid “chunkier” renderings that radically change appearance via presentation-specific fields on the Datasource Item. Use Rendering Variants and bury the presentation settings in Rendering Parameters instead. This forces the rendering thumbnails to accurately represent the Renderings being added to the page and keeps content semantically discrete from presentation concerns.
A good rule of thumb: If you would need more than one thumbnail to represent the rendering, it needs to be split into discrete Rendering Definitions, and it may need to be split into unique Renderings in code.
Subcontent and Procedural Navigation Generation
Because “Subcontent” is stored below its hosting Page in the content tree, it is (by default) available for editing by any Author that has read/write permission to that page. if this needs to be further restricted, the page fragment in question should probably be a “Widget” with its own repository folder, with appropriate security restrictions.
Automatic navigation rendering components will need to be built to look for the “Context Datasource” template inheritance when crawling the Site to establish links to other pages. This will prevent navigation from accidentally picking up subcontent storage folders, or even subcontent Items themselves.
Constellation.Foundation.Datasources includes Data Templates, Rule Conditions, and Rule Actions.
- Context Datasource
- Subcontent Datasource
- Supports Subcontent
- Widget Datasource
The purpose of each has been discussed above, with the exception of “Supports Subcontent”. This particular Template is typically paired with Context Datasource on a given customer’s “Page” template definitions. The existence of this template in a given Item’s inheritance is used to force the creation of a “subcontent” folder below the Item in question, for storing a page’s local datasources.
The following Rule Conditions are added to the Item Information rule options:
- Item is Context Datasource
- Item is Subcontent Datasource
- Item is Widget Datasource
- Item Supports Subcontent
These conditions are pretty self-explanatory. They will inspect the complete template inheritance hierarchy of the Item in question to determine if it inherits the correct flagging template (as described above).
You can use these conditions to perform actions based on the semantic type of the Item. For example: On Item:Saved, one could lowercase the Item.Name if the “Item is Context Datasource”.
The following rule action is added to the Item Information rule options:
- Create Subcontent Folder
This action can be used to create a rule such as the following:
On Item:Saved, if the Item path starts with “/sitecore/content” and the Item “Supports Subcontent”, then “Create Subcontent Folder” (if one does not exist)
This rule is essential to content tree management as it ensures that all “page” Items get a place to put their Subcontent datasources.
Constellation.Foundation.Datasources is managed via NuGet.
In Visual Studio, fire up the Package Manager console and install into any of your Sitecore projects:
PM> Install-Package Constellation.Foundation.Datasources
Run your local build & deploy process and restart Sitecore. This will ensure that the supporting Sitecore Items required by this library are installed on your system.
Source code available on GitHub.
After downloading and deploying this library, you’ll need to consider the following in this order:
Assign “Context Datasource” and “Supports Subcontent” Data Templates to your project’s “Page” content types.
Create a rule that generates “subcontent” folders for each instance of your project’s “Page” content type in your system. This is done by adding a new Rule at /sitecore/system/Settings/Rules/Item Saved/Rules
For page fragments (Renderings), decide if each fragment’s datasource is a “Subcontent” or “Widget” type and assign the appropriate base Data Template.
For “Subcontent” type renderings, set the “Datasource Location” field value to “./_subcontent” This ensures that when the Rendering is added to the page, its matching content Item will be placed under the current page in the content tree.
For Widget-type Renderings, establish a location in the content tree to store that Rendering’s datasource Items, and set the Rendering Definition’s “Datasource Location” field to that location.
Consider your workflow strategies for Subcontent and Widgets. Want to inspect the Rule Conditions yourself, Check out the source code available on GitHub.