Getting Started

Release 1.0 - ...

Placeholders are stateful containers which can be filled with data from other places in the SXML document. The Placeholder macro declares a named container. From that point, you can manipulate its data using the PlaceholderData macro and a rich set of Viper methods.

A placeholder can be seen as an empty datatable with one or more columns and no rows. Being a datatable means implicit that the rich formatting options apply to this macro as well. If no formatting parameters are declared, the rendered placeholder will return a string represention of the content of the first column.

Placeholders are useful containers decreasing the amount of queries performed.

Creating a placeholder

When the Placeholder macro is used without any further parameters a datatable with just one column is defined:

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder" />

A more complex datatable is created using the fieldnames parameter. With this parameter the different columns of the datatable are declared

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder" fieldnames="Nr, Title" />

Since multiple columns are created, formatting should be applied to this container. Else, only the first column, the Nr column, is displayed in the output.

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder" fieldnames="nr,title" 
 rowformat="{this.field(title)} ({this.field(nr)})" rowdelimiter=", " />


The columns of the datatable, declared by the fieldnames parameter, can be strongly typed as well

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder">
 <se:parameters>
  <se:parameter name="fieldnames">
   <se:collection>
    <se:member name="nr" type="integer"></se:member>
    <se:member name="title" type="string"></se:member>
   </se:collection>
  </se:parameter>
  <se:parameter name="rowformat">{this.field(title)} ({this.field(nr)})</se:parameter>
  <se:parameter name="rowdelimiter">, </se:parameter>
 </se:parameters>
</se:placeholder>

Adding data to a placeholder

Once a placeholder is created, data can be added to the container using the placeholderdata macro, the placeholder viper or by page extension vipers

Smartsite SXML CopyCode image Copy Code
{placeholder.add('myplaceholder,'1', 'hello world')}
{page.myplaceholder.add('1','hello world')}

This can be done from whitin another macro as well:

Smartsite SXML CopyCode image Copy Code
<se:xlinks parent="2" rowformat={placeholder.add(myplaceholder,this.field(nr),this.field(title))}" />
 
<se:xlinks parent="2">
 <se:parameters>
  <se:parameter name="rowformat">
   {placeholder.add(myplaceholder,this.field(nr),this.field(title))}
  </se:parameter>
 </se:parameters>
</se:xlinks>

Managing Duplicates and order your data

Adding data to your placeholder might include duplicates. The Placeholder macro has the IgnoreDuplicates parameter to skip these duplicates. Each field within a placeholder can be marked as primary key. If no primary keys are defined, duplicates are rows containing exact the same data in each field:

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder" ignoreduplicates="true">
 <se:parameters>
  <se:parameter name="fieldnames">
   <se:collection>
    <se:member name="nr" type="integer"></se:member>
    <se:member name="title" type="string"></se:member>
   </se:collection>
  </se:parameter>
  <se:parameter name="rowformat"><li>{this.field(nr)} - {this.field(title)}</li></se:parameter>
  <se:parameter name="resultformat"><ul>{this.result()}</ul></se:parameter>
 </se:parameters>
</se:placeholder>
  
{placeholder.add(1, 'hello world')}
{placeholder.add(1, 'hello world')}
 
1 - hello world

The next example uses the same placeholder. Because the rows are different, both rows are added to the placeholder:

Smartsite SXML CopyCode image Copy Code
{placeholder.add(1, 'hello world')}
{placeholder.add(1, 'hello moon')}
 
1 - hello world
2 - hello moon

However, if the primary key is set to the Nr column, the previous example will return one row again:

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder" ignoreduplicates="true">
 <se:parameters>
  <se:parameter name="fieldnames">
   <se:collection>
    <se:member name="nr" type="integer" primarykey="true"></se:member>
    <se:member name="title" type="string"></se:member>
   </se:collection>
  </se:parameter>
  <se:parameter name="rowformat"><li>{this.field(nr)} - {this.field(title)}</li></se:parameter>
  <se:parameter name="resultformat"><ul>{this.result()}</ul></se:parameter>
 </se:parameters>
</se:placeholder>
 
{placeholder.add(1, 'hello world')}
{placeholder.add(1, 'hello moon')}
 
1 - hello world

If the title field is set to be a primary key as well, the example above will return two rows again. In that case, rows added to the placeholder should match both columns before they are marked as a duplicate.

Where to render

A placeholder is a container which should be created before you can add data. The placeholder have to be defined at the top of your rendertemplate, or better, at a high level in the SXML stack. However, this is most often not the place you want to display the data. The parameter render=false delays the rendering of the placeholder. The vipermehtod placeholder.render() can be used to render the content of the container.

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="myplaceholder" fieldnames="nr,title" 
 rowformat="{this.field(title)} ({this.field(nr)})" rowdelimiter=", " render="false" />
 
{placeholder.render(myplaceholder)}

Benefits

The benefits of placeholders is that they can reduce the amount of queries performed. Assume a placeholder named SeeAlso is created. Based on different criteria each macro can add data to this placeholder; an sqlquery macro adds the top 1 based on moddate, an XLinks macro adds the first three children, an itemdata macro adds references based on a seealso field in a contenttype, etc.

Another benefit is the delivery of proper XHTML. If a single page uses a special CSS or JavaScript include, this can be added to a placeholder Includes from, for example, the logic field of that single item.

Smartsite SXML CopyCode image Copy Code
<se:placeholder id="includes" />
 
<se:placeholderdata targetid="includes">
 <link rel="stylesheet" type="text/css" href="{channel.link(CSS_FORTHISITEMONLY)}" />
</se:placeholderdata>

Because this is a very useful approach, mandatory placeholders for CSS and JavaScript includes are defined within the Smartsite.config.