From 6e1121179d4846e73f057e8c1b2ae8fe1877f91c Mon Sep 17 00:00:00 2001 From: "livefromthemoon@gmail.com" Date: Thu, 28 Oct 2010 03:37:29 +0200 Subject: [PATCH 1/4] guess locale from browser settings --- Gemfile | 1 + Gemfile.lock | 7 +++++++ app/controllers/application_controller.rb | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/Gemfile b/Gemfile index ddff8fa21..b97d1df4f 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,7 @@ gem 'roxml', :git => 'git://github.com/Empact/roxml.git' gem 'addressable', :require => 'addressable/uri' gem 'json' gem 'mini_fb' +gem 'http_accept_language', :git => 'http://github.com/iain/http_accept_language.git' #Standards gem 'pubsubhubbub' diff --git a/Gemfile.lock b/Gemfile.lock index dc26a8bf9..d4e0cf1c1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -67,6 +67,12 @@ GIT capistrano (>= 2.5.5) highline (>= 1.4.0) +GIT + remote: http://github.com/iain/http_accept_language.git + revision: 0b78aa7849fc90cf9e12586af162fa4c408a795d + specs: + http_accept_language (1.0.1) + GEM remote: http://rubygems.org/ specs: @@ -367,6 +373,7 @@ DEPENDENCIES em-websocket factory_girl_rails haml + http_accept_language! json launchy magent! diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e581613f3..e1327bac4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base before_filter :set_friends_and_status, :except => [:create, :update] before_filter :count_requests before_filter :set_invites + before_filter :set_locale def set_friends_and_status if current_user @@ -33,4 +34,8 @@ class ApplicationController < ActionController::Base @invites = current_user.invites end end + + def set_locale + I18n.locale = request.compatible_language_from I18n.available_locales + end end From b7a586b1a54f798266f314639159c28a5b045641 Mon Sep 17 00:00:00 2001 From: "livefromthemoon@gmail.com" Date: Thu, 28 Oct 2010 17:27:06 +0200 Subject: [PATCH 2/4] allow user to change his language in his settings --- app/controllers/application_controller.rb | 7 ++++++- app/controllers/users_controller.rb | 7 +++++++ app/helpers/language_helper.rb | 9 +++++++++ app/models/user.rb | 9 +++++++++ app/views/users/edit.html.haml | 10 ++++++++++ config/environment.rb | 12 ++++++++++++ config/languages.yml | 17 +++++++++++++++++ spec/controllers/users_controller_spec.rb | 9 +++++++++ spec/models/user_spec.rb | 13 +++++++++++++ 9 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 app/helpers/language_helper.rb create mode 100644 config/languages.yml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e1327bac4..d58dfc32a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,6 +3,7 @@ # the COPYRIGHT file. class ApplicationController < ActionController::Base + include LanguageHelper protect_from_forgery :except => :receive @@ -36,6 +37,10 @@ class ApplicationController < ActionController::Base end def set_locale - I18n.locale = request.compatible_language_from I18n.available_locales + if current_user + I18n.locale = current_user.language + else + I18n.locale = request.compatible_language_from AVAILABLE_LANGUAGE_CODES + end end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 79d33940a..45182cd88 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -29,6 +29,7 @@ class UsersController < ApplicationController else params[:user].delete(:password) if params[:user][:password].blank? params[:user].delete(:password_confirmation) if params[:user][:password].blank? and params[:user][:password_confirmation].blank? + params[:user].delete(:language) if params[:user][:language].blank? if params[:user][:password] && params[:user][:password_confirmation] if @user.update_attributes(:password => params[:user][:password], :password_confirmation => params[:user][:password_confirmation]) @@ -36,6 +37,12 @@ class UsersController < ApplicationController else flash[:error] = "Password Change Failed" end + elsif params[:user][:language] + if @user.update_attributes(:language => params[:user][:language]) + flash[:notice] = "Language Changed" + else + flash[:error] = "Language Change Failed" + end end redirect_to edit_user_path(@user) diff --git a/app/helpers/language_helper.rb b/app/helpers/language_helper.rb new file mode 100644 index 000000000..20a0db902 --- /dev/null +++ b/app/helpers/language_helper.rb @@ -0,0 +1,9 @@ +module LanguageHelper + def available_language_options + options = [] + AVAILABLE_LANGUAGES.each do |locale, language| + options << [language, locale] + end + options.sort_by { |o| o[0] } + end +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 16cc2783e..5e8bf087c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -19,6 +19,7 @@ class User include MongoMapper::Document include Diaspora::UserModules include Encryptor::Private + include LanguageHelper plugin MongoMapper::Devise @@ -42,11 +43,15 @@ class User key :getting_started, Boolean, :default => true + key :language, String + before_validation :strip_username, :on => :create + before_validation :set_current_language, :on => :create validates_presence_of :username validates_uniqueness_of :username, :case_sensitive => false validates_format_of :username, :with => /\A[A-Za-z0-9_.]+\z/ validates_with InvitedUserValidator + validates_inclusion_of :language, :in => AVAILABLE_LANGUAGE_CODES one :person, :class_name => 'Person', :foreign_key => :owner_id validate :person_is_valid @@ -75,6 +80,10 @@ class User end end + def set_current_language + self.language = I18n.locale.to_s if self.language.blank? + end + def self.find_for_authentication(conditions={}) if conditions[:username] =~ /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i # email regex conditions[:email] = conditions.delete(:username) diff --git a/app/views/users/edit.html.haml b/app/views/users/edit.html.haml index 5317a5095..2f0c899d4 100644 --- a/app/views/users/edit.html.haml +++ b/app/views/users/edit.html.haml @@ -45,6 +45,16 @@ or = f.submit 'Change password' + %h3 Change language + = form_for @user do |f| + = f.error_messages + + %p + = f.select :language, available_language_options + = f.submit 'Change language' + + %br + %h3 Export Data = link_to "download my xml", users_export_path, :class => "button" = link_to "download my photos", users_export_photos_path, :class => "button" diff --git a/config/environment.rb b/config/environment.rb index bf2896fc6..e95579b99 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -18,6 +18,18 @@ if File.exists?(File.expand_path("./config/fb_config.yml")) else FACEBOOK = false end + +if File.exists?(File.expand_path("./config/languages.yml")) + languages = YAML::load(File.open(File.expand_path("./config/languages.yml"))) + AVAILABLE_LANGUAGES = languages['available'] + DEFAULT_LANGUAGE = languages['default'] + AVAILABLE_LANGUAGE_CODES = languages['available'].keys.map { |v| v.to_s} +else + AVAILABLE_LANGUAGES = { :en => 'English' } + DEFAULT_LANGUAGES = 'en' + AVAILABLE_LANGUAGE_CODES = ['en'] +end + # Initialize the rails application Diaspora::Application.initialize! diff --git a/config/languages.yml b/config/languages.yml new file mode 100644 index 000000000..5df33034f --- /dev/null +++ b/config/languages.yml @@ -0,0 +1,17 @@ +default: 'en' +available: + cs: 'Lietuviškai' + cy: 'Cymraeg' + de: 'Deutsch' + en: 'English' + es: 'Español' + fr: 'Français' + id: 'Bahasa Indonesia' + it: 'Italiano' + nb: 'Norske' + nl: 'Nederlandse' + pt-BR: 'Português' + ro: 'Română' + ru: 'Россию' + sv: 'Svenska' + tr: 'Türk' \ No newline at end of file diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 93790c681..0ef94de1a 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -10,6 +10,7 @@ describe UsersController do let!(:aspect) { user.aspect(:name => "lame-os") } let!(:old_password) { user.encrypted_password } + let!(:old_language) { user.language } before do sign_in :user, user @@ -47,5 +48,13 @@ describe UsersController do user.encrypted_password.should == old_password end end + + describe 'language' do + it 'should allow user to change his language' do + put("update", :id => user.id, "user" => {"language" => "fr"}) + user.reload + user.language.should_not == old_language + end + end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index dfb5995c0..4d3dd8ca9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -91,6 +91,19 @@ describe User do duplicate_user.should_not be_valid end end + + describe "of language" do + it "requires availability" do + user = Factory.build(:user, :language => 'some invalid language') + user.should_not be_valid + end + + it "should save with current language if blank" do + I18n.locale = :fr + user = Factory(:user, :language => nil) + user.language.should == 'fr' + end + end end describe ".build" do From c4d8f4e587fe72bed3de7f806909abbd54e648b7 Mon Sep 17 00:00:00 2001 From: "livefromthemoon@gmail.com" Date: Thu, 28 Oct 2010 17:38:45 +0200 Subject: [PATCH 3/4] remove two useless lines of code --- app/controllers/application_controller.rb | 2 -- app/models/user.rb | 1 - config/languages.yml | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d58dfc32a..2ab2838c2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,8 +3,6 @@ # the COPYRIGHT file. class ApplicationController < ActionController::Base - include LanguageHelper - protect_from_forgery :except => :receive before_filter :set_friends_and_status, :except => [:create, :update] diff --git a/app/models/user.rb b/app/models/user.rb index 5e8bf087c..c52d2c033 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -19,7 +19,6 @@ class User include MongoMapper::Document include Diaspora::UserModules include Encryptor::Private - include LanguageHelper plugin MongoMapper::Devise diff --git a/config/languages.yml b/config/languages.yml index 5df33034f..510b10090 100644 --- a/config/languages.yml +++ b/config/languages.yml @@ -14,4 +14,4 @@ available: ro: 'Română' ru: 'Россию' sv: 'Svenska' - tr: 'Türk' \ No newline at end of file + tr: 'Türk' From 52522c102e7995226c7ce1d288a1b58358d5e51d Mon Sep 17 00:00:00 2001 From: "livefromthemoon@gmail.com" Date: Thu, 28 Oct 2010 18:09:25 +0200 Subject: [PATCH 4/4] add some basic verification when loading the languages config file --- app/controllers/application_controller.rb | 1 + config/environment.rb | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2ab2838c2..3e32d4c27 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -35,6 +35,7 @@ class ApplicationController < ActionController::Base end def set_locale + I18n.default_locale = DEFAULT_LANGUAGE if current_user I18n.locale = current_user.language else diff --git a/config/environment.rb b/config/environment.rb index e95579b99..9afe20c52 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -21,9 +21,9 @@ end if File.exists?(File.expand_path("./config/languages.yml")) languages = YAML::load(File.open(File.expand_path("./config/languages.yml"))) - AVAILABLE_LANGUAGES = languages['available'] - DEFAULT_LANGUAGE = languages['default'] - AVAILABLE_LANGUAGE_CODES = languages['available'].keys.map { |v| v.to_s} + AVAILABLE_LANGUAGES = (languages['available'].length > 0) ? languages['available'] : { :en => 'English' } + DEFAULT_LANGUAGE = (AVAILABLE_LANGUAGES.include?(languages['default'])) ? languages['default'] : AVAILABLE_LANGUAGES.keys[0].to_s + AVAILABLE_LANGUAGE_CODES = languages['available'].keys.map { |v| v.to_s } else AVAILABLE_LANGUAGES = { :en => 'English' } DEFAULT_LANGUAGES = 'en'