This commit is contained in:
2025-11-29 01:57:38 +01:00
parent cc7ec65685
commit d63acce8f7
3 changed files with 226 additions and 117 deletions

View File

@@ -1,10 +1,8 @@
<?php
// partials/structure/header.php
// Aktuelle Domain + Protokoll
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? app_primary_domain();
$baseUrl = $scheme . '://' . $host;
// Aktuelle Basis-URL der laufenden Instanz (staging, prod, etc.)
$baseUrl = app_current_base_url();
// Aktueller Page-Key (z.B. 'landing', 'fakecheck', 'dashboard')
$pageKey = $GLOBALS['pageKey'] ?? null;
@@ -84,7 +82,7 @@ $currentLangLabel = $currentLangInfo['label'] ?? $currentLangCode;
// -----------------------------------------
// Helper: URL mit anderem ?lang=.. bauen
// -----------------------------------------
$currentPath = strtok($_SERVER['REQUEST_URI'] ?? '/', '?');
$currentPath = app_current_path();
$currentQuery = $_GET ?? [];
function build_lang_url(string $code, string $path, array $query): string
@@ -95,8 +93,7 @@ function build_lang_url(string $code, string $path, array $query): string
}
?>
<header class="sticky top-0 z-40 border-b border-brand-border/70 backdrop-blur bg-brand-bg/85">
<div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 flex items-center justify-between min-h-16 py-2">
<div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 flex items-center justify-between min-h-16 py-2">
<!-- Logo -->
<div class="flex items-center gap-3">
@@ -120,27 +117,23 @@ function build_lang_url(string $code, string $path, array $query): string
<div class="flex items-center gap-6">
<!-- Hauptnavigation -->
<!-- Hauptnavigation -->
<?php if (!empty($navAnchors)): ?>
<nav class="flex flex-wrap items-center gap-x-4 gap-y-1 sm:gap-x-6 text-xs font-medium text-brand-muted uppercase tracking-[0.18em]">
<?php foreach ($navAnchors as $item): ?>
<?php
$href = $item['href'] ?? '#';
$label = $item['label'] ?? '';
$i18nKey = $item['i18n'] ?? '';
?>
<a href="<?= htmlspecialchars($href) ?>"
class="hover:text-brand-primary transition-colors"
<?php if ($i18nKey !== ''): ?>
data-i18n="<?= htmlspecialchars($i18nKey) ?>"
<?php endif; ?>
><?= htmlspecialchars($label) ?></a>
<?php endforeach; ?>
</nav>
<?php endif; ?>
<?php if (!empty($navAnchors)): ?>
<nav class="flex flex-wrap items-center gap-x-4 gap-y-1 sm:gap-x-6 text-xs font-medium text-brand-muted uppercase tracking-[0.18em]">
<?php foreach ($navAnchors as $item): ?>
<?php
$href = $item['href'] ?? '#';
$label = $item['label'] ?? '';
$i18nKey = $item['i18n'] ?? '';
?>
<a href="<?= htmlspecialchars($href) ?>"
class="hover:text-brand-primary transition-colors"
<?php if ($i18nKey !== ''): ?>
data-i18n="<?= htmlspecialchars($i18nKey) ?>"
<?php endif; ?>
><?= htmlspecialchars($label) ?></a>
<?php endforeach; ?>
</nav>
<?php endif; ?>
<!-- Language Switcher -->
<div class="relative">

View File

