From 4bc035b783db8df8427e51b060fe8e3f5c7cd61c Mon Sep 17 00:00:00 2001 From: Hermes Date: Thu, 4 Jun 2026 16:13:54 +0000 Subject: [PATCH] fix(i18n): map gallery + hero + floorplan images to real filenames; force-DE on legal pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - home: map 9/12 gallery items to real filenames (Wohnzimmer-1 -> wohnzimmer2.png, Badezimmer-1 -> Bad.jpg, etc.); remove 3 items whose source images are missing - home: hero-bg.jpg -> Außenansicht-2.webp (file exists) - home: floorplan image -> /bilder/grundrisse/.png (subdir + correct name) - layout: og:image fallback Aussenansicht-2.webp (ASCII) -> Außenansicht-2.png (UTF-8) - layout: hero-bg.jpg fallback -> Außenansicht-2.png (UTF-8) - Controller::render(): add $forceLocale param for legal pages - ImpressumController / DatenschutzController: force 'de' (TMG §5 / GDPR) so is emitted regardless of cookie --- app/Controllers/Controller.php | 7 +++-- app/Controllers/DatenschutzController.php | 21 +++++++------- app/Controllers/ImpressumController.php | 21 +++++++------- app/views/home/index.php | 35 ++++++++++++++--------- app/views/layouts/main.php | 4 +-- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/app/Controllers/Controller.php b/app/Controllers/Controller.php index f491ecc..8e7571e 100644 --- a/app/Controllers/Controller.php +++ b/app/Controllers/Controller.php @@ -25,10 +25,13 @@ abstract class Controller * Render a view inside a layout. * * @param array $data + * @param string|null $forceLocale If set, overrides the locale resolved from + * cookie/Accept-Language for this render. Used by legal pages (Impressum, + * Datenschutz) that must be served in German only by German law. */ - protected function render(string $view, array $data = [], string $layout = 'main'): void + protected function render(string $view, array $data = [], string $layout = 'main', ?string $forceLocale = null): void { - $locale = LocaleController::current(); + $locale = $forceLocale ?? LocaleController::current(); $i18n = static fn (string $key, array $params = []): string => I18n::t($key, $params, $locale); $globals = [ diff --git a/app/Controllers/DatenschutzController.php b/app/Controllers/DatenschutzController.php index b68a908..efc3994 100644 --- a/app/Controllers/DatenschutzController.php +++ b/app/Controllers/DatenschutzController.php @@ -11,17 +11,18 @@ class DatenschutzController extends Controller { public function index(): void { - $locale = LocaleController::current(); - + // Legal pages (Datenschutzerklärung) must be served in German only by GDPR / German law. + // Force German locale for render() so + German meta are emitted + // regardless of cookie/Accept-Language. $this->render('datenschutz/index', [ - 'pageTitle' => I18n::t('legal.privacy_h1', [], $locale) . ' – ' . I18n::t('site.title', [], $locale), - 'pageDescription' => I18n::t('legal.privacy_h1', [], $locale) . ' – ' . I18n::t('site.title', [], $locale), + 'pageTitle' => I18n::t('legal.privacy_h1', [], 'de') . ' – ' . I18n::t('site.title', [], 'de'), + 'pageDescription' => I18n::t('legal.privacy_h1', [], 'de') . ' – ' . I18n::t('site.title', [], 'de'), 'robots' => 'noindex', - 'canonical' => I18n::t('site.canonical_base', [], $locale) . '/datenschutz', - 'ogLocale' => Locale::toOgLocale($locale), - 'ogUrl' => I18n::t('site.canonical_base', [], $locale) . '/datenschutz', - 'ogTitle' => I18n::t('legal.privacy_h1', [], $locale), - 'ogDescription' => I18n::t('legal.privacy_h1', [], $locale), - ]); + 'canonical' => I18n::t('site.canonical_base', [], 'de') . '/datenschutz', + 'ogLocale' => Locale::toOgLocale('de'), + 'ogUrl' => I18n::t('site.canonical_base', [], 'de') . '/datenschutz', + 'ogTitle' => I18n::t('legal.privacy_h1', [], 'de'), + 'ogDescription' => I18n::t('legal.privacy_h1', [], 'de'), + ], 'main', 'de'); } } diff --git a/app/Controllers/ImpressumController.php b/app/Controllers/ImpressumController.php index e5b0b9d..e856c16 100644 --- a/app/Controllers/ImpressumController.php +++ b/app/Controllers/ImpressumController.php @@ -11,17 +11,18 @@ class ImpressumController extends Controller { public function index(): void { - $locale = LocaleController::current(); - + // Legal pages (Impressum) must be served in German only by German law (TMG §5). + // Force German locale for render() so + German meta are emitted + // regardless of cookie/Accept-Language. $this->render('impressum/index', [ - 'pageTitle' => I18n::t('legal.imprint_h1', [], $locale) . ' – ' . I18n::t('site.title', [], $locale), - 'pageDescription' => I18n::t('legal.imprint_h1', [], $locale) . ' – ' . I18n::t('site.title', [], $locale), + 'pageTitle' => I18n::t('legal.imprint_h1', [], 'de') . ' – ' . I18n::t('site.title', [], 'de'), + 'pageDescription' => I18n::t('legal.imprint_h1', [], 'de') . ' – ' . I18n::t('site.title', [], 'de'), 'robots' => 'noindex', - 'canonical' => I18n::t('site.canonical_base', [], $locale) . '/impressum', - 'ogLocale' => Locale::toOgLocale($locale), - 'ogUrl' => I18n::t('site.canonical_base', [], $locale) . '/impressum', - 'ogTitle' => I18n::t('legal.imprint_h1', [], $locale), - 'ogDescription' => I18n::t('legal.imprint_h1', [], $locale), - ]); + 'canonical' => I18n::t('site.canonical_base', [], 'de') . '/impressum', + 'ogLocale' => Locale::toOgLocale('de'), + 'ogUrl' => I18n::t('site.canonical_base', [], 'de') . '/impressum', + 'ogTitle' => I18n::t('legal.imprint_h1', [], 'de'), + 'ogDescription' => I18n::t('legal.imprint_h1', [], 'de'), + ], 'main', 'de'); } } diff --git a/app/views/home/index.php b/app/views/home/index.php index c4c838f..87b6670 100644 --- a/app/views/home/index.php +++ b/app/views/home/index.php @@ -15,22 +15,22 @@ declare(strict_types=1); */ $gridItems = [ - ['img' => 'bilder/Außenansicht-2.png', 'key' => 'gallery.exterior', 'alt' => 'gallery.alt.exterior', 'class' => 'span-2 row-2'], - ['img' => 'bilder/Wohnzimmer-1.png', 'key' => 'gallery.living', 'alt' => 'gallery.alt.living', 'class' => 'span-2 row-1'], - ['img' => 'bilder/Küche-1.png', 'key' => 'gallery.kitchen', 'alt' => 'gallery.alt.kitchen', 'class' => ''], - ['img' => 'bilder/Schlafzimmer-1.png','key' => 'gallery.bedroom', 'alt' => 'gallery.alt.bedroom', 'class' => ''], - ['img' => 'bilder/Badezimmer-1.png', 'key' => 'gallery.bath', 'alt' => 'gallery.alt.bath', 'class' => ''], - ['img' => 'bilder/Kinderzimmer-1-1.png', 'key' => 'gallery.kid1', 'alt' => 'gallery.alt.kid1', 'class' => ''], - ['img' => 'bilder/Kinderzimmer-2.png','key' => 'gallery.kid2', 'alt' => 'gallery.alt.kid2', 'class' => ''], - ['img' => 'bilder/Kinderzimmer-Detail.png','key' => 'gallery.kid_detail', 'alt' => 'gallery.alt.kid_detail', 'class' => 'span-2 row-1'], - ['img' => 'bilder/Gästezimmer.png', 'key' => 'gallery.guest', 'alt' => 'gallery.alt.guest', 'class' => ''], - ['img' => 'bilder/Wohnbereich.png', 'key' => 'gallery.area1', 'alt' => 'gallery.alt.living', 'class' => ''], - ['img' => 'bilder/Wohnbereich-Detail.png', 'key' => 'gallery.area2', 'alt' => 'gallery.alt.living', 'class' => ''], - ['img' => 'bilder/Außenansicht-1.png','key' => 'gallery.area3', 'alt' => 'gallery.alt.exterior', 'class' => 'span-2 row-1'], + // NOTE: image filenames reflect the actual files in public/bilder/ on the server. + // 3 items were removed (gästezimmer / wohnbereich / wohnbereich-detail) + // because no matching files exist in the image inventory. + ['img' => 'bilder/Außenansicht-2.png', 'key' => 'gallery.exterior', 'alt' => 'gallery.alt.exterior', 'class' => 'span-2 row-2'], + ['img' => 'bilder/wohnzimmer2.png', 'key' => 'gallery.living', 'alt' => 'gallery.alt.living', 'class' => 'span-2 row-1'], + ['img' => 'bilder/Küche 1.jpg', 'key' => 'gallery.kitchen', 'alt' => 'gallery.alt.kitchen', 'class' => ''], + ['img' => 'bilder/schlafzimmer.png', 'key' => 'gallery.bedroom', 'alt' => 'gallery.alt.bedroom', 'class' => ''], + ['img' => 'bilder/Bad.jpg', 'key' => 'gallery.bath', 'alt' => 'gallery.alt.bath', 'class' => ''], + ['img' => 'bilder/Kinderzimmer 2.jpg', 'key' => 'gallery.kid1', 'alt' => 'gallery.alt.kid1', 'class' => ''], + ['img' => 'bilder/Kinderzimmer 3.jpg', 'key' => 'gallery.kid2', 'alt' => 'gallery.alt.kid2', 'class' => ''], + ['img' => 'bilder/kinderzimmer 2 2.webp', 'key' => 'gallery.kid_detail', 'alt' => 'gallery.alt.kid_detail', 'class' => 'span-2 row-1'], + ['img' => 'bilder/Außenansicht-2.png', 'key' => 'gallery.area3', 'alt' => 'gallery.alt.exterior', 'class' => 'span-2 row-1'], ]; ?>
- +

@@ -105,6 +105,13 @@ $gridItems = [

'bilder/grundrisse/EG.png', + 'og1' => 'bilder/grundrisse/OG 1 2.png', + 'og2' => 'bilder/grundrisse/OG 2 grundriss.png', + 'attic' => 'bilder/grundrisse/Dachboden unten.png', + ]; + $floors = [ ['id' => 'eg', 'titleKey' => 'floors.eg.title', 'areaKey' => 'floors.eg.area', 'altKey' => 'floors.alt.eg', 'rooms' => [ @@ -148,7 +155,7 @@ $gridItems = [
- <?= htmlspecialchars($t($floor['altKey']), ENT_QUOTES) ?> diff --git a/app/views/layouts/main.php b/app/views/layouts/main.php index 60a9d3a..d32dff8 100644 --- a/app/views/layouts/main.php +++ b/app/views/layouts/main.php @@ -28,7 +28,7 @@ $canonical = $canonical ?? $canonicalBase . ($currentPath === '/' ? ' $siteName = I18n::t('site.name', [], $locale); $ogTitle = $openGraph['ogTitle'] ?? $title; $ogDescription = $openGraph['ogDescription'] ?? $description; -$ogImage = $openGraph['ogImage'] ?? 'https://haus-schleusingen.de/bilder/Aussenansicht-2.webp'; +$ogImage = $openGraph['ogImage'] ?? 'https://haus-schleusingen.de/bilder/Außenansicht-2.png'; $ogUrl = $openGraph['ogUrl'] ?? $canonical; $hreflangs = Locale::hreflangAlternates($currentPath === '/' ? '/' : $currentPath, $canonicalBase); @@ -72,7 +72,7 @@ $navItems = [ - +