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
orCONTENT_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.
Directive | Description |
---|---|
<<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. |
If the access ID is blank, the default access ID (which is the access ID where the original template is stored) is used.
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.
- 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
Log in to D1.
On the landing page, click the API link under repository where you want to use template services:
The OpenAPI page opens.
Consider switching to Swagger 2.0 before executing requests — it is more mature than OpenAPI, which is still in experimental phase.
Expand endpoints under Conversion. You will find both
/apply-template
and/merge-templates
.Click Try it out! to activate the fields.
Paste your template specification into the Request body field.
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:
- Upload ParentTemplate.vm, Import1.html, Import2.html, and an image to your D1 repository.
- Find the
/tribefire-services/api/v1/access.adx.content.default/v1/convert/merge-templates
endpoint in OpenAPI > Merge templates. - Copy the JSON Body and replace the
contentId
with the write ID of your contents. - 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