upd
This commit is contained in:
103
config/i18n.php
103
config/i18n.php
@@ -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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user