[DTP-Worker 20260730_085719] Auto exec · session 20260730_085719
CI / Contraintes NON-NÉGOCIABLES (CLAUDE.md) (push) Has been cancelled
CI / Validation JSON (schémas Faisabilité) (push) Has been cancelled
CI / Qualité documentaire (liens + 4Big) (push) Has been cancelled
CI / Publiciste · parser + schéma + generator (unittest) (push) Has been cancelled
CI / RBAC · 50 rôles + schéma (unittest) (push) Has been cancelled
CI / Faisabilité · générateur 4 volets + round-trip (unittest) (push) Has been cancelled
CI / RBAC · fixtures ERPNext (Role + Custom DocPerm) (push) Has been cancelled
CI / RBAC · plan User Permission (row-level) (push) Has been cancelled
CI / RBAC · Role Profile (bundles par portail) (push) Has been cancelled
CI / RBAC · run-book d'application unifié (agrégat 3 volets) (push) Has been cancelled
CI / Faisabilité · dossier bancable trilingue FR/EN/ES (push) Has been cancelled
CI / CRM · workflow vente ERPNext (lead → CONFOTUR) (push) Has been cancelled
CI / CRM · DocType porteur OTO Dossier Vente (push) Has been cancelled
CI / CRM · barème commissions vendeurs (push) Has been cancelled
CI / Fiscal · e-CF DGII (Compupar) (push) Has been cancelled
CI / Frontend · Workspaces 5 portails rôle (push) Has been cancelled
CI / Legal · DocType CONFOTUR Application (push) Has been cancelled
CI / QA · Audit 5D conformité (push) Has been cancelled
CI / SEO · mots-clés trilingues + schema.org + hreflang (push) Has been cancelled
CI / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
CI / Contraintes NON-NÉGOCIABLES (CLAUDE.md) (push) Has been cancelled
CI / Validation JSON (schémas Faisabilité) (push) Has been cancelled
CI / Qualité documentaire (liens + 4Big) (push) Has been cancelled
CI / Publiciste · parser + schéma + generator (unittest) (push) Has been cancelled
CI / RBAC · 50 rôles + schéma (unittest) (push) Has been cancelled
CI / Faisabilité · générateur 4 volets + round-trip (unittest) (push) Has been cancelled
CI / RBAC · fixtures ERPNext (Role + Custom DocPerm) (push) Has been cancelled
CI / RBAC · plan User Permission (row-level) (push) Has been cancelled
CI / RBAC · Role Profile (bundles par portail) (push) Has been cancelled
CI / RBAC · run-book d'application unifié (agrégat 3 volets) (push) Has been cancelled
CI / Faisabilité · dossier bancable trilingue FR/EN/ES (push) Has been cancelled
CI / CRM · workflow vente ERPNext (lead → CONFOTUR) (push) Has been cancelled
CI / CRM · DocType porteur OTO Dossier Vente (push) Has been cancelled
CI / CRM · barème commissions vendeurs (push) Has been cancelled
CI / Fiscal · e-CF DGII (Compupar) (push) Has been cancelled
CI / Frontend · Workspaces 5 portails rôle (push) Has been cancelled
CI / Legal · DocType CONFOTUR Application (push) Has been cancelled
CI / QA · Audit 5D conformité (push) Has been cancelled
CI / SEO · mots-clés trilingues + schema.org + hreflang (push) Has been cancelled
CI / E2E baseline Playwright (manuel) (push) Has been cancelled
CI / Gate qualité (agrégat) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""Generation de la carte hreflang (balises `alternate` multilingues + x-default).
|
||||
|
||||
Pour chaque page (accueil + une par projet) : une alternate par langue du site
|
||||
plus un `x-default` pointant vers la langue par defaut. La `canonical` de chaque
|
||||
page est l'URL de la langue par defaut. URLs construites depuis `site.base_url`
|
||||
et `site.path_prefix` — deterministe, aucune horloge.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import deps
|
||||
|
||||
|
||||
def _build_url(base: str, prefix: str, rel: str) -> str:
|
||||
"""base + prefixe de langue + chemin relatif, slashs normalises.
|
||||
|
||||
rel == "" -> page d'accueil (slash final conserve)."""
|
||||
pre = prefix.strip("/")
|
||||
segs = [s for s in (pre, rel.strip("/")) if s]
|
||||
path = "/".join(segs)
|
||||
if not rel:
|
||||
return base + "/" + (path + "/" if path else "")
|
||||
return base + "/" + path
|
||||
|
||||
|
||||
def _page(base: str, prefixes: dict, langs: list, default: str, xdef: str,
|
||||
name: str, rel: str) -> dict:
|
||||
alternates = [{"hreflang": lang, "href": _build_url(base, prefixes[lang], rel)}
|
||||
for lang in langs]
|
||||
alternates.append({"hreflang": "x-default",
|
||||
"href": _build_url(base, prefixes[xdef], rel)})
|
||||
return {
|
||||
"page": name,
|
||||
"canonical": _build_url(base, prefixes[default], rel),
|
||||
"alternates": alternates,
|
||||
}
|
||||
|
||||
|
||||
def generate(spec: dict, master: dict) -> dict:
|
||||
site = spec["site"]
|
||||
base = site["base_url"].rstrip("/")
|
||||
prefixes = site["path_prefix"]
|
||||
langs = site["langs"]
|
||||
default = site["default_lang"]
|
||||
xdef = site["x_default_lang"]
|
||||
|
||||
pages = [_page(base, prefixes, langs, default, xdef, "home", "")]
|
||||
for p in master["projets"]:
|
||||
slug = deps.slugify(p["nom"])
|
||||
pages.append(_page(base, prefixes, langs, default, xdef,
|
||||
p["code"], f"projets/{slug}"))
|
||||
|
||||
return {"base_url": base, "x_default_lang": xdef, "pages": pages}
|
||||
Reference in New Issue
Block a user