Template tags#
This page lists the template tags and filters that FairDM ships, in three tag libraries. Each entry gives the tag’s form, its arguments, what it returns and what it does when something is missing. It does not cover the Cotton components, which are on Components, or the tags of the packages FairDM installs, such as Django’s own, which are in the Django documentation.
A template loads a library before it uses the library’s tags:
{% load fairdm plugin_tags contributor_tags %}
Library |
Holds |
|---|---|
Markdown, units, the registry, fields and permissions |
|
Plugin addresses and the viewer’s level on a record |
|
Contributions, roles and contributor names |
The functions behind the tags, with their docstrings, are in fairdm.templatetags.fairdm, fairdm.contrib.plugins.templatetags.plugin_tags and fairdm.contrib.contributors.templatetags.contributor_tags.
A tag written {% name ... %} returns its value into the page. Add as variable to keep the value in a variable instead, as for any Django simple tag. A filter is written {{ value|name }} or {{ value|name:"argument" }}.
The fairdm library#
is_active#
{% is_active "/datasets/" %}
Arguments:
url, a path prefix.Returns:
"active"when the current request’s path starts withurl, and""otherwise.Needs:
requestin the template context. Without it the tag raisesKeyError.
notation#
{{ description.type|notation }}
Value: a vocabulary concept, such as the
typeof a description or a date, orNone.Returns: the concept’s
skos:notation, the code it was stored as before it had an address. For the terms DataCite also lists, such as the description and contributor types, that is DataCite’s own value. An empty string when there is no concept or it has no notation.
unit#
{{ "m/s"|unit }}
Value: a unit name that the unit library understands, such as
"m"or"g/cm**3", or a unit object.Returns: the unit written as HTML with its symbols.
Raises:
UndefinedUnitErrorfor a name the unit library does not know. Any value that is neither a string nor a unit makes the filter fail withUnboundLocalError.
get_registry_info#
{% get_registry_info object as info %}
Arguments: a model class, a model instance or a queryset.
Returns: the registry configuration of the model, or
Nonewhen the model is not registered. Python code callsregistry.get_for_model(), which raises for an unregistered model instead.
display_url#
{% display_url "https://www.example.org/data" %}
Arguments:
url, a string.Returns: the address with
https://,http://andwww.removed, for showing as link text. Here,example.org/data.
get_field#
{% get_field object "rock_type" as field %}{{ field.verbose_name }}
Arguments:
obj, a model instance or class, andfname, a field name.Returns: the model field, or
Nonewhen the model has no field of that name.
get_field_and_value#
{% get_field_and_value object "rock_type" as pair %}{{ pair.field.verbose_name }}: {{ pair.value }}
Arguments:
obj, a model instance, andfname, a field name.Returns: a dictionary with
field, the model field, andvalue, the instance’s value for it.Raises:
FieldDoesNotExistwhen the model has no field of that name.
get_fields#
{% get_fields object field_names as pairs %}
{% for field, value in pairs %}{{ field.verbose_name }}: {{ value }}{% endfor %}
Arguments:
obj, a model instance, andfields, a list of field names from the context.Returns: a list of
(field, value)pairs in the order offields.Raises:
FieldDoesNotExistfor a name the model does not have.
edit_url#
{% edit_url object %}
Arguments:
obj, a model instance with auuid, andfields, an optional list of field names.Returns: the address of the URL named
<model name>-update, with?fields=and the names joined by commas whenfieldsis given.Raises:
NoReverseMatchfor every FairDM model, because FairDM defines no URL with a name of that form. Useplugin_urlwith the name of an editing page instead, as Record editing pages lists.
avatar_url#
{% avatar_url person %}
Arguments:
contributor, a person or organization, orNone.Returns: the address of the contributor’s uploaded image. When the contributor is
Noneor has no image, it returns the markup of FairDM’s default person icon, an<svg>element, not an address.
To draw a contributor’s picture, use the c-contributor.avatar component, which picks the right size and falls back to initials.
plugin_url in fairdm#
The fairdm library holds a copy of plugin_url from plugin_tags, and it behaves the same. Load it from plugin_tags.
safe_markdown#
{{ project.description|safe_markdown }}
Value: markdown text.
Returns: the HTML, sanitised and marked safe, so the template does not escape it again. The extensions applied are those in
FAIRDM_MARKDOWN_EXTENSIONS. The editor’s live preview uses the same function, so what a person previews is what the page shows.
How to render markdown in a template uses it, and How markdown is sanitised explains what is removed.
has_perms#
{% if perms_list|has_perms:"project.change_project,project.delete_project" %}...{% endif %}
Value: a collection of permission names, such as a list from the context.
Argument: permission names separated by commas, with no spaces.
Returns:
Truewhen the collection holds at least one of them.
has_permission#
{% has_permission "dataset.change_dataset" as may_edit %}
Arguments: permission names separated by commas, with no spaces.
Returns:
Truewhenuser_permissionsin the template context holds one of them, or, failing that, whenuserholds one of them for the whole portal. It does not ask about a particular record. To ask whether the viewer may work on a record, useholds_level.
get_related_field#
{% get_related_field sample "dataset__project__name" as found %}
Arguments:
obj, a model instance, andfield_name, a path of attribute names joined by double underscores.Returns: a pair: the object that holds the last attribute, and the name of that attribute. It does not return the value. Here it returns the project and
"name". When an object part-way along the path isNone, it returns(None, None).Raises:
AttributeErrorwhen a name before the last does not exist.
The plugin_tags library#
plugin_url#
{% plugin_url "contribution-list" %}
{% plugin_url "edit" %}
Arguments:
view_name, the URL name of a plugin page, then any positional or keyword arguments the address takes.Returns: the address of that page for the record in the context. The record is
non_polymorphic_objectwhen the context holds it, and otherwiseobject. The arguments the record’s addressing needs, such as itsuuid, are filled in from the record. Returns""when the context holds neither.Raises:
NoReverseMatchwhen the record’s type has no page of that name.
The Python function behind it is fairdm.contrib.plugins.utils.reverse, on Plugins.
holds_level#
{% holds_level "edit" object as can_edit %}
{% if can_edit %}<a href="{% plugin_url 'edit' %}">Edit</a>{% endif %}
Arguments:
level, one of"view","edit"or"manage", andrecord, a project, dataset, sample or measurement.Returns:
Truewhen the viewer holds that level on the record or a higher one, through a contribution on the record, on a record above it or for the whole portal.Falsefor a visitor who is not signed in, for a record that is none of the four, and when the context holds norequest.Raises:
ValueErrorfor any other level.
The answer is the one the record’s own pages are opened with. Contribution levels and record access lists what each level allows, and How to show part of a page to a record’s team uses the tag.
The contributor_tags library#
by_role#
{{ dataset.contributors.all|by_role:"https://w3id.org/fairdm/vocabularies/contributor-roles/creator,https://w3id.org/fairdm/vocabularies/contributor-roles/contact-person" }}
Value: a queryset of contributions.
Argument: role addresses separated by commas, or a list of addresses. A role’s address is its concept’s URI in the contributor roles vocabulary, such as
https://w3id.org/fairdm/vocabularies/contributor-roles/creator.Returns: the contributions that hold at least one of the roles. With no argument, the queryset unchanged.
has_role#
{% if contribution|has_role:"https://w3id.org/fairdm/vocabularies/contributor-roles/contact-person" %}...{% endif %}
Value: one contribution.
Argument: role addresses separated by commas, or a list of addresses. A role’s address is its concept’s URI in the contributor roles vocabulary, such as
https://w3id.org/fairdm/vocabularies/contributor-roles/creator.Returns:
Truewhen the contribution holds one of the roles. With no argument it returns the contribution itself, which a template reads as true.
as_contributor#
{% with person=contribution|as_contributor %}{{ person.name }}{% endwith %}
Value: a contribution, a contributor or
None.Returns: the person or organization behind a contribution, or the contributor itself. A plain contributor is turned into its person or organization. Returns
NoneforNoneand for a contribution whose contributor was deleted.
as_contributors#
{% for contributor in dataset.contributors.all|as_contributors %}...{% endfor %}
Value: a list of contributions or contributors, or
None.Returns: a list of persons and organizations, leaving out contributions whose contributor was deleted.
Nonegives an empty list.
contributor_name#
{% contributor_name person "family_given" %}
Arguments:
contributor, a person or organization, andname_format, an optional name format.Returns: the contributor’s
name. With a format, a person’s name in that format, as for theformatattribute ofc-contributor.name. An organization ignores the format.Nonegives"".
split_contributors#
{% split_contributors dataset.contributors.all 3 as split %}
{% for contributor in split.shown %}...{% endfor %}
{% if split.more %}and {{ split.more }} more{% endif %}
Arguments:
values, contributions or contributors,limit, how many to show, where0shows everyone, andtotal, the real count whenvaluesis already cut short.Returns: a dictionary with
shown, the contributors to name,more, how many are left out, andtotal. When only one would be left out, it names that one too, because a count takes as much room as the name.