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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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.