@@ -3,11 +3,9 @@
// Erwartet (vor require):
// - $pageKey (string) Seiten-Key für i18n, z. B. 'landing', 'fakecheck', 'login', 'dashboard'
// - $lang (2-letter ISO, z. B. 'de', 'en', 'it', 'fr'), möglichst bereits aus fileload.php
// - optional: $pageTitle (string)
// - optional: $pageDescription (string)
// - optional: $canonical (string)
// - optional: $userInitials (string|null)
// -----------------------------------------------------------
// Fallbacks & i18n Title/Description
@@ -21,45 +19,39 @@ if (!isset($pageKey) || !is_string($pageKey) || $pageKey === '') {
$pageKey = 'landing';
}
// Sprache: erst lokale $lang prüfen, sonst global aus fileload.php, dann Fallback
if (!isset($lang) || !isset($availableLangs[$lang])) {
$lang = $GLOBALS['lang'] ?? (array_key_first($availableLangs) ?: 'en');
}
// Sprache: aus Globals (fileload.php) bzw. Fallback
$lang = $GLOBALS['lang'] ?? (array_key_first($availableLangs) ?: 'en');
// Title aus i18n, falls nichts explizit gesetzt wurde
if (!isset($pageTitle) || !is_string($pageTitle) || $pageTitle === '') {
// pages.{pageKey}.meta.title
$pageTitle = i18n_get("pages.$pageKey.meta.title", app_primary_domain());
}
// Description aus i18n, falls nichts explizit gesetzt wurde
if (!isset($pageDescription) || !is_string($pageDescription) || $pageDescription === '') {
// pages.{pageKey}.meta.description
$pageDescription = i18n_get("pages.$pageKey.meta.description", '');
}
// -----------------------------------------------------------
// Standard-Script für Header-Interaktionen
// Standard-Scripts für Header-Interaktionen (Footer-Scripts)
// -----------------------------------------------------------
if (function_exists('tpl_add_script')) {
// header.js kommt wie gehabt in den Footer
tpl_add_script('/assets/js/header.js', 'footer', true, false, '', null);
tpl_add_script('/assets/js/lang.js', 'footer', true, false, '', null);
}
if (function_exists('tpl_add_script')) {
// header.js kommt wie gehabt in den Footer
tpl_add_script('/assets/js/lang.js', 'footer', true, false, '', null);
}
// -----------------------------------------------------------
// Canonical-URL bestimmen
// -----------------------------------------------------------
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? app_primary_domain();
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
// Wenn $canonical gesetzt → verwenden, sonst aktuelle URL ohne Query-String
$effectiveCanonical = isset($canonical) && is_string($canonical) && $canonical !== ''
? $canonical
: ($scheme . '://' . $host . strtok($requestUri, '?'));
// -----------------------------------------------------------
// Globales CSS registrieren (z.B. main.css)
// → Priority 'late', damit es Tailwind überschreiben kann
// -----------------------------------------------------------
if (function_exists('tpl_add_style')) {
tpl_add_style('/assets/css/main.css', 'header', 'late'); // < Pfad ist korrekt, relativ zum Webroot
}
// -----------------------------------------------------------
// Canonical-URL bestimmen (zentral über Helper)
// -----------------------------------------------------------
$effectiveCanonical = app_canonical_url($canonical ?? null);
?>
<!DOCTYPE html>
@@ -79,47 +71,12 @@ $effectiveCanonical = isset($canonical) && is_string($canonical) && $canonical !
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Montserrat:wght@600;700;800&display=swap" rel="stylesheet">
<?php
// App-Config (usbConfig + i18n.available/current) ins Fenster schreiben
tpl('app_config', 'structure');
// CSS im Header aus der zentralen Registry
foreach ($GLOBALS['page_styles'] as $style) {
if (($style['pos'] ?? 'header') !== 'header') {
continue;
}
$href = $style['href'];
if (!empty($style['version'])) {
$href .= (str_contains($href, '?') ? '&' : '?') . 'v=' . urlencode($style['version']);
}
echo '<link rel="stylesheet" href="' . htmlspecialchars($href) . '">' . PHP_EOL;
}
// Scripts im Header aus der zentralen Registry
foreach ($GLOBALS['page_header_scripts'] as $script) {
$src = $script['src'];
if (!empty($script['version'])) {
$src .= (str_contains($src, '?') ? '&' : '?') . 'v=' . urlencode($script['version']);
}
$attr = '';
if (!empty($script['async'])) {
$attr .= ' async';
} elseif (!empty($script['defer'])) {
$attr .= ' defer';
}
if (!empty($script['type'])) {
$attr .= ' type="' . htmlspecialchars($script['type']) . '"';
}
echo '<script src="' . htmlspecialchars($src) . '"' . $attr . '></script>' . PHP_EOL;
}
?>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Montserrat:wght@600;700;800&display=swap"
rel="stylesheet"
>
<!-- Tailwind Config -->
<script>
window.tailwind = window.tailwind || {};
window.tailwind.config = {
@@ -148,11 +105,78 @@ $effectiveCanonical = isset($canonical) && is_string($canonical) && $canonical !
}
};
</script>
<!-- Tailwind (Dev) -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Eigenes CSS -->
<link rel="stylesheet" href="/assets/css/main.css">
<?php
// App-Config (usbConfig + i18n.available/current) ins Fenster schreiben
tpl('app_config', 'structure');
// -------------------------------------------------------
// CSS im Header aus der zentralen Registry
// -------------------------------------------------------
$styles = $GLOBALS['page_styles'] ?? [];
if (!empty($styles)) {
usort($styles, function ($a, $b) {
$order = ['early' => 0, 'normal' => 1, 'late' => 2];
$pa = $order[$a['priority'] ?? 'normal'] ?? 1;
$pb = $order[$b['priority'] ?? 'normal'] ?? 1;
return $pa <=> $pb;
});
foreach ($styles as $s) {
$href = $s['href'] ?? '';
$version = $s['version'] ?? null;
if ($href === '') {
continue;
}
// Cache-Buster nur, wenn Version explizit gesetzt und nicht leer
if ($version !== null && $version !== '') {
$separator = (strpos($href, '?') === false) ? '?' : '&';
$href .= $separator . 'v=' . rawurlencode($version);
}
echo '<link rel="stylesheet" href="' . htmlspecialchars($href) . '">' . "\n";
}
}
// -------------------------------------------------------
// Scripts im Header aus der zentralen Registry
// -------------------------------------------------------
$headerScripts = $GLOBALS['page_header_scripts'] ?? [];
foreach ($headerScripts as $script) {
$src = $script['src'] ?? '';
$version = $script['version'] ?? null;
if ($src === '') {
continue;
}
if ($version !== null && $version !== '') {
$src .= (str_contains($src, '?') ? '&' : '?') . 'v=' . urlencode($version);
}
$attr = '';
if (!empty($script['async'])) {
$attr .= ' async';
} elseif (!empty($script['defer'])) {
$attr .= ' defer';
}
if (!empty($script['type'])) {
$attr .= ' type="' . htmlspecialchars($script['type']) . '"';
}
echo '<script src="' . htmlspecialchars($src) . '"' . $attr . '></script>' . PHP_EOL;
}
?>
</head>
<body class="bg-brand-bg text-brand-text font-sans antialiased scroll-smooth">