i am havin problems with some image urls generated partly through twig.
Here is how i am currently doing it:
{% autoescape false %}
{% set imageurl %}
http://www.someurl.com/mails/images/emails
{% endset %}
{% endautoescape %}
And this is how i am using it in the template itself:
{{imageurl}}/spacer.gif
The problem now is, that these images are not getting displayed properly in the final email because of a "%0A" inside the url. It looks like this:
/emails%0A/spacer.gif
I have no idea what is causing this problem, maybe you guys can help me..
Thanks in advance.
%0A is the Line Feed character. It is appended because of the newline after .../emails.
Either set the variable in one line:
{% set imageurl %}http://www.someurl.com/mails/images/emails{% endset %}
Or use Twig's tag level whitespace control:
{%- set imageurl -%}
http://www.someurl.com/mails/images/emails
{%- endset -%}
Related
I'm building an admin for Flask and SQLAlchemy, and I want to pass the HTML for the different inputs to my view using render_template. The templating framework seems to escape the HTML automatically, so all <"'> characters are converted to HTML entities. How can I disable that so that the HTML renders correctly?
To turn off autoescaping when rendering a value, use the |safe filter.
{{ something|safe }}
Only do this on data you trust, since rendering untrusted data without escaping is a cross-site scripting vulnerability.
MarkupSafe provides Jinja's autoescaping behavior. You can import Markup and use it to declare a value HTML safe from the code:
from markupsafe import Markup
value = Markup('<strong>The HTML String</strong>')
Pass that to the templates and you don't have to use the |safe filter on it.
From the Jinja docs section HTML Escaping:
When automatic escaping is enabled everything is escaped by default
except for values explicitly marked as safe. Those can either be
marked by the application or in the template by using the |safe
filter.
Example:
<div class="info">
{{data.email_content|safe}}
</div>
When you have a lot of variables that don't need escaping, you can use an autoescape override block:
{% autoescape false %}
{{ something }}
{{ something_else }}
<b>{{ something_important }}</b>
{% endautoescape %}
For handling line-breaks specifically, I tried a number of options before finally settling for this:
{% set list1 = data.split('\n') %}
{% for item in list1 %}
{{ item }}
{% if not loop.last %}
<br/>
{% endif %}
{% endfor %}
The nice thing about this approach is that it's compatible with the auto-escaping, leaving everything nice and safe. It can also be combined with filters, like urlize.
Of course it's similar to Helge's answer, but doesn't need a macro (relying instead on Jinja's built-in split function) and also doesn't add an unnecesssary <br/> after the last item.
Some people seem to turn autoescape off which carries security risks to manipulate the string display.
If you only want to insert some linebreaks into a string and convert the linebreaks into <br />, then you could take a jinja macro like:
{% macro linebreaks_for_string( the_string ) -%}
{% if the_string %}
{% for line in the_string.split('\n') %}
<br />
{{ line }}
{% endfor %}
{% else %}
{{ the_string }}
{% endif %}
{%- endmacro %}
and in your template just call this with
{{ linebreaks_for_string( my_string_in_a_variable ) }}
Use the safe filter in your template, and then sanitize the HTML with the bleach library in your view. Using bleach, you can whitelist the HTML tags that you need to use.
This is the safest, as far as I know. I tried both the safe filter and the Markup class, and both ways allowed me to execute unwanted JavaScript. Not very safe!
In one of my posts I added this custom variable:
exclude-from-indexes: true
In the layout for the category this post appears in, I have:
{% for post in site.categories[page.category] %}
{% if post.exclude-from-indexes!=true %}
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
However, the page is still included.
If I add:
{{ post.exclude-from-indexes }}
The variable is not shown.
I have tried different key names, but this doesn't appear to work. If I do:
{{ post | inspect }}
The key is not shown.
Am I accessing or declaring the custom variables in the wrong way? Or am I accessing some strange type of "post" that doesn't have the custom variables?
I noticed in another page, if I do:
{% for post in site.posts %}
{{ post.exclude-from-indexes }}
{% endfor %}
The variable is shown. So I think it's something to do with the data stored in site.categories[page.category]...
Turns out it was the keyname. Using:
excludefromindexes=true
Fixes it.
I have blog posts to which I add tags in the YFM like this:
tags: amp
I want Liquid to check whether the tag == amp and if so, to add a link in the blog-post.html layout file. I tried the code below:
{% if page.tags == "amp" %}
link
{% endif %}
But nothing gets outputted
The tags attribute in the YFM should actually be stored as an array since there can be multiple tags, as seen in the docs.
tags: [amp, foo, bar]
When checking the tags, use the contains liquid filter.
{% if page.tags contains 'amp' %}
link
{% endif %}
I have a page say index.html and a file with liquid code called tags. I want to pass a parameter which I specify in index.html to a liquid call in tags. Namely,
index.html
<div>
{% include tags param="site.categories" %}
</div>
Tags
{% assign tags_list = {{ include.param }} %}
...
The {% assign tags_list = {{ include.param }} %} does not work for some reason. Is it possible to do so because this allows me to use tags file for multiple purposes? Instead of writing liquid calls in every page Iwould be able to just do {% include tags param="something" %}. Thanks.
Well, {% include tags param="site.categories" %} is not passing the site.categories hash but the "site.categories" string.
The right syntax is :
{% include tags.html param=site.categories %}
I am building a Jekyll blog, and I have come across an issue with permalinks.
My permalinks to blog posts are set like this in
_config.yml:
permalink: /:page/:categories/:title
It outputs like this when navigating to a blog post:
http://localhost:4000/blog/travel/netherlands-trip-prequesites/
I have some static pages in the site: Blog, Travel
The variable page.url outputs this url: /blog/travel/netherlands-trip-prequesites
The code my navigation bar uses to highlight the current page (giving it an "active" class):
{% assign url = page.url|remove:'index.html' %}
{% for nav in site.navigation %}
{% if nav.href == url %}
<li class="active">{{nav.name}}</li>
{% else %}
<li>{{nav.name}}</li>
{% endif %}
{%endfor%}
It works great when navigating to static pages, however when I click a blog post it doesn't highlight the correct static page. (ex.: If i navigate to a blog post with the url /blog/smth/title it should automatically highlight "Blog" in my navigation. When I navigate to /travel/smth/title it should highlight "Travel")
What I'd like to do is to strip down the output of page.url to its first part. For example I'd like to stip the following output
/blog/travel/netherlands-trip-prequesites
down to
/blog/
Why? So I can use it to check which static page it belongs to and highlight it accordigly.
The easiest way is to use split:
{{ page.url | split:'/' | first }}
That will give you the URL content up to the first / character.
I managed to solve it with three filters:
{{ page.url | replace:'/',' ' | truncatewords: 1 | remove:'...' }}
page.url outputs: /page/cat/title, then replace removes the forward slashes producing: page cat title. truncatewords truncates the string down to one word, producing: page... (for some reason three dots gets inserted after the remaining word). After all this I only needed to remove those dots with remove and voilá, my final string: page.
Hope this helps someone.
The answer provided by PeterInvincible was almost perfect, however, there's no need to get piping to remove involved...
The following also will produce desired output
{{ page.url | replace:'/',' ' | truncatewords: 1,"" }}
And to save it to a variable use capture redirection
{{ capture url_base }}{{ page.url | replace:'/',' ' | truncatewords: 1,"" }}{{ endcapture }}
Which can be called via {{url_base}} or mixed with other processing calls.
Also for file paths instead of URLs page.dir works well if you're not using permalink settings for layout, check the gh-pages branch (specifically _includes/nav_gen.html for functional, though rough'round the edges, example) for hosted examples of similar code examples related to liquid syntax and other magic.
Edits & Updates
The above linked script is now live/mostly-working/modular and auto-serving parsed sub-directories viewed currently at the related https://s0ands0.github.io/Perinoid_Pipes/ project site providing examples of recursive parsing of directories. Including and modding for nearly any theme should be possible just check the commented section at the top for currently recognized commands that maybe passed at inclusion call... on that note of inclusion and modularization here's how to turn the above example code for directory parsing into a function
{% comment %}
# Save this to _include/dir_path_by_numbers.html
# import with the following assigning arguments if needed
# {% include dir_path_by_numbers.html directory_argument_path="blog" directory_argument_depth=1 %}
{% endcomment %}
{% assign default_arg_directory_path = page.url %}
{% assign default_arg_directory_depth = 1 %}
{% if directory_argument_path %}
{% assign directory_to_inspect = directory_argument_path %}
{% else %}
{% assign directory_to_inspect = default_arg_directory_path %}
{% endif %}
{% if directory_argument_depth %}
{% assign directory_to_inspect_depth = directory_argument_path %}
{% else %}
{% assign directory_to_inspect_depth = default_arg_directory_depth %}
{% endif %}
{% comment %}
# Defaults read and assigned now to output results
{% endcomment %}
{{ directory_to_inspect_depth | replace:'/',' ' | truncatewords: directory_to_inspect_depth,"" | remove_first: '/' | replace:' ','/' }}
The above should output directory path lengths of whatever size desired and maybe included as shown previously or if feeling adventurous try what's shown below; though for looping and recursive features look to the linked script for how I've worked around stack size restrictions.
{% capture dir_sub_path %}{{include dir_path_by_numbers.html directory_argument_path="blog" directory_argument_depth=1}}{% endcapture %}
Note above is just speculation, untested, and maybe more buggy than scripts tested and hosted publicly... in other words inspiration.
Simplest way would be using
if page.url contains
example:
<li class="{% if page.url contains '/docs/' %}current{% endif %}">
Docs