From c513725f26b5c08f8a25884517ca365bd15b81ef Mon Sep 17 00:00:00 2001 From: Jonathan Allard <jonathan@allard.io> Date: Fri, 7 Feb 2014 22:24:10 -0500 Subject: [PATCH 1/2] Allow users to toggle interface language in their preferences --- .../discourse/controllers/preferences_controller.js | 6 ++++++ app/assets/javascripts/discourse/models/user.js | 1 + .../templates/user/preferences.js.handlebars | 10 ++++++++++ app/controllers/application_controller.rb | 6 +++++- app/models/site_setting.rb | 5 +++++ app/serializers/user_serializer.rb | 1 + app/services/user_updater.rb | 1 + config/locales/client.en.yml | 5 +++++ config/locales/client.fr.yml | 5 +++++ db/migrate/20140206044818_add_locale_to_user.rb | 5 +++++ spec/controllers/application_controller_spec.rb | 13 +++++++++++++ 11 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20140206044818_add_locale_to_user.rb diff --git a/app/assets/javascripts/discourse/controllers/preferences_controller.js b/app/assets/javascripts/discourse/controllers/preferences_controller.js index f34439265..18d87d9b3 100644 --- a/app/assets/javascripts/discourse/controllers/preferences_controller.js +++ b/app/assets/javascripts/discourse/controllers/preferences_controller.js @@ -30,6 +30,12 @@ Discourse.PreferencesController = Discourse.ObjectController.extend({ return Discourse.SiteSettings.enable_names; }.property(), + availableLocales: function() { + return Discourse.SiteSettings.available_locales.split('|').map( function(s) { + return {name: s, value: s}; + }); + }.property(), + digestFrequencies: [{ name: I18n.t('user.email_digests.daily'), value: 1 }, { name: I18n.t('user.email_digests.weekly'), value: 7 }, { name: I18n.t('user.email_digests.bi_weekly'), value: 14 }], diff --git a/app/assets/javascripts/discourse/models/user.js b/app/assets/javascripts/discourse/models/user.js index b17e8c62a..56df28465 100644 --- a/app/assets/javascripts/discourse/models/user.js +++ b/app/assets/javascripts/discourse/models/user.js @@ -170,6 +170,7 @@ Discourse.User = Discourse.Model.extend({ 'bio_raw', 'website', 'name', + 'locale', 'email_digests', 'email_direct', 'email_always', diff --git a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars index b65bbd149..4a0560aa0 100644 --- a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars @@ -66,6 +66,16 @@ </div> </div> + <div class="control-group"> + <label class="control-label">{{i18n user.locale.title}}</label> + <div class="controls"> + {{combobox valueAttribute="value" content=availableLocales value=locale none="user.locale.default"}} + </div> + <div class='instructions'> + {{i18n user.locale.instructions}} + </div> + </div> + <div class="control-group"> <label class="control-label">{{i18n user.bio}}</label> <div class="controls"> diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 091cac085..79d3d48aa 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -109,7 +109,11 @@ class ApplicationController < ActionController::Base end def set_locale - I18n.locale = SiteSetting.default_locale + I18n.locale = if current_user && current_user.locale.present? + current_user.locale + else + SiteSetting.default_locale + end end def store_preloaded(key, json) diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 25b92d0ed..8365c3bf6 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -23,6 +23,11 @@ class SiteSetting < ActiveRecord::Base load_settings(file) end + SiteSettingExtension.class_variable_get(:@@client_settings) << :available_locales + + def self.available_locales + LocaleSiteSetting.values.map{ |e| e[:value] }.join('|') + end def self.call_discourse_hub? self.enforce_global_nicknames? && self.discourse_org_access_key.present? diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index 7d93ffee7..4b55a2fd9 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -47,6 +47,7 @@ class UserSerializer < BasicUserSerializer end private_attributes :email, + :locale, :email_digests, :email_private_messages, :email_direct, diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb index ade9dd64c..025f0b376 100644 --- a/app/services/user_updater.rb +++ b/app/services/user_updater.rb @@ -27,6 +27,7 @@ class UserUpdater user.bio_raw = attributes.fetch(:bio_raw) { user.bio_raw } user.name = attributes.fetch(:name) { user.name } + user.locale = attributes.fetch(:locale) { user.locale } user.digest_after_days = attributes.fetch(:digest_after_days) { user.digest_after_days } if attributes[:auto_track_topics_after_msecs] diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index db9f1095f..dd209023b 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -325,6 +325,11 @@ en: enter_email: 'Username found. Enter matching email.' prefilled: "Email matches this registered username." + locale: + title: "Interface language" + instructions: "The language used by the forum interface. It will change when you refresh the page." + default: "(default)" + password_confirmation: title: "Password Again" diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml index 3e277d146..af5196b5a 100644 --- a/config/locales/client.fr.yml +++ b/config/locales/client.fr.yml @@ -299,6 +299,11 @@ fr: enter_email: 'Pseudo trouvé. Entrez l''adresse email correspondante.' prefilled: "L'adresse email correspond à ce pseudo enregistré." + locale: + title: "Langue de l'interface" + instructions: "La langue utilisée dans l'interface du forum. Le changement se fait lorsque vous rechargez la page." + default: "(par défaut)" + password_confirmation: title: "Confirmation" diff --git a/db/migrate/20140206044818_add_locale_to_user.rb b/db/migrate/20140206044818_add_locale_to_user.rb new file mode 100644 index 000000000..c0f2431b3 --- /dev/null +++ b/db/migrate/20140206044818_add_locale_to_user.rb @@ -0,0 +1,5 @@ +class AddLocaleToUser < ActiveRecord::Migration + def change + add_column :users, :locale, :string, limit: 10 + end +end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 00ba7824b..0cfc4ea80 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -44,6 +44,19 @@ describe TopicsController do end + describe 'set_locale' do + it 'sets the one the user prefers' do + SiteSetting.stubs(:allow_user_locale).returns(true) + + user = Fabricate(:user, locale: :fr) + log_in_user(user) + + get :show, {topic_id: topic.id} + + I18n.locale.should == :fr + end + end + end describe 'api' do From 0592420e527bb8cedb168211f7223cd270fcf5da Mon Sep 17 00:00:00 2001 From: Jonathan Allard <jonathan@allard.io> Date: Sat, 8 Feb 2014 20:35:46 -0500 Subject: [PATCH 2/2] Add a site setting to allow users to toggle I18n.locale It is false by default. --- .../controllers/preferences_controller.js | 4 ++++ .../templates/user/preferences.js.handlebars | 18 ++++++++++-------- app/controllers/application_controller.rb | 2 +- config/locales/server.en.yml | 1 + config/locales/server.fr.yml | 1 + config/site_settings.yml | 3 +++ .../controllers/application_controller_spec.rb | 9 +++++++++ 7 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/preferences_controller.js b/app/assets/javascripts/discourse/controllers/preferences_controller.js index 18d87d9b3..fa800b0a1 100644 --- a/app/assets/javascripts/discourse/controllers/preferences_controller.js +++ b/app/assets/javascripts/discourse/controllers/preferences_controller.js @@ -11,6 +11,10 @@ Discourse.PreferencesController = Discourse.ObjectController.extend({ return Discourse.SiteSettings.allow_uploaded_avatars; }.property(), + allowUserLocale: function() { + return Discourse.SiteSettings.allow_user_locale; + }.property(), + // By default we haven't saved anything saved: false, diff --git a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars index 4a0560aa0..a29de784f 100644 --- a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars @@ -66,15 +66,17 @@ </div> </div> - <div class="control-group"> - <label class="control-label">{{i18n user.locale.title}}</label> - <div class="controls"> - {{combobox valueAttribute="value" content=availableLocales value=locale none="user.locale.default"}} + {{#if allowUserLocale}} + <div class="control-group"> + <label class="control-label">{{i18n user.locale.title}}</label> + <div class="controls"> + {{combobox valueAttribute="value" content=availableLocales value=locale none="user.locale.default"}} + </div> + <div class='instructions'> + {{i18n user.locale.instructions}} + </div> </div> - <div class='instructions'> - {{i18n user.locale.instructions}} - </div> - </div> + {{/if}} <div class="control-group"> <label class="control-label">{{i18n user.bio}}</label> diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 79d3d48aa..16a7e7196 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -109,7 +109,7 @@ class ApplicationController < ActionController::Base end def set_locale - I18n.locale = if current_user && current_user.locale.present? + I18n.locale = if SiteSetting.allow_user_locale && current_user && current_user.locale.present? current_user.locale else SiteSetting.default_locale diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 74d7cc3c3..326d4aab9 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -549,6 +549,7 @@ en: site_settings: default_locale: "The default language of this Discourse instance (ISO 639-1 Code)" + allow_user_locale: "Allow users to choose their own language interface preference" min_post_length: "Minimum post length in characters" min_private_message_post_length: "Minimum post length in characters for private messages" max_post_length: "Maximum post length in characters" diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index 71be63bd0..0826f1456 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -484,6 +484,7 @@ fr: description: "HTML qui sera ajouté au pied de toutes les pages" site_settings: default_locale: "Le langage par défaut de cette instance de Discourse (code ISO 639-1)" + allow_user_locale: "Permettre aux utilisateurs de choisir leur propre préférence de langue pour l'interface" min_post_length: "Longueur minimale des messages en nombre de caractères" min_private_message_post_length: "Longueur minimale des messages privés en nombre de caractères" max_post_length: "Longueur maximale des messages en nombres de caractères" diff --git a/config/site_settings.yml b/config/site_settings.yml index 5f1579fce..5c3241c28 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -24,6 +24,9 @@ basic: default_locale: default: 'en' enum: 'LocaleSiteSetting' + allow_user_locale: + client: true + default: false ga_tracking_code: client: true default: '' diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 0cfc4ea80..082717646 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -55,6 +55,15 @@ describe TopicsController do I18n.locale.should == :fr end + + it 'is sets the default locale when the setting not enabled' do + user = Fabricate(:user, locale: :fr) + log_in_user(user) + + get :show, {topic_id: topic.id} + + I18n.locale.should == :en + end end end