From 45ef66e3bf22fddcbbf86dc2cd740bbb7733aa58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Eckel?= Date: Tue, 21 Apr 2026 14:41:51 +0200 Subject: [PATCH 1/2] Enhance SEO and metadata across multiple pages - Added Open Graph and Twitter Card metadata to kern/for-communities.html, kern/for-platforms.html, kern/for-utilities.html, and kern/index.html to improve social media sharing. - Introduced structured data in JSON-LD format to kern/index.html for better search engine understanding. - Created llms.txt to provide an overview of Riddle&Code and its products, enhancing discoverability. - Implemented a robots.txt file to manage crawler access and included sitemap for improved indexing. - Updated references/index.html and technology/index.html with new metadata for consistency. - Ensured canonical links are present in all relevant templates to prevent duplicate content issues. --- build.py | 58 +++++++++- company/about-us.html | 2 + company/career.html | 2 + company/get-in-touch.html | 2 + company/media.html | 2 + company/news.html | 2 + de/company/about-us.html | 2 + de/company/career.html | 2 + de/company/get-in-touch.html | 2 + de/company/media.html | 2 + de/company/news.html | 2 + de/index.html | 46 ++++++++ de/kern/for-aggregators.html | 6 ++ de/kern/for-communities.html | 6 ++ de/kern/for-platforms.html | 6 ++ de/kern/for-utilities.html | 6 ++ de/kern/index.html | 36 +++++++ de/references/index.html | 6 ++ de/technology/index.html | 6 ++ index.html | 46 ++++++++ kern/for-aggregators.html | 6 ++ kern/for-communities.html | 6 ++ kern/for-platforms.html | 6 ++ kern/for-utilities.html | 6 ++ kern/index.html | 36 +++++++ llms.txt | 38 +++++++ references/index.html | 6 ++ robots.txt | 25 +++++ sitemap.xml | 160 ++++++++++++++++++++++++++++ technology/index.html | 6 ++ templates/company/about-us.html | 2 + templates/company/career.html | 2 + templates/company/get-in-touch.html | 2 + templates/company/media.html | 2 + templates/company/news.html | 2 + templates/index.html | 46 ++++++++ templates/kern/for-aggregators.html | 6 ++ templates/kern/for-communities.html | 6 ++ templates/kern/for-platforms.html | 6 ++ templates/kern/for-utilities.html | 6 ++ templates/kern/index.html | 36 +++++++ templates/references/index.html | 6 ++ templates/technology/index.html | 6 ++ 43 files changed, 663 insertions(+), 2 deletions(-) create mode 100644 llms.txt create mode 100644 robots.txt create mode 100644 sitemap.xml diff --git a/build.py b/build.py index 9f114ad..5734c9e 100644 --- a/build.py +++ b/build.py @@ -24,6 +24,7 @@ ROOT = Path(__file__).parent TEMPLATES_DIR = ROOT / "templates" LOCALES_DIR = ROOT / "locales" +BASE_URL = "https://riddleandcode.com" # Maps language code → output directory LANGS = { @@ -32,6 +33,56 @@ } +def get_canonical_url(tmpl_path: Path) -> str | None: + """Return the canonical EN URL for a template, or None for partials.""" + rel = str(tmpl_path.relative_to(TEMPLATES_DIR)).replace("\\", "/") + if rel.startswith("includes/"): + return None + if rel == "index.html": + return f"{BASE_URL}/" + if rel.endswith("/index.html"): + return f"{BASE_URL}/{rel[:-len('index.html')]}" + return f"{BASE_URL}/{rel}" + + +def build_sitemap() -> None: + """Generate sitemap.xml with bilingual hreflang annotations.""" + templates = sorted(TEMPLATES_DIR.rglob("*.html")) + entries = [] + for tmpl_path in templates: + en_url = get_canonical_url(tmpl_path) + if en_url is None: + continue + rel = str(tmpl_path.relative_to(TEMPLATES_DIR)).replace("\\", "/") + if rel == "index.html": + de_url = f"{BASE_URL}/de/" + elif rel.endswith("/index.html"): + de_url = f"{BASE_URL}/de/{rel[:-len('index.html')]}" + else: + de_url = f"{BASE_URL}/de/{rel}" + + for loc in (en_url, de_url): + entries.append( + f" \n" + f" {loc}\n" + f" \n" + f" \n" + f" \n" + f" " + ) + + xml = ( + '\n' + '\n' + + "\n".join(entries) + + "\n\n" + ) + out = ROOT / "sitemap.xml" + out.write_text(xml, encoding="utf-8") + print(f" [sitemap] → sitemap.xml ({len(entries)} URLs)") + + def render(template: str, strings: dict) -> str: """Replace {{ key }} placeholders with values from strings dict.""" def replace(m): @@ -73,7 +124,8 @@ def build() -> int: source = tmpl_path.read_text(encoding="utf-8") for lang, out_dir in LANGS.items(): - strings = {**locales[lang], "lang": lang} + canonical = get_canonical_url(tmpl_path) + strings = {**locales[lang], "lang": lang, "canonical_url": canonical or ""} rendered = render(source, strings) out_path = out_dir / rel @@ -83,6 +135,7 @@ def build() -> int: print(f" [{lang}] {rel} → {out_path.relative_to(ROOT)}") built += 1 + build_sitemap() return built @@ -97,7 +150,8 @@ def check_mode(): source = tmpl_path.read_text(encoding="utf-8") for lang, real_dir in LANGS.items(): - strings = {**locales[lang], "lang": lang} + canonical = get_canonical_url(tmpl_path) + strings = {**locales[lang], "lang": lang, "canonical_url": canonical or ""} rendered = render(source, strings) real_file = real_dir / rel diff --git a/company/about-us.html b/company/about-us.html index b1da564..a7aaed7 100644 --- a/company/about-us.html +++ b/company/about-us.html @@ -7,11 +7,13 @@ + + diff --git a/company/career.html b/company/career.html index 4b7c9c2..2ce0a03 100644 --- a/company/career.html +++ b/company/career.html @@ -7,11 +7,13 @@ + + diff --git a/company/get-in-touch.html b/company/get-in-touch.html index e5b1a0e..289cea4 100644 --- a/company/get-in-touch.html +++ b/company/get-in-touch.html @@ -7,11 +7,13 @@ + + diff --git a/company/media.html b/company/media.html index 48940ae..18b1a8a 100644 --- a/company/media.html +++ b/company/media.html @@ -7,11 +7,13 @@ + + diff --git a/company/news.html b/company/news.html index d399b64..bb1d3fe 100644 --- a/company/news.html +++ b/company/news.html @@ -7,11 +7,13 @@ + +