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..3e32d4c27 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,12 +3,12 @@ # the COPYRIGHT file. class ApplicationController < ActionController::Base - protect_from_forgery :except => :receive 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 +33,13 @@ class ApplicationController < ActionController::Base @invites = current_user.invites end end + + def set_locale + I18n.default_locale = DEFAULT_LANGUAGE + 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 5946727d8..0e16880f1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -42,11 +42,16 @@ class User key :getting_started, Boolean, :default => true + key :language, String + before_validation :strip_and_downcase_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 @@ -76,6 +81,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..9afe20c52 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'].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' + 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..510b10090 --- /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' diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 93790c681..5b15e3b3f 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,15 @@ describe UsersController do user.encrypted_password.should == old_password end end + + describe 'language' do + it 'should allow user to change his language' do + user.language = 'en' + user.save + 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 d0c1d5b22..032422538 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -119,6 +119,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