Getting Started
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 |
|
|---|---|
<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 |
|
|---|---|
<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 |
|
|---|---|
<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 |
|
|---|---|
<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 |
|
|---|---|
{placeholder.add('myplaceholder,'1', 'hello world')}
{page.myplaceholder.add('1','hello world')}
|
|
This can be done from whitin another macro as well:
| Smartsite SXML |
|
|---|---|
<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 |
|
|---|---|
<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 |
|
|---|---|
{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 |
|
|---|---|
<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 |
|
|---|---|
<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 |
|
|---|---|
<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.