mirror of
https://github.com/flarum/framework.git
synced 2024-12-05 00:43:39 +08:00
Extract English translations into a language pack
To make this work, we add support for the client working without any locale. Also fixes #412.
This commit is contained in:
parent
7889b15f09
commit
e65536cdf8
|
@ -1,3 +0,0 @@
|
|||
app.translator.plural = function(count) {
|
||||
return count == 1 ? 'one' : 'other';
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
'plural' => function ($count) {
|
||||
return $count == 1 ? 'one' : 'other';
|
||||
}
|
||||
];
|
|
@ -1,230 +0,0 @@
|
|||
core:
|
||||
|
||||
##
|
||||
# UNIQUE KEYS - The following keys are used in only one location each.
|
||||
##
|
||||
|
||||
# These strings are used in the Change Email modal dialog.
|
||||
change_email_confirmation_message: => core.confirmation_email_sent
|
||||
change_email_go_to_button: => core.go_to_url
|
||||
change_email_submit_button: => core.save_changes
|
||||
change_email_title: => core.change_email
|
||||
|
||||
# These strings are used in the Change Password modal dialog.
|
||||
change_password_send_button: Send Password Reset Email
|
||||
change_password_text: Click the button below and check your email for a link to change your password.
|
||||
change_password_title: => core.change_password
|
||||
|
||||
# These strings are used by the Composer controls.
|
||||
composer_close_tooltip: Close
|
||||
composer_exit_full_screen_tooltip: Exit Full Screen
|
||||
composer_full_screen_tooltip: Full Screen
|
||||
composer_minimize_tooltip: Minimize
|
||||
|
||||
# These strings are used by the Composer when starting a discussion.
|
||||
composer_discussion_body_placeholder: Write a Post...
|
||||
composer_discussion_discard_confirmation: You have not posted your discussion. Do you wish to discard it?
|
||||
composer_discussion_submit_button: Post Discussion
|
||||
composer_discussion_title_placeholder: Discussion Title
|
||||
|
||||
# These strings are used by the Composer when editing a post.
|
||||
composer_edit_discard_confirmation: You have not saved your changes. Do you wish to discard them?
|
||||
composer_edit_post_link: "Post #{number} in {discussion}"
|
||||
composer_edit_submit_button: => core.save_changes
|
||||
|
||||
# These strings are used by the Composer when replying to a discussion.
|
||||
composer_reply_body_placeholder: => core.write_a_reply
|
||||
composer_reply_discard_confirmation: You have not posted your reply. Do you wish to discard it?
|
||||
composer_reply_posted_message: Your reply was posted.
|
||||
composer_reply_submit_button: Post Reply
|
||||
composer_reply_view_button: View
|
||||
|
||||
# These strings are used by the discussion control buttons.
|
||||
discussion_controls_cannot_reply_button: Can't Reply
|
||||
discussion_controls_cannot_reply_text: You don't have permission to reply to this discussion.
|
||||
discussion_controls_delete_button: => core.delete
|
||||
discussion_controls_delete_confirmation: Are you sure you want to delete this discussion?
|
||||
discussion_controls_delete_forever_button: => core.delete_forever
|
||||
discussion_controls_log_in_to_reply_button: Log In to Reply
|
||||
discussion_controls_rename_button: Rename
|
||||
discussion_controls_rename_text: Enter a new title for this discussion:
|
||||
discussion_controls_reply_button: Reply
|
||||
discussion_controls_restore_button: => core.restore
|
||||
|
||||
# These strings are used in the discussion list.
|
||||
discussion_list_load_more_button: => core.load_more
|
||||
discussion_list_mark_as_read_tooltip: Mark as Read
|
||||
discussion_list_replied_text: "{username} replied {ago}"
|
||||
discussion_list_started_text: "{username} started {ago}"
|
||||
|
||||
# These strings are used in the Edit User modal dialog (moderator function).
|
||||
edit_user_email_label: => core.email
|
||||
edit_user_password_label: => core.password
|
||||
edit_user_submit_button: => core.save_changes
|
||||
edit_user_username_label: => core.username
|
||||
|
||||
# These strings are used in the Forgot Password modal dialog.
|
||||
forgot_password_go_to_button: => core.go_to_url
|
||||
forgot_password_email_placeholder: => core.email
|
||||
forgot_password_email_sent_message: We've sent you an email containing a link to reset your password. Check your spam folder if you don't receive it within the next minute or two.
|
||||
forgot_password_submit_button: Recover Password
|
||||
forgot_password_text: Enter your email address and we will send you a link to reset your password.
|
||||
forgot_password_title: Forgot Password
|
||||
|
||||
# These strings are used in the header and session dropdown menu.
|
||||
header_admin_button: Administration
|
||||
header_log_in_link: => core.log_in
|
||||
header_log_out_button: Log Out
|
||||
header_profile_button: Profile
|
||||
header_search_placeholder: Search Forum
|
||||
header_settings_button: => core.settings
|
||||
header_sign_up_link: => core.sign_up
|
||||
|
||||
# These strings are used on the index page, peripheral to the discussion list.
|
||||
index_all_discussions_link: All Discussions
|
||||
index_cannot_start_discussion_button: "Can't Start Discussion"
|
||||
index_mark_all_as_read_tooltip: => core.mark_all_as_read
|
||||
index_refresh_tooltip: Refresh
|
||||
index_start_discussion_button: Start a Discussion
|
||||
|
||||
# These strings are used by the sorting control above the discussion list.
|
||||
index_sort_latest_button: Latest
|
||||
index_sort_newest_button: Newest
|
||||
index_sort_oldest_button: Oldest
|
||||
index_sort_relevance_button: Relevance
|
||||
index_sort_top_button: Top
|
||||
|
||||
# These strings are used in the Log In modal dialog.
|
||||
log_in_confirmation_required_message: "You need to confirm your email before you can log in. We've sent a confirmation email to {email}. If it doesn't arrive soon, check your spam folder."
|
||||
log_in_forgot_password_link: Forgot password?
|
||||
log_in_invalid_login_message: Your login details were incorrect.
|
||||
log_in_no_account_text: "Don't have an account? " # Final space is needed for string separation.
|
||||
log_in_password_placeholder: => core.password
|
||||
log_in_sign_up_link: => core.sign_up
|
||||
log_in_submit_button: => core.log_in
|
||||
log_in_title: => core.log_in
|
||||
log_in_username_or_email_placeholder: Username or Email
|
||||
|
||||
# These strings are used by the Notifications dropdown, a.k.a. "the bell".
|
||||
notifications_discussion_renamed_text: "{username} changed the title"
|
||||
notifications_empty_text: No Notifications
|
||||
notifications_mark_all_as_read_tooltip: => core.mark_all_as_read
|
||||
notifications_title: => core.notifications
|
||||
notifications_tooltip: => core.notifications
|
||||
|
||||
# These strings are used by tooltips displayed for individual posts.
|
||||
post_edited_tooltip: "{username} edited {ago}"
|
||||
post_number_tooltip: "Post #{number}"
|
||||
|
||||
# These strings are used by the post control buttons.
|
||||
post_controls_delete_button: => core.delete
|
||||
post_controls_delete_forever_button: => core.delete_forever
|
||||
post_controls_edit_button: => core.edit
|
||||
post_controls_restore_button: => core.restore
|
||||
|
||||
# These strings are used in the scrubber to the right of the post stream.
|
||||
post_scrubber_now_link: Now
|
||||
post_scrubber_original_post_link: Original Post
|
||||
post_scrubber_unread_text: "{count} unread"
|
||||
post_scrubber_viewing_text:
|
||||
one: "{index} of {count} post"
|
||||
other: "{index} of {count} posts"
|
||||
|
||||
# These strings are displayed between posts in the post stream.
|
||||
post_stream_discussion_renamed_text: "{username} changed the title from {old} to {new}."
|
||||
post_stream_reply_placeholder: => core.write_a_reply
|
||||
post_stream_time_lapsed_text: "{period} later"
|
||||
|
||||
# These strings are used by the search results dropdown list.
|
||||
search_all_discussions_button: 'Search all discussions for "{query}"'
|
||||
search_discussions_heading: => core.discussions
|
||||
search_users_heading: Users
|
||||
|
||||
# These strings are used in the Settings page.
|
||||
settings_account_heading: Account
|
||||
settings_change_email_button: => core.change_email
|
||||
settings_change_password_button: => core.change_password
|
||||
settings_notifications_heading: => core.notifications
|
||||
settings_privacy_disclose_online_label: Allow others to see when I am online
|
||||
settings_privacy_heading: Privacy
|
||||
settings_title: => core.settings
|
||||
|
||||
# These strings are used in the Notifications grid on the Settings page.
|
||||
settings_notify_by_email_heading: => core.email
|
||||
settings_notify_by_web_heading: Web
|
||||
settings_notify_discussion_renamed_label: Someone renames a discussion I started
|
||||
|
||||
# These strings are used in the Sign Up modal dialog.
|
||||
sign_up_already_have_account_text: "Already have an account? " # Final space is needed for string separation.
|
||||
sign_up_confirmation_message: => core.confirmation_email_sent
|
||||
sign_up_email_placeholder: => core.email
|
||||
sign_up_go_to_button: => core.go_to_url
|
||||
sign_up_log_in_link: => core.log_in
|
||||
sign_up_password_placeholder: => core.password
|
||||
sign_up_submit_button: => core.sign_up
|
||||
sign_up_title: => core.sign_up
|
||||
sign_up_username_placeholder: => core.username
|
||||
sign_up_welcome_text: "Welcome, {username}!"
|
||||
|
||||
# These strings are used in the user profile page and profile popup.
|
||||
user_bio_placeholder: Write something about yourself
|
||||
user_discussions_link: => core.discussions
|
||||
user_joined_date_text: "Joined {ago}"
|
||||
user_online_text: Online
|
||||
user_posts_load_more_button: => core.load_more
|
||||
user_posts_link: Posts
|
||||
user_settings_link: => core.settings
|
||||
|
||||
# These strings are used to control the avatar in the user profile page.
|
||||
user_avatar_remove_button: Remove
|
||||
user_avatar_upload_button: Upload
|
||||
|
||||
# These strings are found on the user profile page (moderator function).
|
||||
user_controls_button: Controls
|
||||
user_controls_delete_button: => core.delete
|
||||
user_controls_edit_button: => core.edit
|
||||
|
||||
##
|
||||
# REUSED STRINGS - The following keys are referenced by two or more unique keys.
|
||||
##
|
||||
|
||||
change_email: Change Email
|
||||
change_password: Change Password
|
||||
confirmation_email_sent: "We've sent a confirmation email to {email}. If it doesn't arrive soon, check your spam folder."
|
||||
delete: Delete
|
||||
delete_forever: Delete Forever
|
||||
discussions: Discussions
|
||||
edit: Edit
|
||||
email: Email
|
||||
go_to_url: "Go to {url}"
|
||||
load_more: Load More
|
||||
log_in: Log In
|
||||
mark_all_as_read: Mark All as Read
|
||||
notifications: Notifications
|
||||
password: Password
|
||||
restore: Restore
|
||||
save_changes: Save Changes
|
||||
settings: Settings
|
||||
sign_up: Sign Up
|
||||
username: Username
|
||||
write_a_reply: Write a Reply...
|
||||
|
||||
##
|
||||
# GLOBAL STRINGS - Keys in this section are used globally (or generated automatically).
|
||||
##
|
||||
|
||||
# This string replaces a deleted username:
|
||||
deleted_username: "[deleted]"
|
||||
|
||||
# The following keys are generated from group names:
|
||||
group_admin: Admin
|
||||
group_admins: Admins
|
||||
group_guest: Guest
|
||||
group_guests: Guests
|
||||
group_member: Member
|
||||
group_members: Members
|
||||
group_mod: Mod
|
||||
group_mods: Mods
|
||||
|
||||
# This string is currently unused:
|
||||
powered_by_flarum: Powered by Flarum
|
|
@ -24,31 +24,15 @@ class LocaleServiceProvider extends ServiceProvider
|
|||
{
|
||||
$manager = $this->app->make('flarum.localeManager');
|
||||
|
||||
$this->registerLocale($manager, 'en', 'English');
|
||||
|
||||
event(new RegisterLocales($manager));
|
||||
}
|
||||
|
||||
public function registerLocale(LocaleManager $manager, $locale, $title)
|
||||
{
|
||||
$path = __DIR__.'/../../locale/'.$locale;
|
||||
|
||||
$manager->addLocale($locale, $title);
|
||||
$manager->addTranslations($locale, $path.'.yml');
|
||||
$manager->addConfig($locale, $path.'.php');
|
||||
$manager->addJsFile($locale, $path.'.js');
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton('Flarum\Locale\LocaleManager');
|
||||
|
||||
$this->app->alias('Flarum\Locale\LocaleManager', 'flarum.localeManager');
|
||||
|
||||
$this->app->bind('translator', function ($app) {
|
||||
$locales = $app->make('flarum.localeManager');
|
||||
|
||||
return new Translator($locales->getTranslations('en'), $locales->getConfig('en')['plural']);
|
||||
});
|
||||
$this->app->instance('translator', new Translator);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,21 +15,27 @@ use Closure;
|
|||
|
||||
class Translator implements TranslatorInterface
|
||||
{
|
||||
protected $translations;
|
||||
protected $translations = [];
|
||||
|
||||
protected $plural;
|
||||
|
||||
public function __construct(array $translations, Closure $plural)
|
||||
public function setTranslations(array $translations)
|
||||
{
|
||||
$this->translations = $translations;
|
||||
}
|
||||
|
||||
public function setPlural(callable $plural)
|
||||
{
|
||||
$this->plural = $plural;
|
||||
}
|
||||
|
||||
protected function plural($count)
|
||||
{
|
||||
$plural = $this->plural;
|
||||
if ($this->plural) {
|
||||
$plural = $this->plural;
|
||||
|
||||
return $plural($count);
|
||||
return $plural($count);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLocale()
|
||||
|
@ -47,7 +53,11 @@ class Translator implements TranslatorInterface
|
|||
$translation = array_get($this->translations, $id);
|
||||
|
||||
if (is_array($translation) && isset($parameters['count'])) {
|
||||
$translation = $translation[$this->plural($parameters['count'])];
|
||||
$plural = $this->plural($parameters['count']);
|
||||
|
||||
if ($plural) {
|
||||
$translation = $translation[$plural];
|
||||
}
|
||||
}
|
||||
|
||||
if (is_string($translation)) {
|
||||
|
|
|
@ -100,15 +100,15 @@ abstract class ClientAction extends HtmlAction
|
|||
$actor = app('flarum.actor');
|
||||
$assets = $this->getAssets();
|
||||
$locale = $this->getLocale($actor, $request);
|
||||
$localeCompiler = $this->getLocaleCompiler($locale);
|
||||
$localeCompiler = $locale ? $this->getLocaleCompiler($locale) : null;
|
||||
|
||||
$view = new ClientView(
|
||||
$this->apiClient,
|
||||
$request,
|
||||
$actor,
|
||||
$assets,
|
||||
$localeCompiler,
|
||||
$this->layout
|
||||
$this->layout,
|
||||
$localeCompiler
|
||||
);
|
||||
|
||||
$view->setVariable('locales', $this->locales->getLocales());
|
||||
|
@ -120,14 +120,17 @@ abstract class ClientAction extends HtmlAction
|
|||
// which translations should be included in the locale file. Afterwards,
|
||||
// we will filter all of the translations for the actor's locale and
|
||||
// compile only the ones we need.
|
||||
$translations = $this->locales->getTranslations($locale);
|
||||
$keys = $this->translationKeys;
|
||||
|
||||
event(new BuildClientView($this, $view, $keys));
|
||||
|
||||
$translations = $this->filterTranslations($translations, $keys);
|
||||
if ($localeCompiler) {
|
||||
$translations = $this->locales->getTranslations($locale);
|
||||
|
||||
$localeCompiler->setTranslations($translations);
|
||||
$translations = $this->filterTranslations($translations, $keys);
|
||||
|
||||
$localeCompiler->setTranslations($translations);
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
@ -141,6 +144,12 @@ abstract class ClientAction extends HtmlAction
|
|||
public function flushAssets()
|
||||
{
|
||||
$this->getAssets()->flush();
|
||||
|
||||
$locales = array_keys($this->locales->getLocales());
|
||||
|
||||
foreach ($locales as $locale) {
|
||||
$this->getLocaleCompiler($locale)->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,11 +260,9 @@ abstract class ClientAction extends HtmlAction
|
|||
$locale = $this->settings->get('default_locale', 'en');
|
||||
}
|
||||
|
||||
if (! $this->locales->hasLocale($locale)) {
|
||||
return 'en';
|
||||
if ($this->locales->hasLocale($locale)) {
|
||||
return $locale;
|
||||
}
|
||||
|
||||
return $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -110,23 +110,23 @@ class ClientView implements Renderable
|
|||
* @param Request $request
|
||||
* @param User $actor
|
||||
* @param AssetManager $assets
|
||||
* @param JsCompiler $locale
|
||||
* @param string $layout
|
||||
* @param JsCompiler $locale
|
||||
*/
|
||||
public function __construct(
|
||||
Client $apiClient,
|
||||
Request $request,
|
||||
User $actor,
|
||||
AssetManager $assets,
|
||||
JsCompiler $locale,
|
||||
$layout
|
||||
$layout,
|
||||
JsCompiler $locale = null
|
||||
) {
|
||||
$this->apiClient = $apiClient;
|
||||
$this->request = $request;
|
||||
$this->actor = $actor;
|
||||
$this->assets = $assets;
|
||||
$this->locale = $locale;
|
||||
$this->layout = $layout;
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,7 +262,11 @@ class ClientView implements Renderable
|
|||
$view->noJs = $noJs;
|
||||
|
||||
$view->styles = [$this->assets->getCssFile()];
|
||||
$view->scripts = [$this->assets->getJsFile(), $this->locale->getFile()];
|
||||
$view->scripts = [$this->assets->getJsFile()];
|
||||
|
||||
if ($this->locale) {
|
||||
$view->scripts[] = $this->locale->getFile();
|
||||
}
|
||||
|
||||
$view->head = implode("\n", $this->headStrings);
|
||||
$view->foot = implode("\n", $this->footStrings);
|
||||
|
|
Loading…
Reference in New Issue
Block a user