Multi-column layouts with Roxen and XSL

2008-10-21, 16:00 by Tobias Liin in RXML/XSLT

As a web developer working with Roxen, you often need to make components render in different columns on the site, which may seem difficult since there is no column concept in the component editor. You may also want page layouts to vary from page to page, on one page you might want to use the full width of the page to render the content, but on another page you want two columns where the content column is a bit smaller to make room for a right column. There are many different ways to accomplish this, and the best way to do it depends on the requirements.

One way to do it, that I like personally, is to use pre-defined variant intervals. This will allow the page layout to vary automatically with the type of component inserted on the page, without having to treat each component specifically or make any modifications to the main XSL code when adding new components.

Lets say you have a site with two different possible layouts, one or two columns. Some components are supposed to be used in any of the columns, some only in the left and some only in the right column. So you specify variant intervals:

  • variant 0-99: renders in left column
  • variant 100-199: renders in right column
  • variant >= 200: not supported (open for future changes)

Now, in your templates you have the possibility to look for different variant intervals to determine the page layout:

  • If there is at least one component with a variant 100-199 the page layout is two columns
  • If not, the page layout is one column

So, you could have a template that determines the page layout for the current page:

<xsl:template name="page-layout">
  <xsl:choose>
    <xsl:when test="//*[variant &gt;= 200]">
      <xsl:text>unknown</xsl:text>
    </xsl:when>
     
    <xsl:when test="//*[variant &gt;= 100 and variant &lt; 200]">
      <xsl:text>2-column</xsl:text>
    </xsl:when>
     
    <xsl:otherwise>
      <xsl:text>1-column</xsl:text>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>

Now you can use the proper HTML and CSS to create the desired page layout. If you want, you could also provide the page layout in an XSL parameter when applying the templates, if you want components to be able to behave differently depending on the page layout E.g like this:

<xsl:variable name="page-layout">
  <xsl:call-template name="page-layout"/>
</xsl:variable>

<div class="page-container">
  <xsl:choose>
    <xsl:when test="$page-layout = '1-column'">
      <div class="content-full-width">
        <xsl:apply-templates>
          <xsl:with-param name="page-layout" select="$page-layout"/>
        </xsl:apply-templates>
      </div>
    </xsl:when>

    <xsl:when test="$page-layout = '2-column'">
      <div class="content-left">
        <xsl:apply-templates select="//*[variant &gt;= 0 and variant &lt; 100]">
          <xsl:with-param name="page-layout" select="$page-layout"/>
        </xsl:apply-templates>
      </div>

      <div class="content-right">
        <xsl:apply-templates select="//*[variant &gt;= 100 and variant &lt; 200]">
          <xsl:with-param name="page-layout" select="$page-layout"/>
        </xsl:apply-templates>
      </div>
    </xsl:when>

    <xsl:otherwise>
      <strong>Unsupported component kombination</strong>
    </xsl:otherwise>
  </xsl:choose>
</div>

As stated above, there are a lot of different ways to handle multiple columns and this is only one way to do it. The idea is very simple: let the components inserted on the page decide the page layout, without having to make assumptions for specific components. Instead we use variant intervals to make positioning and the choice of page layout generic among all components, old as well as future ones.
 

 

You need to log in to post comments.

 

1   Pontus Östlund

2008-10-23 15:48

I've been thinking about this a few times. This is a good solution but it takes a lot of work to alter all variant stuff in all the component templates. I've been thinking about creating a "column component" that you can insert three instances of in a page:

1. variant 0: Begin columns 2. variant 1: Break (component between 0 and 1 goes left) 3. variant 2: End (components between 1 and 2 goes right)

Then in the main page layout see if there are any "column-components" and collect accordingly. This would also make it possible to specify the column widths in the component and all your other components variants would still be intact.

2   Tobias Liin

2008-10-23 15:54

Indeed, that is a good solution that I have also used. I did it slightly different though and used a "Column break" component, i.e one component to create two columns, two components to have three columns etc. The only problem I ran into with that was that the "Forms and response" components won't work, since it has its own templates that do the <xsl:apply-templates/> stuff. I worked that out to, but it was a bit of a hazzle.

3   Pontus Östlund

2008-10-23 17:48

My though with three separators is that you then can have full width content, then two column content, then full with content again. I guess with two separators the two column layout will have to stretch to the footer. But when I think about it its quite rare that you want e.g. 1 col width, 2 cols width, 1 col width. In those case it's probably easier to just hard code the column layout in the XML file ;)

Sep 23, 2017

Categories

HTML/CSS (1)
Pike (0)
RXML/XSLT (4)

Latest comments

My though with three separators is that you then can have full width content, then two column content, then full with content again. I guess with two separators the two column layout will have to stretch to the footer. But when I think about it its quite rare that you want e.g. 1 col width, 2 cols width, 1 col width. In those case it's probably easier to just hard code the column layout in the XML file ;)
Indeed, that is a good solution that I have also used. I did it slightly different though and used a "Column break" component, i.e one component to create two columns, two components to have three columns etc. The only problem I ran into with that was that the "Forms and response" components won't work, since it has its own templates that do the <xsl:apply-templates/> stuff. I worked that out to, but it was a bit of a hazzle.
I've been thinking about this a few times. This is a good solution but it takes a lot of work to alter all variant stuff in all the component templates. I've been thinking about creating a "column component" that you can insert three instances of in a page: 1. variant 0: Begin columns 2. variant 1: Break (component between 0 and 1 goes left) 3. variant 2: End (components between 1 and 2 goes right) Then in the main page layout see if there are any "column-components" and collect accordingly. This would also make it possible to specify the column widths in the component and all your other components variants would still be intact.