Skip to main content
Version: 2.8

Using velocity templates

This page provides request body examples how to use REST services related to using templates. Currently, the following services are available:

  • Apply template /tribefire-services/api/v1/access.adx.content.default/v1/convert/apply-template
  • Merge templates /tribefire-services/api/v1/access.adx.content.default/v1/convert/merge-templates

Both of these endpoints only require a sessionId (see Authentication and session handling in Document.One) and a request body with JSON data structure containing the following items:

  • Template specifications
  • IDs of the templates you work with (note that in D1 2.x templates are treated as any other contents, hence the contentId in the examples below)
  • Information about action to be performed (resultAction - either NEW_CONTENT or CONTENT_REPRESENTATION)

See the examples below to get an idea of how the request body could look like.

Templates

Examples shown later in this page are based on the following Velocity templates, which you can copy to a text editor, save as .vm file, and upload to Document.One (D1):

Simple template with one variable (let's call it simple.vm):

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>D1 template</title>
</head>
<body>
Hello ${replacement}!
</body>
</html>

More complex template with a for loop (let's call it loop.vm):

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Complex D1 template</title>
</head>
<body>
$simple
#foreach( $entry in $list.getValues() )
<li>$entry.get("name")</li>
#end
</body>
</html>

Template specification for text replacement

Use the JSON snippets below to develop your own text replacement body.

Text replacement Apply template

This is an example of a request body where the source template has one variable replacement. When you send the request below to /apply-template, a new document called D1 template will be generated, with Replacement text being assigned to replacement and rendered in the document.

{
"contentId": "simple-vm-ID-goes-here",
"templateSpecifications": [
{
"variables": {
"replacement": "Replacement text"
}
}
],
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "D1 template"
}

Text replacement Merge templates

When you send the following request body to /merge-templates endpoint, two templates (identified by contentIds array) are merged into a new document. replacement variable in both templates is replaced by Replacement text.

{
"contentIds": ["simple-vm-ID-goes-here", "simple-vm-ID-goes-here"],
"templateSpecifications": [
{
"variables": {
"replacement": "Replacement text"
}
}
],
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "Merged Template"
}

Template specifications with map records

These examples show how to use template specifications with a map record, which bundles multiple variables.

Apply template

Examples below demonstrate how you could work with simple.vm and loop.vm via the /apply-template endpoint.

Simple template

When we send the following request to /apply-template, target document will be rendered from simple.vm:

{
"contentId": "simple-vm-ID-goes-here",
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "D1 template",
"templateSpecifications": [
{
"mapRecord": {
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"replacement": "D1 replacement text"
}
}
}
]
}

Loop template

When we send the following request to /apply-template, target document will be rendered from loop.vm:

{
"contentId": "loop-vm-ID-goes-here",
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "D1 template",
"templateSpecifications": [
{
"mapRecord": {
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"simple": "D1 templates",
"list": {
"_type": "com.braintribe.model.record.ListRecord",
"values": [
{
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"name": "D1 templates loop value 1"
}
},
{
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"name": "D1 templates loop value 2"
}
}
]
}
}
}
}
]
}

Merge template

Examples below demonstrate how you could work with simple.vm and loop.vm via the /merge-templates endpoint.

Simple template

This request will merge two simple.vm templates into one document.

{
"contentIds": [
"simple-vm-ID-goes-here", "simple-vm-ID-goes-here"
],
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "D1 template",
"templateSpecifications": [
{
"mapRecord": {
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"replacement": "D1 replacement text"
}
}
}
]
}

Loop template

This request will merge two loop.vm templates into one document.

{
"contentIds": [
"loop-vm-ID-goes-here","loop-vm-ID-goes-here"
],
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "D1 template",
"templateSpecifications": [
{
"mapRecord": {
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"simple": "D1 templates",
"list": {
"_type": "com.braintribe.model.record.ListRecord",
"values": [
{
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"name": "D1 templates loop value 1"
}
},
{
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"name": "D1 templates loop value 2"
}
}
]
}
}
}
}
]
}

Nesting and back-linking velocity templates

Document.One (D1) enables you to nest velocity templates inside each other. This allows to you import templates into other ones before the original template is evaluated. You can also import images.

When nesting templates, be aware of the following:

  • ContentIDs of imported templates and images are defined in the JSON body of the /merge-template request.
  • Both the imported templates and the images must be contents in your D1 repository.

