From 02e0559f560c43a795c0ad84733606eed57e8ddd Mon Sep 17 00:00:00 2001 From: PhilippTheServer Date: Thu, 24 Sep 2026 00:17:09 +0200 Subject: [PATCH] feat: add a German page at /de/ Closes #5 Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 8 ++++ _includes/head.html | 9 +++++ _layouts/default.html | 24 ++++++++---- assets/css/site.css | 1 + de/index.md | 89 +++++++++++++++++++++++++++++++++++++++++++ llms.txt | 2 + scripts/check_site.rb | 33 +++++++++++++++- 7 files changed, 157 insertions(+), 9 deletions(-) create mode 100644 de/index.md diff --git a/README.md b/README.md index bb20dd6..9011220 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@ Jekyll, is built and verified by GitHub Actions, and is deployed to GitHub Pages The project documentation remains in the [OpenTaberna wiki](https://wiki.opentaberna.de). +## Languages + +`index.md` is the English page at `/`, `de/index.md` the German page at `/de/`. +Both carry `hreflang` alternates and a language switch; the layout picks its few +interface strings from the page's `lang`. A content change to one page belongs in +the other in the same change. `check_site.rb` fails if the German page, its +alternates or its search terms go missing. + ## Local verification Install Ruby 3.3 and Bundler, then run: diff --git a/_includes/head.html b/_includes/head.html index 2ae8ef5..b59c431 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -9,6 +9,9 @@ + + + @@ -17,7 +20,13 @@ + {%- if page.lang == "de" %} + + + {%- else %} + + {%- endif %} diff --git a/_layouts/default.html b/_layouts/default.html index 0b9c220..23bdf99 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -1,18 +1,26 @@ - +{%- assign de = page.lang == "de" -%} + {%- include head.html -%} - +
- + OpenTaberna - Open-source commerce + {% if de %}Open-Source-E-Commerce{% else %}Open-source commerce{% endif %} - GitHub +
@@ -22,14 +30,14 @@
-

Headless commerce, open from end to end.

+

{% if de %}Headless-Commerce, offen von Anfang bis Ende.{% else %}Headless commerce, open from end to end.{% endif %}

- +

llms.txt · sitemap.xml

- +

{{ site.organization.email }}

diff --git a/assets/css/site.css b/assets/css/site.css index a4343cd..bf4d949 100644 --- a/assets/css/site.css +++ b/assets/css/site.css @@ -93,6 +93,7 @@ a:hover { text-decoration-thickness: 2px; } .brand > span { display: grid; } .brand-name { font-weight: 720; letter-spacing: -0.02em; line-height: 1.2; } .brand-note { color: var(--fg-muted); font-family: var(--mono); font-size: 0.7rem; } +.header-nav { display: flex; gap: 1.25rem; } .header-link { color: var(--fg-muted); font-size: 0.92rem; text-decoration: none; } .header-link:hover { color: var(--fg); } diff --git a/de/index.md b/de/index.md new file mode 100644 index 0000000..9ffbf2e --- /dev/null +++ b/de/index.md @@ -0,0 +1,89 @@ +--- +layout: default +lang: de +title: Open-Source-Shopsystem, headless und selbst gehostet +permalink: /de/ +description: >- + OpenTaberna ist ein Open-Source-Shopsystem, headless und selbst gehostet: Baue + deinen eigenen modernen Webshop und automatisiere dein E-Commerce von Anfang bis + Ende. Eine freie Shopware-Alternative. +--- + +
+
+

Open-Source-E-Commerce, selbst gehostet

+

Das Open-Source-Shopsystem, das wirklich dir gehört.

+

OpenTaberna ist eine moderne, selbst gehostete Webshop-Plattform: Headless-E-Commerce, durchgehend Open Source, das den Ablauf im Onlinehandel von Anfang bis Ende automatisiert.

