Reputation: 3237
I have a set of articles (using pelican for generating static sites) which includes a category called hotels. I'd like to sort these hotels. The problem is that only the hotels have an attribute called 'city' while the other articles do not and this obviously leads to the following error:
Caught exception "'pelican.contents.Article object' has no attribute 'city'".
Here is the code I am using:
{% for article in articles|sort(attribute='city') %}
{% if article.category == 'hotels' %}
<a href="hotels/{{ article.slug }}.html">
<p>{{ article.title }}</p>
</a>
{% endif %}
{% endfor %}
Is there a way to check to see if the attribute exists and provide some default value so that it does not cause an error?
Upvotes: 1
Views: 2120
Reputation: 83
If you want to show only entries that have a 'city'
attribute, and have that list sorted by 'city'
, do:
for article in articles|selectattr("city")|sort(attribute="city")
Upvotes: 1
Reputation: 11
I found this page when was looking for a similar solution. Eventually, I solved it a bit differently and it might be helpful for someone else.
In one of my templates for Pelican I added statistics collected by 'post_stats' plugin about approximate time to read. It looked like
~{{ article.stats['read_mins']|default("0") }} min read
But if the plugin is not loaded then the 'article' object doesn't have the 'stats' attribute and rendering fails.
Jinja has the builtin test for testing if a variable is defined. So, I came up with this solution
~{{ article.stats['read_mins'] if article.stats is defined else "0" }} min read
Upvotes: 0
Reputation: 22007
If you want to iterate over only the hotels, see Sean Vieira's answer. If you want to iterate over all articles, but have the hotels sorted while the rest are in arbitrary order, you can do it by using macros:
{% macro my_macro(article) %}
...
{% endmacro %}
{% for a in articles if a.category == 'hotels' | sort(attribute='city') %}
{{ my_macro(a) }}
{% endfor %}
{% for a in articles if a.category != 'hotels' %}
{{ my_macro(a) }}
{% endfor %}
This will include everything you defined in my_macro
first for each hotel, in the desired order, then for each article that is not a hotel.
Upvotes: 0
Reputation: 159905
You may be able to move your if
statement into your for
loop as a filter:
for article in articles if article.category == 'hotels' | sort(attribute='city')
Upvotes: 1