Creating column layouts using SDL Tridion

One of the things that developers new to the SDL Tridion templating language struggle with is the creation of web-page layouts that are built up using rows and columns of content.  I hope this short post shows a simple way to built this logic into your SDL Tridion layouts.

The screen shot below (taken from one of my colleagues’ favourite websites)  demonstrates the type of scenario that requires implementation.

Web-page content above is displayed using two rows of content laid out in a 3-items-per-row display.  These items are individual Component Presentations (a component spliced with a component template) and placed into the page.

How to do it

The process is actually really simple you need to do just a couple of things:

  • Separate the Component Presentations on the page by their ‘type’ (Component + Component Template equals a ‘type’)
  • Add a little bit of DWT logic to provide the row formatting
  • That’s pretty much it!!

Separating out the Component presentations

Separating out Component Presentations probably needs a post on it’s own.  Fortunately Dominic Cronin has taken care of this for me, so if you’re unsure about how to partition your page component templates read Partitioning Component Presentations over on his recipe website.

So assuming you’ve got a building block to partition your components, the package in your page will look something like this:

Why do they need to be partitioned?

When you loop over your component presentations, it makes life much easier to calculate when a row ending needs to be placed if they are split into partitions.   If you look again at the graphic below you’ll see that the components we need to display in a column layout (the Profile Intro components) start in this page from component number 2.

By partitioning your components you have a nice set of divided presentations to work with.

The required HTML

Going back to the layout, you need to produce a bit of HTML similar to the following:

Essentially the third sub <div> in this list has the CSS class ‘product-last‘, which contains some additional code to the ‘product‘ class to ensure the intro component is displayed on a new line.

The DWT code

The Page Template DWT code will render all of the Profile Intro Component Presentations by simply looping through the ‘partitioned’ components in the package, for example:

<!-- TemplateBeginRepeat name="ProfileIntroComponents" -->  @@RenderComponentPresentation()@@<!-- TemplateEndRepeat -->

So to add our extra <div> items and specifically the <div class=”product”> on the third Component Presentation we simply add a bit of logic into our DWT:

<!-- TemplateBeginRepeat name="ProfileIntroComponents" -->
 <div class="product<!-- TemplateBeginIf cond="((TemplateRepeatIndex+1) % 3 == 0)" -->-last<!-- TemplateEndIf -->">
<!-- TemplateEndRepeat -->

The main thing you need to know about the code modification is this line:

<!-- TemplateBeginIf cond="((TemplateRepeatIndex+1) % 3 == 0)" -->

This code statement is essentially counting as we go through the Component Presentations, when we get to one that is divisible by 3 with no remainder (essentially a third component) render out the bit of code -last onto the div tag.

Finally a couple of tips:

  • Be aware that the TemplateRepeatIndex starts at 0
  • Be aware of white space in your code which can give problems in your final HTML output.

If anyone has other ways to achieve these grid like layouts, let’s use the comments below to start a discussion :)

9 thoughts on “Creating column layouts using SDL Tridion

  1. Good post, I have seen this type of trick needed all the time in implementations I have worked on. I have to say though that if the HTML design good then this should not be needed at all. By good, I mean that the HTML contains semantics only and no layout (which is left to the CSS). In your case the set of spice girls should be a list: Something like

    Scary Spice
    Posh Spice
    Ginger Spice
    Sporty Spice
    Baby Spice

    And the CSS something like this:

    ul {width:900px;list-style-type: none;padding:0px;margin:0px;}
    li {float:left;width:300px;}
    li div {width:300px;}
    li div img {width:300px;}

    This method also is much more in line with that topic of the moment – Responsive Design, whereby you can support many different screen widths (ie devices) from a single HTML design.

  2. Crap, my HTML list was escaped, I meant:

    <li><div><h2>Scary Spice</h2><img src="scary.jpg"/></div></li>
    <li><div><h2>Posh Spice</h2><img src="posh.jpg"/></div></li>
    <li><div><h2>Ginger Spice</h2><img src="ginger.jpg"/></div></li>
    <li><div><h2>Sporty Spice</h2><img src="sporty.jpg"/></div></li>
    <li><div><h2>Baby Spice</h2><img src="baby.jpg"/></div></li>

  3. Hi Will,

    Yeah you’re right, I also prefer that the HTML/CSS just deals with the layout.

    My personal aim is to try and get the DWT’s to something that a HTML designer really can work with and that all they need to know is the syntax of adding content fields. I guess to be in that situation there needs to be some education around ‘what works better when integrated into DWT’ perhaps a good idea for a future post, your HTML/CSS example should be on that list.

  4. Well, its close although perhaps Baby Spice would rank a bit higher… but yes you are right, a list of considerations to make the transition from HTML Design -> DWT easier would be a good subject. I am very much of the opinion that doing workarounds in DWTs to cope with bad HTML design is the wrong approach – you will end up with messy and unmaintainable TBBs – better to fix at source in the HTML Design. Unfortunately the budget holders and PMs don’t always have this kind of long-term vision on the typical stress-ball project. I have some guidelines somewhere, I will dig them out and post them next month.

  5. Thanks to Will for pointing back to this nice post and discussion.

    I now often tag every Component Presentation with the TemplateRepeatIndex too.

    <ul id=’spicegirls’>
    <li class=’spicegirls0′>Scary Spice</li>
    <li class=’spicegirls1′>Posh Spice<</li>
    <li class=’spicegirls2′>Ginger Spice</li>
    <li class=’spicegirls3′>Sporty Spice</li>
    <li class=’spicegirls4′>Baby Spice</li>

    That allows you to latch onto those indexes in case you need to put a hard break in there:

    li.spicegirls3 { clear: both; }

    Of course it is best to stick to fluent layouts like Will does. But this index trick gives you a way to keep the layout choice (“I need a break here”) in the CSS, without adding additional requirements on the HTML.

  6. Nice example and discussion. For rows/columns on more text-heavy content, I like applying the same to schema fields and component templates.

    For example, the classic “paragraph” embedded schema lends well to a similar approach.

    Embedded_Paragraph (use as a repeatable embedded schema):
    – Subheading
    – Text (repeatable)

    Then in our template logic we can wrap fields with divs and class attributes as needed. Repeated text could be column whereas repeated Embedded_Paragraphs could be new rows. Alternatively, we could push this logic “up” one level to have CPs become rows and repeated Embedded_Paragraphs as columns. At this point, we might also reconsider calling these “Paragraphs.” :-)

    One other option for the class names, similar to Frank’s example, you could auto-generate class names, but consider adding separate classes (e.g. class=”someclass first” or class=”someclass pos1″). This might apply if design follow an “object-oriented css” approach.

  7. Can any one help me in creating Responsive Email Template via Tridion ? We can able to do this in Normal HTML template via media query. But, In Tridion my classes are getting deleted, When I am publishing the template.

    Please help me out :-(

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>