Skip to content

Commit ba22bac

Browse files
committed
Handle undefined variables in rss templates
These templates used to work when using the StrictUndefined undefined behavior in the jinja2 environment, but in recent releases, this causes the build to fail. This issue can be seen at Python-Community-News/Site#38. Using the `is defined` test results in similar behavior even when `StrictUndefined` is set, allowing site developers to catch typos or other missing template context without breaking their rss feeds. This change also includes a new test and a test fixture to create a jinja2 environment that can be modified with the scope of a single test.
1 parent 49b7f46 commit ba22bac

4 files changed

Lines changed: 63 additions & 24 deletions

File tree

src/render_engine/render_engine_templates/rss2.0.xml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
<description>{{description}}</description>
77
<atom:link href="{{SITE_URL}}" rel="self" type="application/rss+xml" />
88

9-
{% if language %}<language>{{language}}</language>{% endif %}
10-
{% if copyright %}<copyright>{{copyright}}</copyright>{% endif %}
11-
{% if managing_editor %}<managingEditor>{{managing_editor}}</managingEditor>{% endif %}
12-
{% if web_master %}<webMaster>{{web_master}}</webMaster>{% endif %}
13-
{% if pub_date %}<pubDate>{{pub_date}}</pubDate>{% endif %}
14-
{% if last_build_date %}<lastBuildDate>{{last_build_date}}</lastBuildDate>{% endif %}
15-
{% if categories %}
9+
{% if language is defined %}<language>{{language}}</language>{% endif %}
10+
{% if copyright is defined %}<copyright>{{copyright}}</copyright>{% endif %}
11+
{% if managing_editor is defined %}<managingEditor>{{managing_editor}}</managingEditor>{% endif %}
12+
{% if web_master is defined %}<webMaster>{{web_master}}</webMaster>{% endif %}
13+
{% if pub_date is defined %}<pubDate>{{pub_date}}</pubDate>{% endif %}
14+
{% if last_build_date is defined %}<lastBuildDate>{{last_build_date}}</lastBuildDate>{% endif %}
15+
{% if categories is defined %}
1616
{% for category in categories %}
1717
{% if category['domain'] %}
1818
<category domain="{{category['domain']}}">{{category}}</category>
@@ -21,14 +21,14 @@
2121
{% endif %}
2222
{% endfor %}
2323
{% endif %}
24-
{% if generator %}<generator>{{generator}}</generator>{% endif %}
25-
{% if docs %}<docs>{{docs}}</docs>{% endif %}
26-
{% if cloud %}
24+
{% if generator is defined %}<generator>{{generator}}</generator>{% endif %}
25+
{% if docs is defined %}<docs>{{docs}}</docs>{% endif %}
26+
{% if cloud is defined %}
2727
<cloud domain="{{cloud.domain}}" port={{cloud.port}} path="{{cloud.path}}" registerProcedure="{{cloud.register_procedure}}" protocol="{{cloud.protocol}}" />
2828
{% endif %}
29-
{% if ttl %}<ttl>{{ttl}}</ttl>{% endif %}
30-
{% if image %}<image>{{image}}</image>{% endif %}
31-
{% if comments %}{{comments}}{% endif %}
29+
{% if ttl is defined %}<ttl>{{ttl}}</ttl>{% endif %}
30+
{% if image is defined %}<image>{{image}}</image>{% endif %}
31+
{% if comments is defined %}{{comments}}{% endif %}
3232
{% for item in pages %}
3333
{% include 'rss2.0_items.xml' %}
3434
{% endfor %}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<item>
2-
{% if item.title %}<title>{{item.title}}</title>{% endif %}
3-
{% if item.description %}
2+
{% if item.title is defined %}<title>{{item.title}}</title>{% endif %}
3+
{% if item.description is defined %}
44
<description><![CDATA[{{item.description}}]]></description>
55
{% else %}
66
<description><![CDATA[{{item._content|safe }}]]></description>
77
{% endif %}
88

9-
{% if item.enclosure %}
9+
{% if item.enclosure is defined %}
1010
<enclosure url="{{item.enclosure}}" length="{{item.enclosure.length}}" type="{{item.enclosure.mime_type}}" />
1111
{% endif %}
12-
{% if item.category %}
13-
{% if item.category['domain'] %}
12+
{% if item.category is defined %}
13+
{% if item.category is defined['domain'] %}
1414
<category domain="{{item.category['domain']}}">{{item.category}}</category>
1515
{% else %}
1616
<category>{{item.category}}</category>
@@ -19,9 +19,9 @@
1919
<link>
2020
{{SITE_URL}}{{item.url_for()}}
2121
</link>
22-
{% if item.date_published %}<pubDate>{{item.date_published | to_pub_date }}</pubDate>{% endif %}
23-
{% if item.guid %}<guid isPermaLink="false">{{item.guid}}</guid>{% endif %}
24-
{% if item.author %}{{item.author}}{% endif %}
25-
{% if item.comments %}{{item.comments}}{% endif %}
26-
{% if item.source %}<source url="{{item.source.url}}">{{item.source}}</source>{% endif %}
22+
{% if item.date_published is defined %}<pubDate>{{item.date_published | to_pub_date }}</pubDate>{% endif %}
23+
{% if item.guid is defined %}<guid isPermaLink="false">{{item.guid}}</guid>{% endif %}
24+
{% if item.author is defined %}{{item.author}}{% endif %}
25+
{% if item.comments is defined %}{{item.comments}}{% endif %}
26+
{% if item.source is defined %}<source url="{{item.source.url}}">{{item.source}}</source>{% endif %}
2727
</item>

tests/conftest.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from jinja2 import Environment, select_autoescape
2+
import pytest
3+
4+
from render_engine.engine import render_engine_templates_loader
5+
6+
7+
@pytest.fixture
8+
def engine() -> Environment:
9+
return Environment(
10+
loader=render_engine_templates_loader,
11+
autoescape=select_autoescape(["xml"]),
12+
lstrip_blocks=True,
13+
trim_blocks=True,
14+
)

tests/test_feeds.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import pluggy
22

3+
from jinja2 import StrictUndefined
4+
35
from render_engine.collection import Collection
46
from render_engine.feeds import RSSFeed
57
from render_engine.page import Page
@@ -64,4 +66,27 @@ class TestCollection(Collection):
6466

6567
collection = TestCollection()
6668
print(collection._feed.template)
67-
assert "http://localhost:8000//page.html" in collection._feed._render_content(engine=engine)
69+
assert "http://localhost:8000//page.html" in collection._feed._render_content(engine=engine)
70+
71+
72+
def test_rss_feed_template_with_strictundefined(engine, tmp_path):
73+
"""Test that the RSS feed template works with the StrictUndefined undefined handler."""
74+
tmp_dir = tmp_path / "content"
75+
tmp_dir.mkdir()
76+
file = tmp_dir / "#"
77+
file.write_text("test")
78+
79+
class TestCollection(Collection):
80+
pages = [Page(content_path=file)]
81+
Feed = RSSFeed
82+
83+
collection = TestCollection()
84+
engine.undefined = StrictUndefined
85+
rendered_content = collection._feed._render_content(
86+
engine=engine,
87+
SITE_TITLE="Test Site Title",
88+
SITE_URL="http://localhost:8000",
89+
title="Test Feed Title",
90+
description="Test Feed Description",
91+
)
92+
assert "http://localhost:8000/page.html" in rendered_content

0 commit comments

Comments
 (0)