+
+ +
+ +## Was OpenTaberna ist + +Wir haben OpenTaberna gestartet, weil Shopware teuer ist und sich mit kaum etwas +verbinden ließ, das wir anbinden mussten. Also haben wir eine Open-Source-Alternative +zu Shopware gebaut. OpenTaberna trennt Storefront, Verwaltung und Backend und stellt +die Automatisierung in den Mittelpunkt: vom Katalog über Checkout und Lagerbestand bis +zu Zahlung und Versand. + +Es ist ein Headless-Shop von Grund auf und standardmäßig selbst gehostet. Du betreibst +ihn auf deinen eigenen Servern, wählst Schnittstellen, Dienste und Deployment selbst +und baust den individuellen Webshop, den dein Geschäft braucht, statt deinen Betrieb +an ein geschlossenes Produkt anzupassen. + +## Woraus es besteht + +
    +
  • +

    fastapi

    +

    Das Python-Backend verantwortet API, Commerce-Domäne, Integrationen und den automatisierten Bestellablauf.

    +
  • +
  • +

    frontend

    +

    Die Angular-Storefront bietet Kundinnen und Kunden Katalog, Konto, Warenkorb und Checkout.

    +
  • +
  • +

    admin_frontend

    +

    Das rollengeschützte Backoffice verwaltet Produkte, Lagerbestand, Bestellungen und Retouren.

    +
  • +
  • +

    wiki

    +

    Das Dokumentations-Repository ist die einzige verbindliche Quelle für Einrichtung, Architektur und Betrieb.

    +
  • +
+ +## So fängst du an + +
+

Beginne mit der Dokumentation

+

Lies das OpenTaberna-Wiki und folge dann dem versionierten Getting-Started-Guide (auf Englisch).

+

Die Einrichtungsanleitung steht dort und nicht hier, damit das Wiki die eine aktuelle Quelle bleibt.

+
+ +## Lizenz und Absicht + +OpenTaberna ist vollständig Open Source. Wir wollen mit dem Projekt kein Geld verdienen: +Du darfst es betreiben, forken, für deine eigenen Zwecke pflegen oder weiterverkaufen, +im Rahmen der Lizenzen in den jeweiligen Repositories. + +## Gründer + +
+ + +
+ +## Kontakt + +Fragen, Zusammenarbeit und Anfragen zum Projekt gern an +[root@vaultops.de](mailto:root@vaultops.de). diff --git a/llms.txt b/llms.txt index 900ba19..96edea4 100644 --- a/llms.txt +++ b/llms.txt @@ -7,6 +7,8 @@ sitemap: false > OpenTaberna is an open-source, self-hosted headless shop system: build a modern, custom web shop and automate e-commerce end to end. A free Shopware alternative. The project exists as an open alternative to expensive, hard-to-integrate commerce platforms such as Shopware. +A German version of the website is at {{ site.url }}/de/. + ## Project repositories - [fastapi](https://github.com/OpenTaberna/fastapi): Python backend for the API, commerce domain, integrations and automated order workflow. diff --git a/scripts/check_site.rb b/scripts/check_site.rb index e7caf3e..7a4327c 100755 --- a/scripts/check_site.rb +++ b/scripts/check_site.rb @@ -40,7 +40,7 @@ def internal_target(reference) end required = %w[ - index.html robots.txt llms.txt sitemap.xml CNAME + index.html de/index.html robots.txt llms.txt sitemap.xml CNAME assets/css/site.css wiki/taberna_logo.png ] required.each do |path| @@ -62,6 +62,37 @@ def internal_target(reference) if sitemap && !sitemap.include?("https://#{DOMAIN}/") fail!("sitemap.xml: does not contain the canonical site URL") end +if sitemap && !sitemap.include?("https://#{DOMAIN}/de/") + fail!("sitemap.xml: does not contain the German page") +end + +languages = { + "index.html" => { lang: "en", locale: "en_GB", switch: "/de/" }, + "de/index.html" => { lang: "de", locale: "de_DE", switch: "/" }, +} +languages.each do |path, expected| + html = read(path) + next unless html + + fail!("#{path}: is not lang=\"#{expected[:lang]}\"") unless html.include?(%()) + fail!("#{path}: og:locale is not #{expected[:locale]}") unless html.include?(%()) + { "en" => "https://#{DOMAIN}/", "de" => "https://#{DOMAIN}/de/", "x-default" => "https://#{DOMAIN}/" }.each do |hreflang, href| + unless html.include?(%()) + fail!("#{path}: has lost the hreflang=#{hreflang} alternate") + end + end + fail!("#{path}: has lost the language switch to #{expected[:switch]}") unless html.match?(/]*href="#{Regexp.escape(expected[:switch])}"/) +end + +german = read("de/index.html") +if german + h1 = german[%r{]*>(.*?)}m, 1].to_s.downcase + %w[open-source shopsystem].each { |term| fail!("de/index.html: h1 has lost #{term.inspect}") unless h1.include?(term) } + description = german[/