Views and their template syntax¶
Syntax overview¶
Each view has a template, which determines how the answers given by the user are mapped to a textual document. The template is composed using the Django template syntax, which is a combination of regular HTML, variables, which get replaced with values when the template is evaluated ({{ a_variable }}
), and tags, which control the logic of the template ({% a_tag %}
).
In the first line of the view template you will find the load command for the available view tags. It makes the logic of the template available and should always be there.
{% load view_tags %}
Immediately afterwards there will probably be variable declarations which load sets into place holders and make them available throughout the whole template. These variables can for example be used in for loops as you will see later.
{% get_set 'project/partner/id' as partners %}
{% get_set 'project/dataset/id' as datasets %}
Consider an attribute project/research_question/title
and a user, who answered the question connected to this attribute with “To boldly go where no man has gone before.”. The attribute would be available in the template as project/research_question/title
.
The main research question of the project is:
{% render_value 'project/research_question/title' %}
would, when evaluated in the context by a user in his/her project, render:
The main research question of the project is:
To boldly go where no man has gone before.
Lists of multiple values can also be rendered.
<p>
{% render_value_inline_list 'project/research_question/keywords' %}
</p>
As equivalent for the snippet above you can also use the following which gives you more control over the list layout.
<ul>
{% get_values 'project/research_question/keywords' set_index=0 as text %}
{% for value in text %}
<li>{{ value.value }}</li>
{% endfor %}
</ul>
For set entities, you can use the initially declared variables. Your code would look like this.
{% for dataset in datasets %}
<p>
{% render_set_value dataset 'project/dataset/id' %}
</p>
{% endfor %}
Values can be used if they meet certain conditions. If you want to display something based on a certain value being true
you can for example do this. Note that there is an .is_false
function as well which can be used just as the mentioned counterpart.
{% get_value 'project/dataset/sharing/yesno' as val %}
{% if val.is_true %}
This will be only rendered if personal_data resolves to be true.
{% endif %}
Or checking a value within a dataset.
{% for dataset in datasets %}
{% get_set_value dataset 'project/dataset/id' as val %}
{% if val.is_true %}
{% render_set_value dataset 'project/dataset/id' %}
{% endif %}
{% endfor %}
Calculations¶
You can do calculations in RDMO’s view templates by using filters. The package RDMO utilizes is called django-mathfilters. The following operations are supported. For more information please have a look into the django mathfilters documentation which can be found at the link mentioned before.
Filter Name | Operation |
---|---|
sub | subtraction |
mul | multiplication |
div | division |
intdiv | integer (floor) division |
abs | absolute value |
mod | modulo |
addition | addition |
The following examples illustrate how to use the mathfilters. It is quite easy if you pay attention to two things. First step is to load the desired value into a variable. This can be achieved as usual by get_value
. Afterwards this value can be used in calculations but it explicitly needs to be used as_number
.
For example you could do the following to get the sum of two values.
{% get_value 'project/costs/creation/personnel' as val1 %}
{% get_value 'project/costs/creation/non_personnel' as val2 %}
{{ val1.as_number | addition:val2.as_number }}
Note that filters can be piped after another as often as you like. You could easily do something like this. But pay attention to having the piped filters in a single line because Django templates do not support having filters spreading across multiple lines.
{% get_value 'project/costs/storage/personnel' as val1 %}
{% get_value 'project/costs/storage/non_personnel' as val2 %}
{% get_value 'project/costs/metadata/personnel' as val3 %}
{% get_value 'project/costs/metadata/non_personnel' as val4 %}
{{ val1.as_number | addition:val2.as_number | addition:val3.as_number | addition:val4.as_number }}
Please consult the documentation of the Django template syntax for all the available tags and filters: https://docs.djangoproject.com/en/stable/ref/templates/language.
Child projects¶
If child projects exist, they can be accessed using project.children
(direct children) and project.descendants
(all descendants, e.g. children of children, etc.). The project
keyword argument in the view tags are then used to select a particular project, e.g.:
{% for child in project.children %}
<div>
{% render_value 'project/title' with project=child %}
</div>
{% endfor %}
{% for child in project.descendants %}
<div>
{% render_value 'project/title' with project=child %}
</div>
{% endfor %}
Metadata in exported documents¶
RDMO’s views can be exported as PDF documents or in other office compatible formats. These files are generated using Pandoc and can contain metadata. Pandoc is able to save metadata into exported documents. A mechanism RDMO can make use of.
It is possible to add a metadata header to views, which is characterized by a surrounding metadata
tag in angle brackets as probably known from html. Inside these brackets a set of json data can be declared holding the metadata information.
An example of a metadata header would be something like this.
<metadata>
{
"title": "this is a very nice title",
"author": ["author one", "author two"],
"keywords": ["nothing", "something", "whatever"]
}
</metadata>
The json data are passed unmodified to Pandoc. Therefore is is important to make sure the data have a structure that Pandoc can make sense of. A more elaborated description of which tags are supported can be found in the Pandoc manual.
Pandoc does support saving metadata from version 2.3 upwards. Make sure to meet this requirement. If a lower version of Pandoc is installed RDMO won’t export any metadata into the generated documents.
Custom pandoc version¶
It is possible to explicitly specify the location of the Pandoc binary. This is done by setting the PYPANDOC_PANDOC
environment variable (see https://github.com/JessicaTegner/pypandoc#specifying-the-location-of-pandoc-binaries). This can be done in several ways, the easiest is probably to add the following code to your config/settings/local.py
:
import os
os.environ.setdefault('PYPANDOC_PANDOC', '/path/to/pandoc-3.1.5/bin/pandoc')