Dynamic layouts in Sitecore

20.07.2016 Miklas Bieberstein

This blog post is about the implementation of dynamic layouts in Sitecore. And yet two questions arise immediately:

What are dynamic layouts?
And why don’t they exist in Sitecore innately?

What are dynamic layouts?

The best way to explain what dynamic layouts are by differentiating them from static layouts:

Lets say we have an ordinary homepage, which is divided into different display areas. In reference to a classic text document there is, so-to-say, a header, a content area and a footer. Header and footer contain information that should be displayed on every page of the whole document. So, for a website that means contents, which always have to be visible. Usually those are things like the company name, the logo in the header area, links to the legal notice or a contact form in the footer area. The herein described global document structure represents the static parts of the layout.

The content area should be able to contain various content types such as text, images or charts. For this purpose, an additional spacial structure of the display area is necessary per page. A text document is flexible in this area: If you want to add a picture on page 3 you can do so easily. But contrary to the header and footer areas this picture will not appear on all pages of the document. This is the dynamic part of the layout. This generally refers to the area, where the breakdown is not set in stone during drafting times but only unfolds during the definite elaboration with contents. You know how important this differentiation is, when imagining creating the whole document on paper and being forced to draw the company logo on each page. This should make it clear, how important and useful the division in static and dynamic display areas is. 

And why don’t dynamic layouts exist in Sitecore?

To answer the second question regarding the absence of options for dynamic page design in Sitecore, firstly you have to generally look at how contents in Sitecore are displayed. First off, it is important to differentiate between the spacial proportioning of a page, so the layout on the one hand and the actual contents on the other hand. Generally, you initially define a grid of layout areas in which the actual contents are placed in the second step. For this purpose, corresponding place holders are defined in the layout, which can then be used for content types in Sitecore CMS. For the answer of the actual question the fact, that each of those space holders has its own identification and that those have to be obvious within the corresponding page, is crucial.

We would like to explain why this fact is the heart of the problem with a concrete example.

The ACME website

So let’s start with the implementation of the website for the fictional business ACME (A Company Manufacturing Everything). The scenario provides that several people with different roles create the website. There would be software developers, who realize the concept created by designers and therefore build the basis in which the editors of the corresponding business areas enter their contents. The fundamental layout grid follows the concept of header, content and footer areas mentioned above, merely completed by a navigation area.

The global layout

The global layout defined in Sitecore, which our website uses, refers to a respective .aspx file, in which place holders for the global elements are defined:

Graphic 1: Global Layout in Sitecore

Graphic 2: Place holder in Document.aspx

Those place holders are then filled with the corresponding contents in Sitecore CMS. Here, the key attribute serves as a clear key.

Graphic 3: Assignment of global elements

One requirement here is, of course, that the assignment to these content areas has to be done only once globally and not repeatedly for each page. This can be achieved through assignment on the level of standard values of the global page draft:

Graphic 4: Assignment of layout details on the level of standard values

I would like to note here that this solution reaches its limits when the inheritance hierarchy of the Sitecore templates exceeds two levels. We will discuss how to solve this problem in another blog post.

Now, additional pages of the ACME website that all use the global layout can get created and with that also all have the global elements, i. e. logo, navigation, etc.

Content area

Several sub layouts are defined for the content area, which each allow a specific combination of texts and graphics to present the strengths and goals of ACME. Eventually, even those sub layouts are static and the number of versions correlate 1:1 with the number of respective definitions in Sitecore, according to the underlying .ascx files. These sub layouts dont use place holders but show the contents of the respective Sitecore item directly by analyzing the according fields of the item. For this purpose, there are numerous tags in Sitecore that simplify this task. 

Graphic 5: Sub layout for the header element with logo and title

The editors of the various business departments should have the option, though, to design the content area flexibly and individually, but the existing sub layouts dont offer enough room for this. So, you begin to equip some of the sub layouts with additional place holders which can hold additional sub layouts. This way, it should be possible to increase the flexibility of the sub layout with nesting. Initially, this seems to work. Until an editor gets the idea to use the same sub layout twice within one page. This simply results in the fact, that not all contents display as expected.

After an extensive analysis you realize that, due to the fact that the key of the individual place holders within a page have to be clear, the assignments of the contents simply overwrite in the case of double keys. With the help of restrictions with the options of assignments to place holders (insert options) the problem could be bypassed, but the desired flexibility would still not be attained.

At this point it becomes clear that the problem can only be solved by interfering with the Sitecore layout system.

Dynamic layouts in Sitecore

To reach the desired flexibility with the page design, various sub layouts are defined, which each offer specific layout grids. Those should be able to be combined and nested within each other.

Graphic 6: Sub layouts with different numbers of columns

In order for the whole thing to work, all thats left to solve is the problem with double keys. And since we are dealing with dynamic layouts the solution is to make the key for the place holder dynamic as well.

The first step is a definition of a new place holder Controls, which replaces the existing place holders when dynamic assignments are necessary.

Graphic 7: Two-columned sub layout with dynamic place holders

With the help of the ID of the superordinate rendering the implementation generates a clear key for the place holder, with which the key attribute is then overwritten. 

Graphic 8: Automatically generates place holder key in the layout details

Additionally, you have to engage with the Sitecore rendering pipeline to make sure that e. g. the placeholder settings are adopted correctly. For this purpose, the generated key has to be used in its original form again

In the page editor you can now make a page dynamic to complete the required components and adjust the layout according to the requirements without having to create new sub layouts.

Graphic 9: First row of the two-columned layout in the page editor

The dialogue for adding new renderings makes the choice of previously created layout components possible. In this case the two-columned sub layout is added again:

Graphic 10: Selection of an additional layout component

And you receive a second two-columned row on the page:

Graphic 11: Two-lined or additional two-columned layout

This way, the layout can now be adjusted as desired.

There are a few blog posts regarding this topic in which various developers took to this very fundamental problem in Sitecore. So let’s not hide the fact that inspiration for the solution of the problem also came from the following sources: