locale_selector 1.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +81 -0
- data/Rakefile +40 -0
- data/TESTING.rdoc +8 -0
- data/generators/gettext_hacks/gettext_hacks_generator.rb +15 -0
- data/generators/gettext_hacks/templates/gettext_hacks.rb +40 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/locale_selector/gettext_tasks.rb +170 -0
- data/lib/locale_selector.rb +266 -0
- data/locale_selector.gemspec +21 -0
- data/rails/init.rb +1 -0
- data/uninstall.rb +1 -0
- metadata +83 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= locale_selector
|
2
|
+
|
3
|
+
locale_selector provides a wrapper around the excellent ruby-gettext gem
|
4
|
+
http://www.yotabanana.com/hiki/ruby-gettext.html
|
5
|
+
|
6
|
+
Offers a convinient way to specify the list of locales supported by your
|
7
|
+
application. Provides a html UI control for locale selection.
|
8
|
+
Maintains the user preference in a cookie and provides callback for
|
9
|
+
saving the preference e.g. in a database.
|
10
|
+
|
11
|
+
Tested with Rails 2.1 and gettext 1.93.
|
12
|
+
|
13
|
+
locale_selector home page (rdoc): http://locale-selector.rubyforge.org/index.html
|
14
|
+
|
15
|
+
locale_selector rubyforge page (releases etc.): http://rubyforge.org/projects/locale-selector
|
16
|
+
|
17
|
+
source repository on github: http://github.com/geekq/locale_selector
|
18
|
+
|
19
|
+
= Installation
|
20
|
+
|
21
|
+
1.Install as a gem with
|
22
|
+
|
23
|
+
gem install locale_selector
|
24
|
+
|
25
|
+
It also installs the required gettext gem.
|
26
|
+
|
27
|
+
2.Append following to the Rakefile of your Rails application to get the
|
28
|
+
gettext related tasks
|
29
|
+
|
30
|
+
require 'locale_selector/gettext_tasks'
|
31
|
+
|
32
|
+
`rake -T gettext` now offers a couple of new tasks.
|
33
|
+
|
34
|
+
3.Reference the gettext in your environment.rb. For Rails 2.1 put following
|
35
|
+
at the top of Rails::Initializer.run block:
|
36
|
+
|
37
|
+
config.gem 'gettext', :lib => 'gettext/rails', :version => '1.93'
|
38
|
+
config.gem 'locale_selector', :version => '1.93'
|
39
|
+
|
40
|
+
4.Run the generator to create an initializer with the gettext hacks
|
41
|
+
|
42
|
+
script/generate gettext_hacks
|
43
|
+
|
44
|
+
5.Please provide the root route in your routes.rb and delete the public/index.html
|
45
|
+
|
46
|
+
map.root :controller => "mycontroller"
|
47
|
+
|
48
|
+
|
49
|
+
= Usage
|
50
|
+
|
51
|
+
Please see +LocaleSelector+ for API documentation and usage examples.
|
52
|
+
|
53
|
+
|
54
|
+
= Versioning
|
55
|
+
|
56
|
+
The version numbers of locale_selector match the version of the gettext gem
|
57
|
+
it is based on.
|
58
|
+
|
59
|
+
= Maintaining translations
|
60
|
+
|
61
|
+
Please use the provided rake tasks for maintaining translations.
|
62
|
+
Run <tt>rake -T gettext</tt> to see the list of provided rake tasks.
|
63
|
+
|
64
|
+
Most frequently used are
|
65
|
+
|
66
|
+
rake gettext:updatepo
|
67
|
+
|
68
|
+
to extract the new strings from the application.
|
69
|
+
Note: please make sure, that all the database connections used
|
70
|
+
in your models work. Gettext connects to the database to extract
|
71
|
+
field names to be translated.
|
72
|
+
|
73
|
+
|
74
|
+
rake gettext:makemo
|
75
|
+
|
76
|
+
for compiling the binary mo files from po-s.
|
77
|
+
|
78
|
+
|
79
|
+
Author:: Vladimir Dobriakov (http://www.innoq.com/blog/vd)
|
80
|
+
Copyright:: Vodafone, 2008
|
81
|
+
License:: MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/testtask'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
|
8
|
+
desc 'Default: run unit tests.'
|
9
|
+
task :default => :test
|
10
|
+
|
11
|
+
desc 'Test the locale_selector plugin.'
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
puts "locale_selector is tested within a simple test apllication."
|
14
|
+
puts "Please run `rake test` in the test/TestApp folder."
|
15
|
+
end
|
16
|
+
|
17
|
+
load File.join(File.dirname(__FILE__), 'locale_selector.gemspec')
|
18
|
+
|
19
|
+
desc 'Generate documentation for the locale_selector plugin.'
|
20
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
21
|
+
rdoc.rdoc_dir = 'rdoc'
|
22
|
+
rdoc.title = 'LocaleSelector'
|
23
|
+
rdoc.options = SPEC.rdoc_options
|
24
|
+
|
25
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
26
|
+
rdoc.rdoc_files.include('generators/gettext_hacks/templates/gettext_hacks.rb')
|
27
|
+
rdoc.rdoc_files.include(SPEC.extra_rdoc_files)
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::GemPackageTask.new(SPEC) do |p|
|
31
|
+
p.gem_spec = SPEC
|
32
|
+
p.need_tar = true
|
33
|
+
p.need_zip = true
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Publish the home page'
|
37
|
+
task :publish => :rerdoc do
|
38
|
+
sh 'scp -r rdoc/* geekq@rubyforge.org:/var/www/gforge-projects/locale-selector'
|
39
|
+
end
|
40
|
+
|
data/TESTING.rdoc
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
= Testing
|
2
|
+
|
3
|
+
This plugin does some integration work. It barely makes sense to test it in
|
4
|
+
isolation. It was originally developed as part of a real application and was
|
5
|
+
tested in the context of that application.
|
6
|
+
|
7
|
+
Now where it is published as a plugin, a small test application is the right
|
8
|
+
way to test the plugin.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class GettextHacksGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def initialize(*runtime_args)
|
4
|
+
super(*runtime_args)
|
5
|
+
end
|
6
|
+
|
7
|
+
def manifest
|
8
|
+
record do |m|
|
9
|
+
m.directory File.join('config/initializers')
|
10
|
+
|
11
|
+
m.template 'gettext_hacks.rb', File.join('config/initializers', "gettext_hacks.rb")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GetText
|
2
|
+
# Modification of the original gettext.
|
3
|
+
#
|
4
|
+
# By default all the translated texts from the po files are also html escaped
|
5
|
+
# so translators can not break the application by introducing less-than
|
6
|
+
# and ampersand characters or by trying to incorporate the <blink> tag ;-)
|
7
|
+
#
|
8
|
+
# It is possible though to turn this feature off for particular messages:
|
9
|
+
# if msgid starts with '#no_html_escaping#' then the translation returned as is,
|
10
|
+
# without html escaping.
|
11
|
+
def gettext(msgid)
|
12
|
+
translated = sgettext(msgid, nil)
|
13
|
+
if msgid =~ /^#no_html_escaping#/
|
14
|
+
translated
|
15
|
+
else
|
16
|
+
esc_html translated
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def esc_html(txt)
|
21
|
+
txt.gsub(/\"|\>|\&|\</) {|ptrn| {'"' => '"', '>' => '>', '<' => '<', '&' => '&'}[ptrn] }
|
22
|
+
end
|
23
|
+
|
24
|
+
alias :_ :gettext
|
25
|
+
module_function :_, :esc_html
|
26
|
+
end
|
27
|
+
|
28
|
+
module ActiveRecord # :nodoc:
|
29
|
+
class Errors
|
30
|
+
# We adjust the gettext so the inclusion of the field name must be done explicitely
|
31
|
+
# with #{fn}. If it is omitted, then the field name is not included.
|
32
|
+
# Originally it was 'append_field = true' so if there was no #{fn} then
|
33
|
+
# the field name was appended at the beginning of the message - very
|
34
|
+
# questionable behaviour.
|
35
|
+
def localize_error_messages_with_better_default(append_field = false)
|
36
|
+
localize_error_messages_without_better_default(append_field)
|
37
|
+
end
|
38
|
+
alias_method_chain :localize_error_messages, :better_default
|
39
|
+
end
|
40
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'locale_selector'
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
puts IO.read(File.join(File.dirname(__FILE__), 'README'))
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../locale_selector.rb')
|
2
|
+
require 'gettext'
|
3
|
+
require 'gettext/utils'
|
4
|
+
require 'activesupport'
|
5
|
+
require 'activerecord'
|
6
|
+
|
7
|
+
puts "Loading active_record parsing hacks in gettext_tasks.rb"
|
8
|
+
require 'gettext/rgettext'
|
9
|
+
require 'gettext/parser/active_record'
|
10
|
+
include GetText
|
11
|
+
|
12
|
+
def log(msg)
|
13
|
+
puts msg if false # set verbosity here
|
14
|
+
end
|
15
|
+
|
16
|
+
ActiveRecord::Base.instance_eval do
|
17
|
+
alias inherited_without_log inherited
|
18
|
+
|
19
|
+
@@active_record_classes_list = []
|
20
|
+
|
21
|
+
def inherited(subclass)
|
22
|
+
unless "#{subclass}" =~ /^CGI::/
|
23
|
+
log "registering an ActiveRecord model for later processing: #{subclass}"
|
24
|
+
active_record_classes_list << "#{subclass}"
|
25
|
+
end
|
26
|
+
inherited_without_log(subclass)
|
27
|
+
end
|
28
|
+
|
29
|
+
def active_record_classes_list
|
30
|
+
@@active_record_classes_list
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset_active_record_classes_list
|
34
|
+
@@active_record_classes_list = []
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module GetText
|
39
|
+
module ActiveRecordParser
|
40
|
+
log "overriding the original activerecord parser"
|
41
|
+
|
42
|
+
def self.parse(file, targets = []) # :nodoc:
|
43
|
+
log "locale_selector specific version of activerecordparser.parse is parsing #{file}"
|
44
|
+
GetText.locale = "en"
|
45
|
+
begin
|
46
|
+
eval(open(file).read, TOPLEVEL_BINDING)
|
47
|
+
rescue
|
48
|
+
$stderr.puts _("Ignored '%{file}'. Solve dependencies first.") % {:file => file}
|
49
|
+
$stderr.puts $!
|
50
|
+
end
|
51
|
+
loaded_constants = ActiveRecord::Base.active_record_classes_list
|
52
|
+
ActiveRecord::Base.reset_active_record_classes_list
|
53
|
+
loaded_constants.each do |classname|
|
54
|
+
klass = eval(classname, TOPLEVEL_BINDING)
|
55
|
+
if klass.is_a?(Class) && klass < ActiveRecord::Base
|
56
|
+
log "processing class #{klass.name}"
|
57
|
+
unless (klass.untranslate_all? || klass.abstract_class?)
|
58
|
+
add_target(targets, file, ActiveSupport::Inflector.singularize(klass.table_name.gsub(/_/, " ")))
|
59
|
+
unless klass.class_name == classname
|
60
|
+
add_target(targets, file, ActiveSupport::Inflector.singularize(classname.gsub(/_/, " ").downcase))
|
61
|
+
end
|
62
|
+
begin
|
63
|
+
klass.columns.each do |column|
|
64
|
+
unless untranslate_column?(klass, column.name)
|
65
|
+
if @config[:use_classname]
|
66
|
+
msgid = classname + "|" + klass.human_attribute_name(column.name)
|
67
|
+
else
|
68
|
+
msgid = klass.human_attribute_name(column.name)
|
69
|
+
end
|
70
|
+
add_target(targets, file, msgid)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
rescue
|
74
|
+
$stderr.puts _("No database is available.")
|
75
|
+
$stderr.puts $!
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
if RubyParser.target?(file)
|
81
|
+
targets = RubyParser.parse(file, targets)
|
82
|
+
end
|
83
|
+
targets.uniq!
|
84
|
+
targets
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def gettext_domain
|
91
|
+
initializer_name = File.join(File.dirname(__FILE__),
|
92
|
+
'../../../../config/initializers/gettext.rb')
|
93
|
+
require initializer_name if File.exist?(initializer_name)
|
94
|
+
|
95
|
+
LocaleSelector::default_domain ||
|
96
|
+
ENV['GETTEXT_DOMAIN'] ||
|
97
|
+
puts("Please either set the LocaleSelector::default_domain in your environment.rb or ENV['GETTEXT_DOMAIN'].") && exit
|
98
|
+
end
|
99
|
+
|
100
|
+
def app_version
|
101
|
+
"#{gettext_domain} 1.0"
|
102
|
+
end
|
103
|
+
|
104
|
+
# based on GetText.update_pofiles
|
105
|
+
def update_po_single_language(textdomain, files, app_version, lang, po_root = "po", refpot = "tmp.pot")
|
106
|
+
rgettext(files, refpot)
|
107
|
+
|
108
|
+
FileUtils.mkdir_p(po_root) unless FileTest.exist? po_root
|
109
|
+
msgmerge("#{po_root}/#{textdomain}.pot", refpot, app_version)
|
110
|
+
|
111
|
+
msgmerge("#{po_root}/#{lang}/#{textdomain}.po", refpot, app_version)
|
112
|
+
|
113
|
+
File.delete(refpot)
|
114
|
+
end
|
115
|
+
|
116
|
+
namespace :gettext do
|
117
|
+
desc "Update pot/po files (text files with translations) " \
|
118
|
+
"Note: please make sure, that all the database connections used " \
|
119
|
+
"in your models work. Gettext connects to the database to extract " \
|
120
|
+
"field names to be translated. " \
|
121
|
+
"Use lang={language to process} or lang=all to process po-files for all languages."
|
122
|
+
task :updatepo => :environment do
|
123
|
+
require 'gettext/utils'
|
124
|
+
puts "Updating translation files for gettext domain #{gettext_domain}"
|
125
|
+
orig_msgmerge = ENV["MSGMERGE_PATH"] || "msgmerge"
|
126
|
+
ENV["MSGMERGE_PATH"] = "#{orig_msgmerge} --no-fuzzy-matching"
|
127
|
+
source_files = Dir.glob(["{app,lib,plugins}/**/*.{rb,erb,rjs,rhtml}", "plugins/**/**/*.{rb,erb,rjs,rhtml}"])
|
128
|
+
lang = ENV['lang']
|
129
|
+
if lang.nil?
|
130
|
+
fail "Use lang={language to process} or lang=all to process po-files for all languages."
|
131
|
+
else
|
132
|
+
# will work in gettext-1.94
|
133
|
+
# options = {:msgmerge => [:no_wrap, :no_fuzzy_matching, :sort_output]}
|
134
|
+
# options[:lang] = lang if lang != 'all'
|
135
|
+
# options[:verbose] = true
|
136
|
+
# puts options.inspect
|
137
|
+
# GetText.update_pofiles(gettext_domain, source_files, app_version, options)
|
138
|
+
|
139
|
+
if lang == 'all'
|
140
|
+
GetText.update_pofiles(gettext_domain, source_files, app_version)
|
141
|
+
else
|
142
|
+
update_po_single_language(gettext_domain, source_files, app_version, lang)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
desc "Compile mo-(machine object) files."
|
148
|
+
task :makemo do
|
149
|
+
require 'gettext/utils'
|
150
|
+
GetText.create_mofiles(true, "po", "locale")
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "Translation for additional (new) language, use lang=xx"
|
154
|
+
task :translate_to do
|
155
|
+
lang = ENV['lang']
|
156
|
+
if lang
|
157
|
+
puts <<-"# # #"
|
158
|
+
Please run:
|
159
|
+
|
160
|
+
mkdir po/#{lang}
|
161
|
+
msginit -i po/#{gettext_domain} -l #{lang} -o po/#{lang}/#{gettext_domain}.po --no-translator
|
162
|
+
svn add po/#{lang}
|
163
|
+
# # #
|
164
|
+
else
|
165
|
+
fail "Please provide the 'lang' parameter on the command line with the desired " +
|
166
|
+
"language code like lang=de"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
@@ -0,0 +1,266 @@
|
|
1
|
+
require 'uri'
|
2
|
+
=begin rdoc
|
3
|
+
|
4
|
+
= Usage
|
5
|
+
|
6
|
+
== Controller
|
7
|
+
|
8
|
+
In your controllers or in the application controller
|
9
|
+
|
10
|
+
require 'locale_selector'
|
11
|
+
|
12
|
+
and use ControllerClassMethods#offer_locales:
|
13
|
+
|
14
|
+
offer_locales :en_UK, :en_ZA, :de, :ru
|
15
|
+
|
16
|
+
You can use different text domains in different parts of your application,
|
17
|
+
if your application is large enough for multiple translation files.
|
18
|
+
Please provide the differing domain in the single controllers e.g.
|
19
|
+
|
20
|
+
class JobsController < ApplicationController
|
21
|
+
offer_locales :de, :ru, :domain => 'HR_terminology'
|
22
|
+
end
|
23
|
+
|
24
|
+
=== Persisting preferences
|
25
|
+
|
26
|
+
locale_selector provides helpers which you can use in connection with Rails
|
27
|
+
hooks like this:
|
28
|
+
|
29
|
+
class ApplicationController
|
30
|
+
before_filter :persist_locale_choice_cookie
|
31
|
+
after_filter :persist_locale_choice_in_db
|
32
|
+
|
33
|
+
def persist_locale_choice_cookie
|
34
|
+
compute_effective_locale do |requested_locale|
|
35
|
+
save_cookie requested_locale
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def persist_locale_choice_in_db
|
40
|
+
compute_effective_locale do |requested_locale|
|
41
|
+
if current_user
|
42
|
+
current_user.update_attribute 'preferred_locale', requested_locale
|
43
|
+
current_user.reload
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
...
|
48
|
+
|
49
|
+
|
50
|
+
== Initializer
|
51
|
+
|
52
|
+
The default text domain can be set in a initializer
|
53
|
+
file config/initializers/gettext.rb
|
54
|
+
|
55
|
+
LocaleSelector::default_domain = 'myapp'
|
56
|
+
|
57
|
+
== View
|
58
|
+
|
59
|
+
In app/views/layouts/application.html.erb or in single views you
|
60
|
+
can use
|
61
|
+
|
62
|
+
<%= language_selector %>
|
63
|
+
|
64
|
+
Or write your own language selector helper. For the example
|
65
|
+
see the documentation for language_selector method for an implementation
|
66
|
+
example.
|
67
|
+
=end
|
68
|
+
|
69
|
+
module LocaleSelector
|
70
|
+
|
71
|
+
# Please set the gettext domain in a initializer,
|
72
|
+
# the file <tt>config/initializers/gettext.rb</tt> is recommended
|
73
|
+
# LocaleSelector::default_domain = 'myapp'
|
74
|
+
def self.default_domain=(d)
|
75
|
+
@@default_domain = d
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.default_domain
|
79
|
+
defined?(@@default_domain) ? @@default_domain : 'default'
|
80
|
+
end
|
81
|
+
|
82
|
+
module ControllerClassMethods
|
83
|
+
# Usage:
|
84
|
+
# offer_locales :en_UK, :de, :domain => 'my_application'
|
85
|
+
# The default for the list of the locales is the list
|
86
|
+
# of subdirectories of the 'locale' folder.
|
87
|
+
# Possible options are:
|
88
|
+
# <tt>:domain</tt>::
|
89
|
+
# the gettext domain
|
90
|
+
# <tt>:lang_cookie_path</tt>::
|
91
|
+
# the path for cookie that remembers the user locale selection
|
92
|
+
def offer_locales(*args)
|
93
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
94
|
+
class_variable_set :@@offered_locales,
|
95
|
+
args.empty? ?
|
96
|
+
GetText::Rails::available_locales :
|
97
|
+
args.flatten.map{|l| l.to_s}.uniq
|
98
|
+
helper_method :effective_locale, :offered_locales
|
99
|
+
init_gettext options[:domain] || LocaleSelector::default_domain
|
100
|
+
class_variable_set :@@lang_cookie_path, options[:lang_cookie_path] || '/'
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def global_offered_locales # :nodoc:
|
106
|
+
class_variable_get :@@offered_locales
|
107
|
+
end
|
108
|
+
|
109
|
+
def lang_cookie_path # :nodoc:
|
110
|
+
class_variable_get :@@lang_cookie_path
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
module ControllerInstanceMethods
|
116
|
+
# List of explicitely offered locales, as set during the
|
117
|
+
# initialization by #offer_locales
|
118
|
+
def offered_locales
|
119
|
+
self.class.send :global_offered_locales
|
120
|
+
end
|
121
|
+
|
122
|
+
# This helper saves the user locale selection in a cookie.
|
123
|
+
# You can adjust the cookie path during the initialization
|
124
|
+
# with #offer_locales, use the :lang_cookie_path option.
|
125
|
+
def save_cookie(requested_lang)
|
126
|
+
cookies[:lang] = {
|
127
|
+
:value => requested_lang,
|
128
|
+
:expires => 1.month.from_now,
|
129
|
+
:path => root_path
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# Accepts a block. The locale, conciously chosen by user
|
136
|
+
# is passed to the block. Can be used for persisting the
|
137
|
+
# user choice in a database or/and in a cookie.
|
138
|
+
def compute_effective_locale
|
139
|
+
# Priority order:
|
140
|
+
# 1.query parameter 'lang'
|
141
|
+
# 2.cookie 'lang'
|
142
|
+
# 3.browser setting
|
143
|
+
requested_lang = params[:lang] || cookies[:lang]
|
144
|
+
if self.offered_locales.include? requested_lang
|
145
|
+
yield requested_lang if block_given?
|
146
|
+
return requested_lang
|
147
|
+
end
|
148
|
+
|
149
|
+
parse_and_match_accept_language || 'en'
|
150
|
+
end
|
151
|
+
|
152
|
+
def parse_and_match_accept_language # :nodoc:
|
153
|
+
parsed = parse_accept_language(request.headers['Accept-language'])
|
154
|
+
match_accept_language parsed, offered_locales
|
155
|
+
end
|
156
|
+
|
157
|
+
def parse_accept_language(s) # :nodoc:
|
158
|
+
return [] unless s
|
159
|
+
res = []
|
160
|
+
s.split(',').each do |entry|
|
161
|
+
code, prio = entry.split(';q=')
|
162
|
+
res << [code, prio ? prio.to_f : 1]
|
163
|
+
end
|
164
|
+
res.sort {|a,b| b[1] <=> a[1]}
|
165
|
+
end
|
166
|
+
|
167
|
+
def match_accept_language(parsed_accept_language, offered_langs) # :nodoc:
|
168
|
+
parsed_accept_language.each do |lang, prio|
|
169
|
+
return lang if offered_langs.include?(lang)
|
170
|
+
return lang[0..1] if offered_langs.include?(lang[0..1])
|
171
|
+
end
|
172
|
+
offered_langs[0]
|
173
|
+
end
|
174
|
+
|
175
|
+
alias effective_locale compute_effective_locale
|
176
|
+
public :effective_locale
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
module ViewInstanceMethods
|
181
|
+
# Simple text based UI element for locale/language selection, that
|
182
|
+
# you can put on every page by calling this method in your layout view.
|
183
|
+
# Lists the languages offered by application as clickable links.
|
184
|
+
# see also #offer_locales.
|
185
|
+
#
|
186
|
+
# You can provide a block (executed per language) if you would
|
187
|
+
# like to override the default list of text based \<a href=""\> elements.
|
188
|
+
#
|
189
|
+
# For example, you can easily implement an image based language selector
|
190
|
+
# language_selector do |lang, active|
|
191
|
+
# link_to image_tag("#{lang}#{active ? '' : '_inactive'}.png", :alt => lang),
|
192
|
+
# language_selector_href(lang, params)
|
193
|
+
# end
|
194
|
+
def language_selector(additional_params=params, &block)
|
195
|
+
content_tag :ul, :id => 'language_selector' do
|
196
|
+
offered_locales.map do |lang|
|
197
|
+
selected = lang == effective_locale
|
198
|
+
content_tag :li, :class => "#{lang} #{selected ? 'selected' : ''}" do
|
199
|
+
if block_given?
|
200
|
+
yield lang, selected
|
201
|
+
else
|
202
|
+
link_to(lang, language_selector_href(lang, additional_params))
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end.join
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# Can be used if you are going to implement your own language selection control.
|
210
|
+
# Generates a link, that links to the current page but with an additional
|
211
|
+
# 'lang' parameter.
|
212
|
+
#
|
213
|
+
# Note: if the user fills in e.g. form fields and clicks the language
|
214
|
+
# selection link afterwards, then the filled in data is lost.
|
215
|
+
def language_selector_href(lang, params)
|
216
|
+
path = (uri = request.request_uri) ? uri.split('?').first.to_s : ''
|
217
|
+
q = request.query_parameters.merge({'lang' => "#{lang}"}).map {
|
218
|
+
|k,v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.sort.join("&")
|
219
|
+
"#{path}?#{q}"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
if defined?(ActionController)
|
225
|
+
ActionController::Base.send(:include, LocaleSelector::ControllerInstanceMethods)
|
226
|
+
ActionController::Base.extend LocaleSelector::ControllerClassMethods
|
227
|
+
end
|
228
|
+
if defined?(ActionView)
|
229
|
+
ActionView::Base.send(:include, LocaleSelector::ViewInstanceMethods)
|
230
|
+
end
|
231
|
+
|
232
|
+
module Locale # :nodoc:
|
233
|
+
# Patch for the gettext gem 1.92 and earlier.
|
234
|
+
# Now incorporated into gettext.
|
235
|
+
class Object
|
236
|
+
def self.parse(locale_name) # :nodoc:
|
237
|
+
# PATCH: the following line is new
|
238
|
+
locale_name = "en" if locale_name.nil? || locale_name.empty?
|
239
|
+
|
240
|
+
lang_charset, modifier = locale_name.split(/@/)
|
241
|
+
lang, charset = lang_charset.split(/\./)
|
242
|
+
language, country, script, variant = lang.gsub(/_/, "-").split('-')
|
243
|
+
language = language ? language.downcase : nil
|
244
|
+
language = "en" if language == "c" || language == "posix"
|
245
|
+
if country
|
246
|
+
if country =~ /\A[A-Z][a-z]+\Z/ #Latn => script
|
247
|
+
tmp = script
|
248
|
+
script = country
|
249
|
+
if tmp =~ /\A[A-Z]+\Z/ #US => country
|
250
|
+
country = tmp
|
251
|
+
else
|
252
|
+
country = nil
|
253
|
+
variant = tmp
|
254
|
+
end
|
255
|
+
else
|
256
|
+
country = country.upcase
|
257
|
+
if script !~ /\A[A-Z][a-z]+\Z/ #Latn => script
|
258
|
+
variant = script
|
259
|
+
script = nil
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
[language, country, charset, script, variant, modifier]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
SPEC = Gem::Specification.new do |s|
|
2
|
+
s.name = 'locale_selector'
|
3
|
+
s.version = '1.93.0'
|
4
|
+
s.summary = 'Wraps and improves ruby-gettext, provides UI for locale selection, maintains user preferences.'
|
5
|
+
s.description = s.summary
|
6
|
+
s.author = 'Vladimir Dobriakov'
|
7
|
+
s.email = 'vd_extern@vfnet.de'
|
8
|
+
s.homepage = 'http://github.com/geekq/locale_selector'
|
9
|
+
s.files = %w(MIT-LICENSE README.rdoc Rakefile TESTING.rdoc init.rb install.rb locale_selector.gemspec uninstall.rb) +
|
10
|
+
Dir.glob("{generators,lib,tasks,rails}/**/*")
|
11
|
+
|
12
|
+
Dir.glob("{generators,lib,tasks}/**/*")
|
13
|
+
s.require_path = "lib"
|
14
|
+
s.bindir = "bin"
|
15
|
+
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ['README.rdoc', 'TESTING.rdoc', 'MIT-LICENSE']
|
18
|
+
s.rdoc_options = ['--line-numbers', '--inline-source', '--promiscuous', '--main', 'README.rdoc']
|
19
|
+
s.add_dependency 'gettext', '1.93.0'
|
20
|
+
s.rubyforge_project = 'locale_selector'
|
21
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'locale_selector'
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: locale_selector
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.93.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vladimir Dobriakov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-02 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: gettext
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.93.0
|
24
|
+
version:
|
25
|
+
description: Wraps and improves ruby-gettext, provides UI for locale selection, maintains user preferences.
|
26
|
+
email: vd_extern@vfnet.de
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
- TESTING.rdoc
|
34
|
+
- MIT-LICENSE
|
35
|
+
files:
|
36
|
+
- MIT-LICENSE
|
37
|
+
- README.rdoc
|
38
|
+
- Rakefile
|
39
|
+
- TESTING.rdoc
|
40
|
+
- init.rb
|
41
|
+
- install.rb
|
42
|
+
- locale_selector.gemspec
|
43
|
+
- uninstall.rb
|
44
|
+
- generators/gettext_hacks
|
45
|
+
- generators/gettext_hacks/templates
|
46
|
+
- generators/gettext_hacks/templates/gettext_hacks.rb
|
47
|
+
- generators/gettext_hacks/gettext_hacks_generator.rb
|
48
|
+
- lib/locale_selector
|
49
|
+
- lib/locale_selector/gettext_tasks.rb
|
50
|
+
- lib/locale_selector.rb
|
51
|
+
- rails/init.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://github.com/geekq/locale_selector
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --line-numbers
|
57
|
+
- --inline-source
|
58
|
+
- --promiscuous
|
59
|
+
- --main
|
60
|
+
- README.rdoc
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
requirements: []
|
76
|
+
|
77
|
+
rubyforge_project: locale_selector
|
78
|
+
rubygems_version: 1.3.1
|
79
|
+
signing_key:
|
80
|
+
specification_version: 2
|
81
|
+
summary: Wraps and improves ruby-gettext, provides UI for locale selection, maintains user preferences.
|
82
|
+
test_files: []
|
83
|
+
|