mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-08-26 20:22:18 +00:00
Merge branch 'ezzra-german_informal'
This commit is contained in:
commit
f65ff3a9a8
@ -79,6 +79,7 @@ class HomeController extends Controller
|
||||
{
|
||||
$locale = app()->getLocale();
|
||||
$cacheKey = 'GLOBAL_TRANSLATIONS_' . $locale;
|
||||
|
||||
if (cache()->has($cacheKey) && config('app.env') !== 'development') {
|
||||
$resp = cache($cacheKey);
|
||||
} else {
|
||||
@ -89,15 +90,6 @@ class HomeController extends Controller
|
||||
'entities' => trans('entities'),
|
||||
'errors' => trans('errors')
|
||||
];
|
||||
if ($locale !== 'en') {
|
||||
$enTrans = [
|
||||
'common' => trans('common', [], 'en'),
|
||||
'components' => trans('components', [], 'en'),
|
||||
'entities' => trans('entities', [], 'en'),
|
||||
'errors' => trans('errors', [], 'en')
|
||||
];
|
||||
$translations = array_replace_recursive($enTrans, $translations);
|
||||
}
|
||||
$resp = 'window.translations = ' . json_encode($translations);
|
||||
cache()->put($cacheKey, $resp, 120);
|
||||
}
|
||||
|
32
app/Providers/TranslationServiceProvider.php
Normal file
32
app/Providers/TranslationServiceProvider.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php namespace BookStack\Providers;
|
||||
|
||||
|
||||
use BookStack\Translation\Translator;
|
||||
|
||||
class TranslationServiceProvider extends \Illuminate\Translation\TranslationServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->registerLoader();
|
||||
|
||||
$this->app->singleton('translator', function ($app) {
|
||||
$loader = $app['translation.loader'];
|
||||
|
||||
// When registering the translator component, we'll need to set the default
|
||||
// locale as well as the fallback locale. So, we'll grab the application
|
||||
// configuration so we can easily get both of these values from there.
|
||||
$locale = $app['config']['app.locale'];
|
||||
|
||||
$trans = new Translator($loader, $locale);
|
||||
|
||||
$trans->setFallback($app['config']['app.fallback_locale']);
|
||||
|
||||
return $trans;
|
||||
});
|
||||
}
|
||||
}
|
74
app/Translation/Translator.php
Normal file
74
app/Translation/Translator.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php namespace BookStack\Translation;
|
||||
|
||||
|
||||
class Translator extends \Illuminate\Translation\Translator
|
||||
{
|
||||
|
||||
/**
|
||||
* Mapping of locales to their base locales
|
||||
* @var array
|
||||
*/
|
||||
protected $baseLocaleMap = [
|
||||
'de_informal' => 'de',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the translation for a given key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $replace
|
||||
* @param string $locale
|
||||
* @return string|array|null
|
||||
*/
|
||||
public function trans($key, array $replace = [], $locale = null)
|
||||
{
|
||||
$translation = $this->get($key, $replace, $locale);
|
||||
|
||||
if (is_array($translation)) {
|
||||
$translation = $this->mergeBackupTranslations($translation, $key, $locale);
|
||||
}
|
||||
|
||||
return $translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the fallback translations, and base translations if existing,
|
||||
* into the provided core key => value array of translations content.
|
||||
* @param array $translationArray
|
||||
* @param string $key
|
||||
* @param null $locale
|
||||
* @return array
|
||||
*/
|
||||
protected function mergeBackupTranslations(array $translationArray, string $key, $locale = null)
|
||||
{
|
||||
$fallback = $this->get($key, [], $this->fallback);
|
||||
$baseLocale = $this->getBaseLocale($locale ?? $this->locale);
|
||||
$baseTranslations = $baseLocale ? $this->get($key, [], $baseLocale) : [];
|
||||
|
||||
return array_replace_recursive($fallback, $baseTranslations, $translationArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of locales to be checked.
|
||||
*
|
||||
* @param string|null $locale
|
||||
* @return array
|
||||
*/
|
||||
protected function localeArray($locale)
|
||||
{
|
||||
$primaryLocale = $locale ?: $this->locale;
|
||||
return array_filter([$primaryLocale, $this->getBaseLocale($primaryLocale), $this->fallback]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale to extend for the given locale.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getBaseLocale($locale)
|
||||
{
|
||||
return $this->baseLocaleMap[$locale] ?? null;
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"ext-json": "*",
|
||||
"ext-tidy": "*",
|
||||
"ext-dom": "*",
|
||||
"laravel/framework": "~5.5.44",
|
||||
|
@ -84,7 +84,7 @@ return [
|
||||
*/
|
||||
|
||||
'locale' => env('APP_LANG', 'en'),
|
||||
'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
|
||||
'locales' => ['en', 'ar', 'de', 'de_informal', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -187,7 +187,6 @@ return [
|
||||
Illuminate\Redis\RedisServiceProvider::class,
|
||||
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
|
||||
Illuminate\Session\SessionServiceProvider::class,
|
||||
Illuminate\Translation\TranslationServiceProvider::class,
|
||||
Illuminate\Validation\ValidationServiceProvider::class,
|
||||
Illuminate\View\ViewServiceProvider::class,
|
||||
Illuminate\Notifications\NotificationServiceProvider::class,
|
||||
@ -205,6 +204,7 @@ return [
|
||||
* Application Service Providers...
|
||||
*/
|
||||
BookStack\Providers\PaginationServiceProvider::class,
|
||||
BookStack\Providers\TranslationServiceProvider::class,
|
||||
|
||||
BookStack\Providers\AuthServiceProvider::class,
|
||||
BookStack\Providers\AppServiceProvider::class,
|
||||
|
6
resources/lang/de_informal/activities.php
Normal file
6
resources/lang/de_informal/activities.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
//
|
||||
];
|
47
resources/lang/de_informal/auth.php
Normal file
47
resources/lang/de_informal/auth.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuche es in :seconds Sekunden erneut.',
|
||||
|
||||
/**
|
||||
* Login & Register
|
||||
*/
|
||||
'ldap_email_hint' => 'Bitte gib eine E-Mail-Adresse ein, um diese mit dem Account zu nutzen.',
|
||||
'register_confirm' => 'Bitte prüfe Deinen Posteingang und bestätig die Registrierung.',
|
||||
'registration_email_domain_invalid' => 'Du kannst dich mit dieser E-Mail nicht registrieren.',
|
||||
'register_success' => 'Vielen Dank für Deine Registrierung! Die Daten sind gespeichert und Du bist angemeldet.',
|
||||
|
||||
/**
|
||||
* Password Reset
|
||||
*/
|
||||
'reset_password_send_instructions' => 'Bitte gib Deine E-Mail-Adresse ein. Danach erhältst Du eine E-Mail mit einem Link zum Zurücksetzen Deines Passwortes.',
|
||||
'reset_password_sent_success' => 'Eine E-Mail mit dem Link zum Zurücksetzen Deines Passwortes wurde an :email gesendet.',
|
||||
'reset_password_success' => 'Dein Passwort wurde erfolgreich zurückgesetzt.',
|
||||
'email_reset_text' => 'Du erhältsts diese E-Mail, weil jemand versucht hat, Dein Passwort zurückzusetzen.',
|
||||
'email_reset_not_requested' => 'Wenn Du das nicht warst, brauchst Du nichts weiter zu tun.',
|
||||
|
||||
/**
|
||||
* Email Confirmation
|
||||
*/
|
||||
'email_confirm_subject' => 'Bestätige Deine E-Mail-Adresse für :appName',
|
||||
'email_confirm_greeting' => 'Danke, dass Du dich für :appName registrierst hast!',
|
||||
'email_confirm_text' => 'Bitte bestätige Deine E-Mail-Adresse, indem Du auf die Schaltfläche klickst:',
|
||||
'email_confirm_send_error' => 'Leider konnte die für die Registrierung notwendige E-Mail zur Bestätigung Deine E-Mail-Adresse nicht versandt werden. Bitte kontaktiere den Systemadministrator!',
|
||||
'email_confirm_success' => 'Deine E-Mail-Adresse wurde bestätigt!',
|
||||
'email_confirm_resent' => 'Bestätigungs-E-Mail wurde erneut versendet, bitte überprüfe Deinen Posteingang.',
|
||||
'email_not_confirmed_text' => 'Deine E-Mail-Adresse ist bisher nicht bestätigt.',
|
||||
'email_not_confirmed_click_link' => 'Bitte klicke auf den Link in der E-Mail, die Du nach der Registrierung erhalten hast.',
|
||||
'email_not_confirmed_resend' => 'Wenn Du die E-Mail nicht erhalten hast, kannst Du die Nachricht erneut anfordern. Fülle hierzu bitte das folgende Formular aus:',
|
||||
];
|
9
resources/lang/de_informal/common.php
Normal file
9
resources/lang/de_informal/common.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
/**
|
||||
* Email Content
|
||||
*/
|
||||
'email_action_help' => 'Sollte es beim Anklicken der Schaltfläche ":action_text" Probleme geben, öffne die folgende URL in Deinem Browser:',
|
||||
];
|
10
resources/lang/de_informal/components.php
Normal file
10
resources/lang/de_informal/components.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
/**
|
||||
* Image Manager
|
||||
*/
|
||||
'image_delete_confirm' => 'Bitte klicke erneut auf löschen, wenn Du dieses Bild wirklich entfernen möchtest.',
|
||||
'image_dropzone' => 'Ziehe Bilder hierher oder klicke hier, um ein Bild auszuwählen',
|
||||
];
|
57
resources/lang/de_informal/entities.php
Normal file
57
resources/lang/de_informal/entities.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
/**
|
||||
* Shared
|
||||
*/
|
||||
'no_pages_viewed' => 'Du hast bisher keine Seiten angesehen.',
|
||||
'no_pages_recently_created' => 'Du hast bisher keine Seiten angelegt.',
|
||||
'no_pages_recently_updated' => 'Du hast bisher keine Seiten aktualisiert.',
|
||||
|
||||
/**
|
||||
* Books
|
||||
*/
|
||||
'books_delete_confirmation' => 'Bist Du sicher, dass Du dieses Buch löschen möchtest?',
|
||||
|
||||
/**
|
||||
* Chapters
|
||||
*/
|
||||
'chapters_delete_confirm' => 'Bist Du sicher, dass Du dieses Kapitel löschen möchtest?',
|
||||
|
||||
/**
|
||||
* Pages
|
||||
*/
|
||||
'pages_delete_confirm' => 'Bist Du sicher, dass Du diese Seite löschen möchtest?',
|
||||
'pages_delete_draft_confirm' => 'Bist Du sicher, dass Du diesen Seitenentwurf löschen möchtest?',
|
||||
'pages_edit_enter_changelog_desc' => 'Bitte gib eine kurze Zusammenfassung Deiner Änderungen ein',
|
||||
'pages_editing_draft_notification' => 'Du bearbeitest momenten einen Entwurf, der zuletzt :timeDiff gespeichert wurde.',
|
||||
'pages_draft_edit_active' => [
|
||||
'start_a' => ':count Benutzer bearbeiten derzeit diese Seite.',
|
||||
'start_b' => ':userName bearbeitet jetzt diese Seite.',
|
||||
'time_a' => 'seit die Seiten zuletzt aktualisiert wurden.',
|
||||
'time_b' => 'in den letzten :minCount Minuten',
|
||||
'message' => ':start :time. Achte darauf, keine Änderungen von anderen Benutzern zu überschreiben!',
|
||||
],
|
||||
|
||||
/**
|
||||
* Editor sidebar
|
||||
*/
|
||||
'tags_explain' => "Füge Schlagwörter hinzu, um ihren Inhalt zu kategorisieren.\nDu kannst einen erklärenden Inhalt hinzufügen, um eine genauere Unterteilung vorzunehmen.",
|
||||
'attachments_explain' => 'Du kannst auf Deiner Seite Dateien hochladen oder Links hinzufügen. Diese werden in der Seitenleiste angezeigt.',
|
||||
'attachments_delete_confirm' => 'Klicke erneut auf löschen, um diesen Anhang zu entfernen.',
|
||||
'attachments_dropzone' => 'Ziehe Dateien hierher oder klicke hier, um eine Datei auszuwählen',
|
||||
'attachments_explain_link' => 'Wenn Du keine Datei hochladen möchtest, kannst Du stattdessen einen Link hinzufügen. Dieser Link kann auf eine andere Seite oder eine Datei im Internet verweisen.',
|
||||
'attachments_edit_drop_upload' => 'Ziehe Dateien hierher, um diese hochzuladen und zu überschreiben',
|
||||
|
||||
/**
|
||||
* Comments
|
||||
*/
|
||||
'comment_placeholder' => 'Gib hier Deine Kommentare ein (Markdown unterstützt)',
|
||||
'comment_delete_confirm' => 'Möchtst Du diesen Kommentar wirklich löschen?',
|
||||
|
||||
/**
|
||||
* Revision
|
||||
*/
|
||||
'revision_delete_confirm' => 'Bist Du sicher, dass Du diese Revision löschen möchtest?',
|
||||
];
|
32
resources/lang/de_informal/errors.php
Normal file
32
resources/lang/de_informal/errors.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
// Pages
|
||||
'permission' => 'Du hast keine Berechtigung, auf diese Seite zuzugreifen.',
|
||||
'permissionJson' => 'Du hast keine Berechtigung, die angeforderte Aktion auszuführen.',
|
||||
|
||||
// Auth
|
||||
'email_already_confirmed' => 'Die E-Mail-Adresse ist bereits bestätigt. Bitte melde dich an.',
|
||||
'email_confirmation_invalid' => 'Der Bestätigungslink ist nicht gültig oder wurde bereits verwendet. Bitte registriere dich erneut.',
|
||||
'social_account_in_use' => 'Dieses :socialAccount-Konto wird bereits verwendet. Bitte melde dich mit dem :socialAccount-Konto an.',
|
||||
'social_account_email_in_use' => 'Die E-Mail-Adresse ":email" ist bereits registriert. Wenn Du bereits registriert bist, kannst Du Dein :socialAccount-Konto in Deinen Profil-Einstellungen verknüpfen.',
|
||||
'social_account_not_used' => 'Dieses :socialAccount-Konto ist bisher keinem Benutzer zugeordnet. Du kannst das in Deinen Profil-Einstellungen tun.',
|
||||
'social_account_register_instructions' => 'Wenn Du bisher kein Social-Media Konto besitzt, kannst Du ein solches Konto mit der :socialAccount Option anlegen.',
|
||||
|
||||
// System
|
||||
'path_not_writable' => 'Die Datei kann nicht in den angegebenen Pfad :filePath hochgeladen werden. Stelle sicher, dass dieser Ordner auf dem Server beschreibbar ist.',
|
||||
'cannot_create_thumbs' => 'Der Server kann keine Vorschau-Bilder erzeugen. Bitte prüfe, ob die GD PHP-Erweiterung installiert ist.',
|
||||
'server_upload_limit' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuche es mit einer kleineren Datei.',
|
||||
|
||||
// Pages
|
||||
'page_draft_autosave_fail' => 'Fehler beim Speichern des Entwurfs. Stelle sicher, dass Du mit dem Internet verbunden bist, bevor Du den Entwurf dieser Seite speicherst.',
|
||||
'page_custom_home_deletion' => 'Eine als Startseite gesetzte Seite kann nicht gelöscht werden.',
|
||||
|
||||
// Users
|
||||
'users_cannot_delete_only_admin' => 'Du kannst den einzigen Administrator nicht löschen.',
|
||||
'users_cannot_delete_guest' => 'Du kannst den Gast-Benutzer nicht löschen',
|
||||
|
||||
// Error pages
|
||||
'sorry_page_not_found' => 'Entschuldigung. Die Seite, die Du angefordert hast, wurde nicht gefunden.',
|
||||
];
|
6
resources/lang/de_informal/pagination.php
Normal file
6
resources/lang/de_informal/pagination.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
//
|
||||
];
|
6
resources/lang/de_informal/passwords.php
Normal file
6
resources/lang/de_informal/passwords.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
//
|
||||
];
|
38
resources/lang/de_informal/settings.php
Normal file
38
resources/lang/de_informal/settings.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
/**
|
||||
* Settings text strings
|
||||
* Contains all text strings used in the general settings sections of BookStack
|
||||
* including users and roles.
|
||||
*/
|
||||
|
||||
/**
|
||||
* App settings
|
||||
*/
|
||||
'app_editor_desc' => 'Wähle den Editor aus, der von allen Benutzern genutzt werden soll, um Seiten zu editieren.',
|
||||
'app_primary_color_desc' => "Dies sollte ein HEX Wert sein.\nWenn Du nichts eingibst, wird die Anwendung auf die Standardfarbe zurückgesetzt.",
|
||||
'app_homepage_desc' => 'Wähle eine Seite als Startseite aus, die statt der Standardansicht angezeigt werden soll. Seitenberechtigungen werden für die ausgewählten Seiten ignoriert.',
|
||||
'app_homepage_books' => 'Oder wähle die Buch-Übersicht als Startseite. Das wird die Seiten-Auswahl überschreiben.',
|
||||
|
||||
/**
|
||||
* Maintenance settings
|
||||
*/
|
||||
'maint_image_cleanup_desc' => 'Überprüft Seiten- und Versionsinhalte auf ungenutzte und mehrfach vorhandene Bilder. Erstelle vor dem Start ein Backup Deiner Datenbank und Bilder.',
|
||||
'maint_image_cleanup_warning' => ':count eventuell unbenutze Bilder wurden gefunden. Möchtest Du diese Bilder löschen?',
|
||||
|
||||
/**
|
||||
* Role settings
|
||||
*/
|
||||
'role_delete_confirm' => 'Du möchtest die Rolle ":roleName" löschen.',
|
||||
'role_delete_users_assigned' => 'Diese Rolle ist :userCount Benutzern zugeordnet. Du kannst unten eine neue Rolle auswählen, die Du diesen Benutzern zuordnen möchtest.',
|
||||
'role_delete_sure' => 'Bist Du sicher, dass Du diese Rolle löschen möchtest?',
|
||||
|
||||
/**
|
||||
* Users
|
||||
*/
|
||||
'users_password_warning' => 'Fülle die folgenden Felder nur aus, wenn Du Dein Passwort ändern möchtest:',
|
||||
'users_delete_confirm' => 'Bist Du sicher, dass Du diesen Benutzer löschen möchtest?',
|
||||
'users_social_accounts_info' => 'Hier kannst Du andere Social-Media-Konten für eine schnellere und einfachere Anmeldung verknüpfen. Wenn Du ein Social-Media Konto löschst, bleibt der Zugriff erhalten. Entferne in diesem Falle die Berechtigung in Deinen Profil-Einstellungen des verknüpften Social-Media-Kontos.',
|
||||
];
|
6
resources/lang/de_informal/validation.php
Normal file
6
resources/lang/de_informal/validation.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
// Extends 'de'
|
||||
return [
|
||||
//
|
||||
];
|
@ -136,7 +136,8 @@ return [
|
||||
'language_select' => [
|
||||
'en' => 'English',
|
||||
'ar' => 'العربية',
|
||||
'de' => 'Deutsch',
|
||||
'de' => 'Deutsch (Sie)',
|
||||
'de_informal' => 'Deutsch (Du)',
|
||||
'es' => 'Español',
|
||||
'es_AR' => 'Español Argentina',
|
||||
'fr' => 'Français',
|
||||
|
@ -81,4 +81,30 @@ class LanguageTest extends TestCase
|
||||
$this->assertTrue(config('app.rtl'), "App RTL config should have been set to true by middleware");
|
||||
}
|
||||
|
||||
public function test_de_informal_falls_base_to_de()
|
||||
{
|
||||
// Base de back value
|
||||
$deBack = trans()->get('common.cancel', [], 'de', false);
|
||||
$this->assertEquals('Abbrechen', $deBack);
|
||||
// Ensure de_informal has no value set
|
||||
$this->assertEquals('common.cancel', trans()->get('common.cancel', [], 'de_informal', false));
|
||||
// Ensure standard trans falls back to de
|
||||
$this->assertEquals($deBack, trans('common.cancel', [], 'de_informal'));
|
||||
// Ensure de_informal gets its own values where set
|
||||
$deEmailActionHelp = trans()->get('common.email_action_help', [], 'de', false);
|
||||
$enEmailActionHelp = trans()->get('common.email_action_help', [], 'en', false);
|
||||
$deInformalEmailActionHelp = trans()->get('common.email_action_help', [], 'de_informal', false);
|
||||
$this->assertNotEquals($deEmailActionHelp, $deInformalEmailActionHelp);
|
||||
$this->assertNotEquals($enEmailActionHelp, $deInformalEmailActionHelp);
|
||||
}
|
||||
|
||||
public function test_de_informal_falls_base_to_de_in_js_endpoint()
|
||||
{
|
||||
$this->asEditor();
|
||||
setting()->putUser($this->getEditor(), 'language', 'de_informal');
|
||||
|
||||
$transResp = $this->get('/translations');
|
||||
$transResp->assertSee('"cancel":"Abbrechen"');
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user