This commit is contained in:
2025-11-29 01:08:56 +01:00
parent c233060f36
commit 08e62ca338
2 changed files with 65 additions and 44 deletions

View File

@@ -275,45 +275,59 @@ function app_i18n_load_lang_json(string $lang): array
return $cache[$lang]; return $cache[$lang];
} }
/**
* Aus einem Label einen stabilen i18n-Key für Nav-Anker bauen.
* Beispiel: "So funktioniert USBCheck!" -> "nav_so_funktioniert_usbcheck"
*/
function app_i18n_make_anchor_key(string $label): string
{
// HTML-Entities entfernen (z. B. &)
$decoded = html_entity_decode($label, ENT_QUOTES | ENT_HTML5, 'UTF-8');
// Kleinbuchstaben
$decoded = mb_strtolower($decoded, 'UTF-8');
// Alles, was kein a-z oder 0-9 ist, durch Unterstrich ersetzen
$key = preg_replace('/[^a-z0-9]+/u', '_', $decoded);
// Mehrfache Unterstriche trimmen
$key = trim($key, '_');
if ($key === '') {
$key = 'item';
}
// Prefix, damit klar ist, dass es Navigationskeys sind
return 'nav_' . $key;
}
/** /**
* Nav-Anker für eine Seite aus der Sprachdatei holen. * Nav-Anker für eine Seite aus der Sprachdatei holen.
* *
* Unterstützte Varianten im JSON: * Haupt-Variante im JSON:
* *
* Variante A (direkte Labels):
* "pages": { * "pages": {
* "landing": { * "landing": {
* "anchors": { * "anchors": {
* "how": "So funktioniert USBCheck", * "how": "So funktioniert USBCheck",
* "problem": "Warum gefälschte USB-Sticks gefährlich sind" * "problem": "Warum gefälschte USB-Sticks gefährlich sind",
* "features": "Funktionen",
* "security": "Sicherheit",
* "faq": "FAQ"
* } * }
* } * }
* } * }
* *
* Variante B (i18n-Keys): * Optional explizit:
* "pages": {
* "landing": {
* "anchors": {
* "how": "nav_how",
* "problem": "nav_problem"
* }
* }
* }
*
* Variante C (explizit):
* "pages": {
* "landing": {
* "anchors": { * "anchors": {
* "how": { "label": "So funktioniert USBCheck", "i18n": "nav_how" }, * "how": { "label": "So funktioniert USBCheck", "i18n": "nav_how" },
* "problem": { "i18n": "nav_problem" } * "faq": { "i18n": "nav_faq" }
* }
* }
* } * }
* *
* Rückgabe-Format: * Rückgabe-Format:
* [ * [
* [ 'href' => '#how', 'label' => 'So funktioniert USBCheck', 'i18n' => '' ], * [ 'href' => '#how', 'label' => 'So funktioniert USBCheck', 'i18n' => 'nav_so_funktioniert_usbcheck' ],
* [ 'href' => '#problem', 'label' => '', 'i18n' => 'nav_problem' ], * [ 'href' => '#faq', 'label' => '', 'i18n' => 'nav_faq' ],
* ] * ]
*/ */
function app_get_nav_anchors(string $pageKey): array function app_get_nav_anchors(string $pageKey): array
@@ -335,40 +349,47 @@ function app_get_nav_anchors(string $pageKey): array
} }
$href = '#' . $id; $href = '#' . $id;
$label = null; $label = '';
$i18n = null; $i18n = '';
if (is_string($value)) { if (is_string($value)) {
$valueTrim = trim($value); // String IMMER als Label übernehmen
$labelTrim = trim($value);
if ($labelTrim === '') {
continue;
}
$label = $labelTrim;
// i18n-Key automatisch aus dem Label ableiten
$i18n = app_i18n_make_anchor_key($labelTrim);
if ($valueTrim !== '') {
// Heuristik:
// - enthält der Wert Leerzeichen → fertiges Label
// - sonst → i18n-Key (z.B. "nav_how")
if (preg_match('/\s/u', $valueTrim)) {
$label = $valueTrim;
} else {
$i18n = $valueTrim;
}
}
} elseif (is_array($value)) { } elseif (is_array($value)) {
// Explizite Variante:
// "how": { "label": "...", "i18n": "nav_how" }
if (!empty($value['label'])) { if (!empty($value['label'])) {
$label = (string)$value['label']; $label = trim((string)$value['label']);
} }
if (!empty($value['i18n'])) { if (!empty($value['i18n'])) {
$i18n = (string)$value['i18n']; $i18n = trim((string)$value['i18n']);
}
} }
// Wenn weder Label noch i18n da ist → überspringen if ($label === '' && $i18n === '') {
if ($label === null && $i18n === null) { continue;
}
// Wenn Label gesetzt, aber kein i18n: automatisch generieren
if ($label !== '' && $i18n === '') {
$i18n = app_i18n_make_anchor_key($label);
}
} else {
// Weder String noch Array → ignorieren
continue; continue;
} }
$anchors[] = [ $anchors[] = [
'href' => $href, 'href' => $href,
'label' => $label ?? '', 'label' => $label,
'i18n' => $i18n ?? '', 'i18n' => $i18n,
]; ];
} }

View File

@@ -26,7 +26,7 @@
"anchors": { "anchors": {
"how": "So funktioniert es", "how": "So funktioniert es",
"problem": "Warum gefälschte Sticks gefährlich sind", "problem": "Warum gefälschte Sticks gefährlich sind",
"features": "Funktionen und so", "features": "Funktionen",
"security": "Sicherheit", "security": "Sicherheit",
"faq": "FAQ" "faq": "FAQ"
}, },