'home'] replaces {slug} * @return string Translated string, or English fallback, or the key itself */ function t(string $key, array $params = []): string { static $strings = null; static $fallback = null; if ($strings === null) { $langDir = __DIR__ . '/'; $lang = _nbAdminLang(); $strings = _nbLoadLangFile($langDir . $lang . '.json'); $fallback = ($lang !== 'en') ? _nbLoadLangFile($langDir . 'en.json') : []; } $text = $strings[$key] ?? $fallback[$key] ?? $key; if ($params) { foreach ($params as $k => $v) { $text = str_replace('{' . $k . '}', $v, $text); } } return $text; } /** * Return all admin translation strings as array (for JS injection). */ function tAll(): array { static $merged = null; if ($merged !== null) return $merged; $langDir = __DIR__ . '/'; $lang = _nbAdminLang(); $en = _nbLoadLangFile($langDir . 'en.json'); $current = ($lang !== 'en') ? _nbLoadLangFile($langDir . $lang . '.json') : []; $merged = array_merge($en, $current); return $merged; } /** * Return all editor translation strings (for frontend JS injection). */ function tEditorAll(): array { $langDir = __DIR__ . '/'; $lang = _nbAdminLang(); $en = _nbLoadLangFile($langDir . 'editor-en.json'); $current = ($lang !== 'en') ? _nbLoadLangFile($langDir . 'editor-' . $lang . '.json') : []; return array_merge($en, $current); } /** * List available admin languages (code => native name). * Scans admin/lang/ for {code}.json files (excludes editor-* files). */ function tAvailableLanguages(): array { $langDir = __DIR__ . '/'; $names = [ 'en' => 'English', 'de' => 'Deutsch', 'es' => 'Español', 'fr' => 'Français', 'it' => 'Italiano', 'pt' => 'Português', 'nl' => 'Nederlands', 'pl' => 'Polski', 'ja' => '日本語', 'zh' => '中文', 'ko' => '한국어', 'ru' => 'Русский', 'cs' => 'Čeština', 'tr' => 'Türkçe', ]; $langs = []; foreach (glob($langDir . '*.json') as $file) { $basename = basename($file, '.json'); if (str_starts_with($basename, 'editor-')) continue; $langs[$basename] = $names[$basename] ?? $basename; } ksort($langs); return $langs; }