Files
usbcheck.it/partials/structure/layout_start.php
2025-11-29 02:24:11 +01:00

193 lines
6.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// public/partials/layout_start.php
// Erwartet (vor require):
// - $pageKey (string) Seiten-Key für i18n, z. B. 'landing', 'fakecheck', 'login', 'dashboard'
// - optional: $pageTitle (string)
// - optional: $pageDescription (string)
// - optional: $canonical (string)
// -----------------------------------------------------------
// Fallbacks & i18n Title/Description
// -----------------------------------------------------------
// Sprachen **immer** aus den GLOBALS holen (aus fileload.php)
$availableLangs = $GLOBALS['availableLangs'] ?? [];
// Page-Key Fallback
if (!isset($pageKey) || !is_string($pageKey) || $pageKey === '') {
$pageKey = 'landing';
}
// 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 === '') {
$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 === '') {
$pageDescription = i18n_get("pages.$pageKey.meta.description", '');
}
// -----------------------------------------------------------
// Standard-Scripts für Header-Interaktionen (Footer-Scripts)
// -----------------------------------------------------------
if (function_exists('tpl_add_script')) {
tpl_add_script('/assets/js/header.js', 'footer', true, false, '', null);
tpl_add_script('/assets/js/lang.js', 'footer', true, false, '', null);
}
// -----------------------------------------------------------
// 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/base.css', 'early');
tpl_add_style('/assets/css/layout-main.css', 'normal');
tpl_add_style('/assets/css/header-extras.css', 'late');
}
// -----------------------------------------------------------
// Canonical-URL bestimmen (zentral über Helper)
// -----------------------------------------------------------
$effectiveCanonical = app_canonical_url($canonical ?? null);
?>
<!DOCTYPE html>
<html lang="<?= htmlspecialchars($lang) ?>">
<head>
<meta charset="UTF-8">
<title><?= htmlspecialchars($pageTitle) ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php if ($pageDescription !== ''): ?>
<meta name="description" content="<?= htmlspecialchars($pageDescription) ?>">
<?php endif; ?>
<!-- Canonical URL -->
<link rel="canonical" href="<?= htmlspecialchars($effectiveCanonical) ?>">
<!-- 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"
>
<!-- Tailwind Config -->
<script>
window.tailwind = window.tailwind || {};
window.tailwind.config = {
theme: {
extend: {
colors: {
'brand-primary': '#3a6ff8',
'brand-primarySoft': '#e8f1ff',
'brand-border': '#dfe6f4',
'brand-bg': '#f9fbff',
'brand-surface': '#ffffff',
'brand-text': '#0f1f3d',
'brand-muted': '#5f6b85'
},
fontFamily: {
heading: ['"Montserrat"', '"Plus Jakarta Sans"', '"Inter"', 'system-ui', 'sans-serif']
},
borderRadius: {
xl2: '1.75rem',
xl3: '2.25rem'
},
boxShadow: {
soft: '0 18px 45px rgba(58, 111, 248, 0.18)'
}
}
}
};
</script>
<!-- Tailwind (Dev) -->
<script src="https://cdn.tailwindcss.com"></script>
<?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">
<div class="min-h-screen flex flex-col">
<!-- HEADER -->
<?php tpl('header'); ?>
<!-- MAIN CONTENT -->
<main class="flex-1">