Freemarker Templating
Introduction¶
The Freemarker plugin provides additional API endpoints that allow custom queries to be run and templates to be applied to the result. This can be used as a lightweight way to create custom exporters or provides an easy way to allow interchange between different systems. The functionality makes use of a popular and powerful templating engine: Apache FreeMarker.
Warning¶
Warning
Allowing users to execute their own code on the server is, in general, bad practice. Badly-written templates could result in the server becoming unresponsive or consuming additional resources. The template framework has also been carefully configured to ensure a minimal amount of data is accessible, but malicious templates may be able to access more data than intended.
To mitigate this risk, the Freemarker templating plugin is an optional extra and when installed, the API endpoints are only accessible by registered users with administrator access. It is recommended that template developers test on a local instance of Mauro in the first instance and carefully iterate on templates. This will ensure any complex queries or loops do not accidentally cause a denial of service to the Mauro instance.
We have plans to improve the templating plugin in the future to provide greater levels of safety as well as allowing non-administrators to have access to the functionality in a safe manner.
Basic usage¶
The main API endpoint provided by the plugin is as follows:
In order to call this endpoint, the user must be authenticated as a user with an administrator role, either through a login call and a persistent
session cookie, or using an API key. The body of the call must be text corresponding to a valid Apache FreeMarker template. The domainType
and id
parameters will point to a particular ‘resource’, that will be queried and have the template applied.
Within the template, the resulting resource will be accessible through a variable with the same name as the domain type. See the examples below for more details. Successful return of the API call will have, as body text, the result of applying the given template to the queried resource.
Any errors in the template will result in an error being thrown, with a message
field indicating the nature of the error and the line number of
the template in which the error was found.
Template language reference¶
The Apache FreeMarker pages contain a general-purpose introduction to the FreeMarker Template Language (FTL), as well as a detailed reference manual for the syntax.
Other online tutorials are provided by Lars Vogel and some useful tricks are given in this article by Baeldung.
You may also wish to visit our Zulip community for help and advice. We would also like to publish reusable templates donated by the community on these pages.
Example 1: A simple web page¶
In this first example, a basic template will be applied to a Data Model in order to generate a simple HTML page for a given Data Model.
The API call:
Is made with an appropriate API key, and the post body:
1 2 3 4 5 6 7 8 9 10 |
|
Note in the template, the variable dataModel
represents the Data Model object with the id
given as the URL parameter. Note also, the use of !
when accessing the description o the Data Model. This is to guard against the case where the description is unset (null).
The body of the API call response is as follows:
1 2 3 4 5 6 7 8 9 10 |
|
Note that this example also illustrates some shortcomings of the approach for complex transformations. If the description were to be html
formatted already, for example, starting with a <p>
tag, the resulting html may be invalid. Some simple transformations are possible within the
templating language, particularly with the use of complex macros, but the use of this plugin should be reserved for simple textual templating.
More complex algorithms should be implemented within a custom plugin or external script, where programmatic functions and libraries are more easily accessible.
Example 2: A CSV file of terms in a terminology¶
This second example uses a slightly more complex template to iterate over the terms of a terminology, printing the code and definition for each.
The API call:
Is made with an appropriate API key and with the following text in the body:
1 2 3 4 |
|
The <#list>
tag indicates a template chunk that is to be repeated for each item in the list - in this case the list of terms given by
terminology.term
. The ?sort_by
annotation indicates that the set of terms should be ordered before iteration. Within these tags, the term in
question is given the variable name term
.
The result is a CSV file of terms, for example:
1 2 3 4 5 |
|
Templating Diffs¶
The plugin also provides an endpoint for templating the difference between two models. The API endpoint:
Compares two objects and allows the result to be templated. The method provides the following variables for use within the template:
sourceModel
- The model to be used as the source of the diff (left-hand side), identified by
sourceId
targetModel
- The model to be used as the target of the diff (right-hand-side), identified by
targetId
diff
- The result of the comparison between the two models, stored as a set of
diffs
The structure of the diff
object is still to be described in more detail, but a simple example is given below.
Example 3: Listing differences¶
This third example gives a flavour of the templating required to examine the differences between two Data Models. A more detailed example is needed here, but we illustrate for a very simple template, comparing two very simple (and similar) models.
Given the API call:
With appropriate authentication and the POST body:
1 2 3 4 5 |
|
This will print first the label of the source model, then the label of the target model. For each basic difference between the two models, it will print the field name, the value of that field in the left-hand model, and the value of that field in the right-hand model.
For two very simple models this might give an output such as:
1 2 3 4 |
|