Django to Jinja migration
As of version 2.0 (Oct 2022) Ontospy’s visualization module replaces Django with Jinja.
This is to make Ontospy footprint more lightweight, as well as to simplify future maintenance of the library. Django offers a lot of functionalities that are not needed by the simple use case of Ontospy: cranking out HTML pages from templates.
This page contains information of Django specific template filters, or constructs, that are not directly usable with Jinja and how they have been updated.
NOW
Django’s template tag now
can be used in Jinja after installing the extension https://pypi.org/project/jinja2-time/.
Then you can do
{% now 'utc', '%a, %d %b %Y %H:%M:%S' %}
IFCHANGED
Django’s template tag ifchanged
does not exist in Jinja. So a custom logic for caching iteration values via jinja assignments must be implemented. I found an example of this approach on https://groups.google.com/g/pocoo-libs/c/uRsxf9ivv2c
From
{% for each in o.annotations %}
{% ifchanged each.1 %}
{% if not forloop.first %}</dl>{% endif %}
<dt>{{each.1}}</dt>
{% endifchanged %}
<dd>{{each.2|linebreaks}}</dd>
{% endfor %}
To
{% for each in o.annotations() %}
{% if each.1 != variable_watcher %}
{% if not loop.first %}</dl>{% endif %}
<dt>{{each.1}}</dt>
{% set variable_watcher = each.1 %}
{% else %}
{% endif %}
<dd>{{each.2|linebreaks}}</dd>
{% endfor %}
DEFAULT
Django’s template tag ifchanged
has a slightly diffent syntax in Jinja.
From
{{s.qname|default:each.qname}}
To
{{s.qname|default(each.qname)}}
LINEBREAKS
Django’s template filter linebreaks
does not exist in Jinja. It can be implemented as a custom filter (see this thread on SO)
import re
from markupsafe import Markup, escape
from jinja2 import pass_eval_context
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
@pass_eval_context
def linebreaks_filter(eval_ctx, value):
result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n')
for p in _paragraph_re.split(escape(value)))
if eval_ctx.autoescape:
result = Markup(result)
return result
env.filters['linebreaks'] = linebreaks_filter
METHOD CALLS
Django’s templating language is ‘relaxed’ when it comes to resolving an object attribute or method call. In both cases, it’s enough to pass the attribute or method name.
With Jinja, method calls need to be followed by parentheses, like in Python. See also https://stackoverflow.com/questions/59589889/difference-between-an-item-and-an-attribute-jinja-python
From
{% for each in o.annotations %}
To
{% for each in o.annotations() %}
PS this applies to each.children()
, each.parents()
, each.rdf_source()
etc..
IFEQUAL
From
{% ifequal objtype "class" #}"""
To
{% if objtype == "class" #}"""
WITH
From
{% with main_entity as each #}"""
...
{% ifequal objtype "class" #}"""
To
{% if objtype == "class" #}"""
WITH
From
{% with main_entity as each #}"""
...
{% endwith %}
To
{% set each = main_entity #}"""
# no need to close anything
COMMENTS
See https://jinja.palletsprojects.com/en/3.1.x/templates/#comments
From
{% set each = main_entity #}"""
# no need to close anything
COMMENTS
See https://jinja.palletsprojects.com/en/3.1.x/templates/#comments
From
{% comment %}
To
{%
comment
#}"""