From 84df11aee7b21ac4715893c7fae3078b39600955 Mon Sep 17 00:00:00 2001 From: Deeman Date: Fri, 20 Feb 2026 23:29:30 +0100 Subject: [PATCH] =?UTF-8?q?refactor(i18n):=20Batch=201=20=E2=80=94=20elimi?= =?UTF-8?q?nate=20{%=20if=20lang=20%}=20blocks=20in=20content=20templates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert 63 inline lang blocks across 7 content templates to t.key references. Add 51 new locale keys (scenario_*, markets_*, article_detail_*). Templates updated: - content/partials/scenario_summary.html (6 blocks → t.keys) - content/partials/scenario_returns.html (15 blocks → t.keys) - content/partials/scenario_operating.html (17 blocks → t.keys) - content/partials/scenario_cashflow.html (7 blocks → t.keys, tformat) - content/partials/scenario_capex.html (9 blocks → t.keys) - content/templates/markets.html (6 blocks → t.keys in title/meta/labels) - content/templates/article_detail.html (2 blocks → t.keys) Also: fix scenario card CTA links (href="/planner/" → url_for), add url_for stub and tformat filter to _bake_env, pass lang+t to bake render calls, update test_planner_cta_link assertion. Co-Authored-By: Claude Opus 4.6 --- padelnomics/src/padelnomics/content/routes.py | 21 +++++++- .../content/templates/article_detail.html | 2 +- .../content/templates/markets.html | 12 ++--- .../templates/partials/scenario_capex.html | 18 +++---- .../templates/partials/scenario_cashflow.html | 14 ++--- .../partials/scenario_operating.html | 34 ++++++------ .../templates/partials/scenario_returns.html | 30 +++++------ .../templates/partials/scenario_summary.html | 12 ++--- padelnomics/src/padelnomics/locales/de.json | 53 ++++++++++++++++++- padelnomics/src/padelnomics/locales/en.json | 53 ++++++++++++++++++- padelnomics/tests/test_content.py | 2 +- 11 files changed, 185 insertions(+), 66 deletions(-) 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 @@

{{ article.title }}

- {% 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 }}

diff --git a/padelnomics/src/padelnomics/content/templates/markets.html b/padelnomics/src/padelnomics/content/templates/markets.html index e6337ff..1acb1aa 100644 --- a/padelnomics/src/padelnomics/content/templates/markets.html +++ b/padelnomics/src/padelnomics/content/templates/markets.html @@ -1,11 +1,11 @@ {% extends "base.html" %} -{% block title %}{% if lang == 'de' %}Padel-Märkte - {{ config.APP_NAME }}{% else %}Padel Markets - {{ config.APP_NAME }}{% endif %}{% endblock %} +{% block title %}{{ t.markets_page_title }} - {{ config.APP_NAME }}{% endblock %} {% block head %} - - - + + + {% endblock %} {% block content %} @@ -19,7 +19,7 @@
- +
- +