diff --git a/padelnomics/src/padelnomics/content/routes.py b/padelnomics/src/padelnomics/content/routes.py
index 1032153..98ab76e 100644
--- a/padelnomics/src/padelnomics/content/routes.py
+++ b/padelnomics/src/padelnomics/content/routes.py
@@ -10,6 +10,7 @@ from markupsafe import Markup
from quart import Blueprint, abort, g, render_template, request
from ..core import capture_waitlist_email, config, csrf_protect, fetch_all, fetch_one, waitlist_gate
+from ..i18n import get_translations
bp = Blueprint(
"content",
@@ -37,9 +38,20 @@ SECTION_TEMPLATES = {
}
# Standalone Jinja2 env for baking scenario cards into static HTML.
-# Does not require a Quart app context.
+# Does not use a Quart request context, so url_for and t are injected
+# explicitly. Baked content is always EN (admin operation).
_TEMPLATE_DIR = Path(__file__).parent / "templates"
_bake_env = Environment(loader=FileSystemLoader(str(_TEMPLATE_DIR)), autoescape=True)
+_bake_env.filters["tformat"] = lambda s, **kw: s.format_map(kw)
+
+# Hardcoded EN URL stubs — the bake env has no request context so Quart's
+# url_for cannot be used. Only endpoints referenced by scenario card templates
+# need to be listed here.
+_BAKE_URLS: dict[str, str] = {
+ "planner.index": "/en/planner/",
+ "directory.index": "/en/directory/",
+}
+_bake_env.globals["url_for"] = lambda endpoint, **kw: _BAKE_URLS.get(endpoint, f"/{endpoint}")
def is_reserved_path(url_path: str) -> bool:
@@ -79,7 +91,12 @@ async def bake_scenario_cards(html: str) -> str:
state_data = json.loads(scenario["state_json"])
tmpl = _bake_env.get_template(template_name)
- card_html = tmpl.render(scenario=scenario, d=calc_data, s=state_data)
+ # Baking is always in the EN admin context; t and lang are required
+ # by scenario card templates for translated labels.
+ card_html = tmpl.render(
+ scenario=scenario, d=calc_data, s=state_data,
+ lang="en", t=get_translations("en"),
+ )
html = html[:match.start()] + card_html + html[match.end():]
return html
diff --git a/padelnomics/src/padelnomics/content/templates/article_detail.html b/padelnomics/src/padelnomics/content/templates/article_detail.html
index b11cf24..7df25ad 100644
--- a/padelnomics/src/padelnomics/content/templates/article_detail.html
+++ b/padelnomics/src/padelnomics/content/templates/article_detail.html
@@ -40,7 +40,7 @@
- {% if article.published_at %}{% if lang == 'de' %}Veröffentlicht{% else %}Published{% endif %} {{ article.published_at[:10] }} · {% endif %}{% if lang == 'de' %}Padelnomics Forschung{% else %}Padelnomics Research{% endif %}
+ {% if article.published_at %}{{ t.article_detail_published_label }} {{ article.published_at[:10] }} · {% endif %}{{ t.article_detail_research_label }}
{{ article.title }}