Data 2 Documents includes a declarative template solution.
Specifying templates is optional, as content is already associated with HTML5 semantic elements and can be rendered on that basis, while further styling can be done using CSS. However, in order to gain more control over document rendering, d2d includes a declarative template solution. (Sub)templates can be nested in a single HTML file that loads and renders individually, to facilitate design.
One of the requirements for Data 2 Documents is to stay within official web standards as much as possible. There are many existing template languages and solutions, but most use imperative terms such as {{if}}
, {{then}}
and {{for}}
in order to express control over content placement. Other requirements are to have templates that can be loaded and viewed separately to facilitate easy web design, and the ability to nest sub templates in the same sense that sections of content are nested in the resulting document; By doing so, a template can contain multiple sub templates that together provide a complete mock-up version of the web document, optionally filled with sample content.
To meet these requirements a declarative template solution was developed for d2d. Templates can be expressed in HTML5 compliant XHTML (polyglot markup), which allows for adding the d2d namespace to the template and use special d2d template tags while staying within official standards. In principal, non-XML based HTML5 templates are also possible though technically speaking these would not be valid HTML5 documents due to the `unknown' template tags being present. However, browsers will skip the unknown tags when loading the template file separately, and in the resulting documents all template tags will be replaced.
The d2d template tags are:
- d2d:Template: Indicates the start and end of a (sub) template. Template tags and all their child elements will be removed from the resulting document. A Template tag can be placed within a Content tag to specify sub templates.
- d2d:Field: Indicates the placement of a content field. This tag can only occur within a Template tag and will be replaced by the actual content plus any optional HTML that is only placed if the field is present.
- d2d:Segment: Can be used to provide several alternatives to render multiple values for a particular field. For example, to render the first value in a different way or treat odd and even indexed values differently. This tag can only occur within a Field tag.
- d2d:Content: This tag can only occur within a Segment tag or directly within a Field tag. If specified, the Content tag will be replaced by the actual content, while any markup situated between the parent Field or Segment tag and the Content tag is regarded as optional content that is only placed if the field itself is placed. That is, if the Triple Specification for the field matched and selected a value. Within the Content tag, sample content can be placed to facilitate template design. As such, a nested sub template can also be specified within a Content tag.
Below are a several examples of the various ways the template tags can be used together.
Each 'template' consists of a d2d:Template
tag that can contain regular HTML code that is used to render the section or article, and one or more d2d:Field
tags that indicate the placement of the actual content within the HTML:
<d2d:Template>
<!-- Optional HTML; placed if article is placed -->
<d2d:Field />
<!-- Optional HTML; placed if article is placed -->
<d2d:Field />
<!-- Optional HTML; placed if article is placed -->
</d2d:Template>
A template can be specified as a literal value within a Render Definition
or in a separate template file that possibly contains multiple (nested) templates. In the former case, the d2d:hasTemplate
property of the Render Definition
has a literal value containing the template. In the latter case, d2d:hasTemplate
has a resource IRI as value, being the IRI of the template file. Templates embedded as literals are useful for small, additional templates while a separate file with nested templates facilitates easy Web design, because it allows a Web designer to create a complete page design separate from the data (compare our special example website with its separate main template file). Typically, template tags can be added after the complete design is finished. Because a template file can contain multiple (nested) templates, templates within such a file must indicate the Render Definition
they are for, using the d2d:for
property:
<d2d:Template d2d:for="http://Render-Definition-IRI" />
The fields within a template can be defined with varying options and levels of complexity. The most basic version is shown below; it simply gets replaced by the actual content:
<d2d:Field />
This more advanced version allows for conditional HTML, that is placed only if there is a value to be placed for the specific field. Here, the d2d:Content
tag is replaced by the actual field content:
<d2d:Field>
<!-- Optional HTML; placed if field is placed -->
<d2d:Content />
<!-- Optional HTML; placed if field is placed -->
</d2d:Field>
This is the extended version of a content field: It allows for conditional HTML and sample content that facilitates template design. The sample content between the d2d:Content
tags gets replaced by the actual content. As the sample content gets replaced, it can contain nested templates for nested articles or sections that would be placed as value for the particular field:
<d2d:Field>
<!-- Optional HTML; placed if field is placed -->
<d2d:Content>
<!-- Sample content; gets replaced -->
<!-- Can contain nested Templates -->
</d2d:Content>
<!-- Optional HTML; placed if field is placed -->
</d2d:Field>
This is the full version of a content field: It allows for multiple segments, conditional HTML and sample content. Using segments, a separate rendering can be defined in case there are possibly multiple values for a field. For example, in case a fiels contains a list of nested articles, a different rendering can be specified for odd and even articles:
<d2d:Field>
<!-- Optional HTML; placed if field is placed -->
<d2d:Segment d2d:matchRule="odd">
<!-- Optional HTML -->
<d2d:Content>
<!-- Sample content; gets replaced -->
<!-- Can contain nested Templates -->
</d2d:Content>
<!-- Optional HTML -->
</d2d:Segment>
<d2d:Segment d2d:matchRule="even">
<!-- Optional HTML -->
<d2d:Content>
<!-- Sample content; gets replaced -->
<!-- Can contain nested Templates -->
</d2d:Content>
<!-- Optional HTML -->
</d2d:Segment>
<!-- Optional HTML; placed if field is placed -->
</d2d:Field>
Field and Content tags get replaced in the order they appear in the template. Alternatively, you can specify an index to indicate a different ordering; the following example results in a field ordering of 1, 4, 2, 3 with respect to the order of the Field Specifications in the Article or Section Definition:
<d2d:Field />
<d2d:Field d2d:index="4" />
<d2d:Field />
<d2d:Field />
Field and Content tags can be nested within each other; the following example results in nothing being placed if a name is not specified, even if an age is specified for the resource acting as section or article:
<d2d:Field>
<p>
Name: <d2d:Content />
</p>
<d2d:Field>
<p>
Age: <d2d:Content />
</p>
</d2d:Field>
</d2d:Field>