Directives

The following table shows the main directives.

DirectiveDescription
<<doc [context.openRemoteResourceByRefEval("path")] >>Inserts the content of the resource identified by the path.
<<doc [context.openRemoteResourceById("accessId", "resourceId")] >>Inserts the content of the resource identified by the actual access ID and resource ID.
<<image [context.openRemoteResourceByRefEval("path")] >>Inserts the specified image in Base64-encoding in the form data:_imageMimeType_;base64,_theActualImageDataEncodedInBase64_.
<<image [context.openRemoteResourceById("accessId", "resourceId"))] >>Inserts the specified image contained in the resource identified by the actual access ID and resource ID.
NOTE

If the access ID is blank, the default access ID (which is the access ID where the original template is stored) is used.

NOTE

The path denotes the location within the input JSON's mapRecord. If you need to access deeper structures within the mapRecord, you can use multiple path elements separated by ->.

Importing mapRecords into TemplateSpecifications

D1 enables you to import mapRecords into a TemplateSpecification. This is helpful when you want to use the same mapRecord in more than one request, for example. To import a mapRecord, use the mapRecordImports property inside your template specification.

NOTE
  • If the main template specification contains a key with a value different from the value of the same key inside the mapRecordImports, then the value in the main template specification takes precedence.
  • You can import more than one mapRecord.

Try it out in OpenAPI

Simple and loop templates

  1. Log in to D1.

  2. On the landing page, click the API link under repository where you want to use template services:

    The OpenAPI page opens.

  3. Consider switching to Swagger 2.0 before executing requests it is more mature than OpenAPI, which is still in experimental phase.

  4. Expand endpoints under Conversion. You will find both /apply-template and /merge-templates.

  5. Click Try it out! to activate the fields.

  6. Paste your template specification into the Request body field.

  7. Click Execute and check the response. You should get the job duration in the response, and your service should be executed. Check D1 Explorer to verify that your content was indeed rendered or merged.

Nesting templates

To follow this example, do the following:

  1. Upload ParentTemplate.vm, Import1.html, Import2.html, and an image to your D1 repository.
  2. Find the /tribefire-services/api/v1/access.adx.content.default/v1/convert/merge-templates endpoint in OpenAPI > Merge templates.
  3. Copy the JSON Body and replace the contentId with the write ID of your contents.
  4. Run the request. The result is a new content called html-template-test.

ParentTemplate.vm

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Parent D1 template</title>
</head>
<body>
<h1>Test template IMPORT1<h1/>
<<doc [context.openRemoteResourceByRefEval("IMPORT1")] >>
<hr />
<<doc [context.openRemoteResourceByRefEval("IMPORT2")] >>
<br/>
An image: <<doc [context.openRemoteResourceByRefEval("IMAGE")] >>
</body>
</html>

Import1.html

Import2.html

This is the  content of "import2.html"
Importing import3: <<doc [context.openRemoteResourceByRefEval("IMPORT3")] >>

Import3.html

In the year of ${year}.

JSON body

{
"contentIds": [
"d4062fce-cd7b-4659-9252-750d0bb940d3"
],
"priority": 0,
"resultAction": "NEW_CONTENT",
"targetName": "html-template-test",
"templateSpecifications": [
{
"mapRecord": {
"_type": "com.braintribe.model.record.MapRecord",
"values": {
"year": "2020",
"IMPORT1": {
"_type" : "tribefire.adx.model.content.service.v1.request.conversion.ContentReference",
"contentId" : "b800cc84-f210-4b3d-84d0-1e47ac682936"
},
"IMPORT2": {
"_type" : "tribefire.adx.model.content.service.v1.request.conversion.ContentReference",
"contentId" : "18d7a885-ae63-4929-a6c9-be27a8652fcc"
},
"IMPORT3": {
"_type" : "tribefire.adx.model.content.service.v1.request.conversion.ContentReference",
"contentId" : "59f4ad63-7a7a-445f-a6cc-4d6dfb2f40ca"
},
"IMAGE": {
"_type" : "tribefire.adx.model.content.service.v1.request.conversion.ContentReference",
"contentId" : "2388c9ab-94b1-4d3c-b1c8-f5ce8abe5db9"
}
}
}
}
]
}

OpenAPI

For code samples, see

Apply template by ID
Merge templates by IDs