feat(content): programmatic SEO seed script + lang bug fixes

- Add scripts/seed_content.py: inserts EN + DE article templates and
  18 cities × 2 language data rows; run with --generate to produce 36
  pre-built SEO articles (Germany 8, USA 6, UK 4 cities) each with
  city-specific financial model overrides for unique content per article
- Fix bake_scenario_cards() to accept lang param and pass it to
  scenario card partials; German articles now render German labels
- Fix _generate_from_template() to extract language from data row and
  pass to calc() and bake_scenario_cards()
- Fix article_slug to use {template_slug}-{city_slug} preventing UNIQUE
  collision when multiple templates generate articles for same city
- Fix _rebuild_article() to pass lang to bake_scenario_cards()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-21 01:38:33 +01:00
parent 7485bdffad
commit ceee85caba
4 changed files with 908 additions and 7 deletions

View File

@@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
### Added
- content: `scripts/seed_content.py` — seeds two article templates (EN + DE) and 18 cities × 2 language rows into the database; run with `uv run python -m padelnomics.scripts.seed_content --generate` to produce 36 pre-built SEO articles covering Germany (8 cities), USA (6 cities), and UK (4 cities); each city has realistic per-market overrides for rates, rent, utilities, permits, and court configuration so the financial model produces genuinely unique output per article
- content: EN template (`city-padel-cost-en`) at `/padel-cost/{{ city_slug }}` and DE template (`city-padel-cost-de`) at `/padel-kosten/{{ city_slug }}` with Jinja2 Markdown bodies embedding `[scenario:slug:section]` cards for summary, CAPEX, operating, cashflow, and returns
### Fixed
- content: `bake_scenario_cards()` now accepts a `lang` parameter and passes it to scenario partial templates; previously `lang` was always `undefined`, causing all cards to render with English labels even for German articles
- admin: `_generate_from_template()` extracts `language` from data row and passes it to `calc()` and `bake_scenario_cards()` so German scenario cards use translated CAPEX/OPEX item names
- admin: `_generate_from_template()` now derives `article_slug` as `{template_slug}-{city_slug}` instead of bare `city_slug`; bare slugs caused UNIQUE constraint collisions when multiple templates generated articles for the same city
- admin: `_rebuild_article()` passes `lang` from data row (or `"en"` for manual articles) to `bake_scenario_cards()` so rebuilt articles render correct language labels
- content: removed unused `g` import from `content/routes.py`
### Changed
- planner: full HTMX refactor — replaced 847-line SPA `planner.js` with server-rendered Jinja2 tab partials; planner now uses `hx-post /planner/calculate` + form state; all tab content (CAPEX, Operating, Cash Flow, Returns, Metrics) rendered server-side; Chart.js data embedded as `<script type="application/json">` tags, re-initialized on `htmx:afterSettle`; new `planner.js` is ~200 lines (chart init, slider sync, toggle management, wizard nav, scenario save/load)
- planner/i18n: merged `_PLANNER_TRANSLATIONS` (~200 keys × 2 languages) into `_TRANSLATIONS`; deleted `get_planner_translations()` and `window.__PADELNOMICS_LOCALE__`; all planner strings now via standard `{{ t.key }}` Jinja2 template variables; adding a new language = one section in `_TRANSLATIONS`