Search code examples
jinja2

Pass by reference or return value in jinja2


I have some code that I've been repeating a lot in one of my jinja2 templates. When I've been turning a string into a link I want to check to see if it has a trailing / at the end and if it does then truncate it. This is what I'd like it to look like.

{% macro remove_trailing_slash(path) %}
  {% if path[-1:] == '/' %}
    {{ path[:-1] }}
  {% else %}
    {{ path }}
  {% endif %}
{% endmacro %}

The problem I'm having is figuring out how to pass the modified path back to the original caller. I can't seem to find a return statement in the jinja2 docs.


Solution

  • This is something that would be better done with a filter in Jinja, rather than a macro.

    In my understanding macros are for reusing pieces of logic, they don't really map to functions in Python (it would be within the Jinja compiler's right to copy the contents of the macro to every place the macro is invoked). Filters, on the other hand, are designed to manipulate the template's data before it is passed on to the "output stream".

    If you register a filter with the Jinja environment, then you can do something like this:

    {{ one_url | remove_trailing_slash }}
    {{ another_url | remove_trailing_slash }}
    

    If you are doing this all over your templates, you may be better off sanitizing these values before even passing them off to your templates.

    You can also create a macro to wrap this pattern:

    {% macro link(url) %}
    <a href="{{ url }}">{{ url | remove_trailing_slash }}</a>
    {% endmacro %}