genki-merb_babel 0.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +151 -0
- data/Rakefile +50 -0
- data/TODO +5 -0
- data/lib/merb_babel.rb +52 -0
- data/lib/merb_babel/core_ext.rb +29 -0
- data/lib/merb_babel/m_i18n.rb +29 -0
- data/lib/merb_babel/m_l10n.rb +118 -0
- data/lib/merb_babel/m_locale.rb +76 -0
- data/lib/merb_babel/merbtasks.rb +6 -0
- data/spec/lang/en-UK.yml +13 -0
- data/spec/lang/en-US.yml +13 -0
- data/spec/lang/en.yml +16 -0
- data/spec/m_i18n_spec.rb +49 -0
- data/spec/m_l10n_spec.rb +50 -0
- data/spec/merb_babel_spec.rb +127 -0
- data/spec/other_lang_dir/fr.yml +14 -0
- data/spec/spec_helper.rb +50 -0
- metadata +83 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Matt Aimonetti
|
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.markdown
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
Merb_babel
|
2
|
+
=========
|
3
|
+
|
4
|
+
A plugin for the Merb framework that provides locales, languages, countries. (in a thread safe environment)
|
5
|
+
|
6
|
+
|
7
|
+
Purpose of Merb\_babel
|
8
|
+
---------------------
|
9
|
+
|
10
|
+
Merb_babel is primarily written to fulfill my personal needs. Instead of porting my http://github.com/mattetti/globalite plugin over, I decided to re write it from scratch learning from my mistakes.
|
11
|
+
|
12
|
+
Goals:
|
13
|
+
|
14
|
+
* simplicity
|
15
|
+
* speed
|
16
|
+
|
17
|
+
My first and simple objective is to get Merb to work in Simplified and Traditional Chinese + switch from one to the other.
|
18
|
+
|
19
|
+
Also, as of today, I'm not planning on supporting model localization since I believe it's easy to do, and in most cases it's too specific to use a plugin. (but other plugins offer that for you anyway ;) )
|
20
|
+
|
21
|
+
One of the objectives is that people can add Merb\_babel to their project and use merb in a different language without worrying about internationalization/localization. I hope to keep merb helpers and other plugins (merb\_activerecord / merb\_datamapper / merb\_sequel) localized so someone can define his app's locale/language/country and Merb will talk his language right away.
|
22
|
+
|
23
|
+
Before you go further, you might want to read [this explanation about i18n/l10n](http://www.w3.org/International/questions/qa-i18n)
|
24
|
+
|
25
|
+
Usage
|
26
|
+
------
|
27
|
+
|
28
|
+
In your application controller add:
|
29
|
+
|
30
|
+
before :set_locale
|
31
|
+
|
32
|
+
|
33
|
+
and access the user locale using @controller.locale (or simply #locale in the controller)
|
34
|
+
If a locale is set, you can also access @controller.language and @controller.country (same thing, you can use #language or #country from within your controller scope)
|
35
|
+
|
36
|
+
The locale is stored in request.env[:locale]
|
37
|
+
|
38
|
+
At the moment you have 3 ways of setting up a locale:
|
39
|
+
|
40
|
+
* default way in the config settings (that you can overwrite in your init.rb file )
|
41
|
+
|
42
|
+
Merb::Plugins.config[:Merb_babel] = {
|
43
|
+
:default_locale => 'en-US',
|
44
|
+
:default_language => 'en',
|
45
|
+
:default_country => 'US'
|
46
|
+
}
|
47
|
+
|
48
|
+
* per request basis, by sending a param called locale (language, and country will set their own values)
|
49
|
+
* store the locale in the session
|
50
|
+
* use routes
|
51
|
+
|
52
|
+
Babel doesn't support http header lookup yet.
|
53
|
+
|
54
|
+
Set locale in your routes
|
55
|
+
--------------------------
|
56
|
+
|
57
|
+
r.match(/\/?(en\-US|en\-UK|es\-ES|es\-AR)?/).to(:locale => "[1]") do |l|
|
58
|
+
l.match("/articles/:action/:id").to(:controller => "articles")
|
59
|
+
end
|
60
|
+
|
61
|
+
What if you don't need to use a full locale?
|
62
|
+
--------------------------------------------
|
63
|
+
|
64
|
+
some people might not need to use the full locale, they just want to use one version of a language and the locale is an overkill. Don't worry, you can use the language instance variable.
|
65
|
+
|
66
|
+
before :set_language
|
67
|
+
|
68
|
+
|
69
|
+
All locale work is done in ``merb_babel/lib/merb_babel/m_locale.rb`` and tested in ``spec/merb_babel_spec.rb``
|
70
|
+
|
71
|
+
Localization(L10n)
|
72
|
+
------------------
|
73
|
+
|
74
|
+
L10n is basically the adaptation of your product to a specific locale. In our case, we see L10n as the storing and retrieval of localized data. (for a locale or language)
|
75
|
+
|
76
|
+
Localizations are loaded from localization files.
|
77
|
+
|
78
|
+
Localization files are simple yaml files that get loaded in memory. By default Merb\_babel will look in ./lang for localization files. The default location is defined in Merb::Plugins.config[:merb_babel][:localization_dirs] and can be overwritten. Also, you can add more folders to look for by calling:
|
79
|
+
|
80
|
+
add_localization_dir(path_with_more_localization_files)
|
81
|
+
|
82
|
+
Note: when you add a new localization directory, localizations gets reloaded.
|
83
|
+
This needs to be done when Merb loads as I didn't add a mutex around that task yet.
|
84
|
+
|
85
|
+
Localizations are available in #localizations and are namespaced as follows:
|
86
|
+
|
87
|
+
localizations['en'][:right] => 'right'
|
88
|
+
localizations['en'][:left] => 'left'
|
89
|
+
localizations['en']['US'][:greeting] => 'Howdie'
|
90
|
+
localizations['en']['AU'][:greeting] => "Good'ay"
|
91
|
+
|
92
|
+
For that the localization files to be loaded properly, you need to follow some conventions:
|
93
|
+
|
94
|
+
* you have to declare a merb localization language code pair:
|
95
|
+
mloc\_language_code: en
|
96
|
+
where en represents the language code of the localization
|
97
|
+
|
98
|
+
* All generic localization for a language should go under their own language file. Region/culture specific localizations have to go to their own files and will be used if the full locale is set.
|
99
|
+
|
100
|
+
* A localization file is recognized as being locale specific if the mloc_country_code pair is set.
|
101
|
+
|
102
|
+
* ONLY localizations/translations specific to a locale should be written in a locale file.
|
103
|
+
|
104
|
+
* Recommended: set the mloc\_language_name pair so you list the available languages in their own language.
|
105
|
+
|
106
|
+
* look at examples in spec/lang
|
107
|
+
|
108
|
+
All the Localization(L10n) work is done in ``merb_babel/lib/merb_abel/m_l10n.rb`` and tested in ``spec/m_l10n_spec.rb``
|
109
|
+
|
110
|
+
|
111
|
+
Internationalization(I18n)
|
112
|
+
--------------------------
|
113
|
+
|
114
|
+
I18n enables easy localization of your product. That's what the developer/designer user to make their data localizable.
|
115
|
+
|
116
|
+
At the moment, only strings can be localized/translated.
|
117
|
+
|
118
|
+
In your controller, or view simply do:
|
119
|
+
|
120
|
+
translate(:localization_key)
|
121
|
+
|
122
|
+
You might prefer a shorter version so here are some aliases for you to use:
|
123
|
+
|
124
|
+
babelize(:translation_key)
|
125
|
+
or
|
126
|
+
t(:translation_key)
|
127
|
+
or
|
128
|
+
_(:translation_key)
|
129
|
+
|
130
|
+
The translation will use the full locale (language and country) if set and available, otherwise the language translation will be displayed.
|
131
|
+
|
132
|
+
*Params*
|
133
|
+
|
134
|
+
You can pass a hash of parameters after the translation key. For instance:
|
135
|
+
|
136
|
+
t(:greetings, :language => 'fr')
|
137
|
+
|
138
|
+
Would lookup the French translation for the greetings key and return 'Salut'
|
139
|
+
|
140
|
+
You can also pass the country code to use the full locale.
|
141
|
+
|
142
|
+
t(:greetings, :language => 'en', :country => 'AU')
|
143
|
+
|
144
|
+
would lookup the Australian English translation for the greetings key and return "G'day"
|
145
|
+
|
146
|
+
|
147
|
+
Other plugins you might want to look at:
|
148
|
+
----------------------------------------
|
149
|
+
|
150
|
+
* http://github.com/myabc/merb_global
|
151
|
+
* http://github.com/lemon/poppycock
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
require 'merb-core'
|
5
|
+
require 'merb-core/tasks/merb'
|
6
|
+
|
7
|
+
GEM_NAME = "merb_babel"
|
8
|
+
GEM_VERSION = "0.1.0.1"
|
9
|
+
AUTHOR = "Matt Aimonetti"
|
10
|
+
EMAIL = "mattaimonetti@gmail.com"
|
11
|
+
HOMEPAGE = "http://github.com/mattetti/merb_babel/"
|
12
|
+
SUMMARY = "Merb plugin that provides simple localization/internationalisation"
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.rubyforge_project = 'merb'
|
16
|
+
s.name = GEM_NAME
|
17
|
+
s.version = GEM_VERSION
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.extra_rdoc_files = ["README.markdown", "LICENSE", 'TODO']
|
21
|
+
s.summary = SUMMARY
|
22
|
+
s.description = s.summary
|
23
|
+
s.author = AUTHOR
|
24
|
+
s.email = EMAIL
|
25
|
+
s.homepage = HOMEPAGE
|
26
|
+
s.add_dependency('merb', '>= 1.0.7.1')
|
27
|
+
s.require_path = 'lib'
|
28
|
+
s.files = %w(LICENSE README.markdown Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
32
|
+
pkg.gem_spec = spec
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "install the plugin as a gem"
|
36
|
+
task :install do
|
37
|
+
Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Uninstall the gem"
|
41
|
+
task :uninstall do
|
42
|
+
Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Create a gemspec file"
|
46
|
+
task :gemspec do
|
47
|
+
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
48
|
+
file.puts spec.to_ruby
|
49
|
+
end
|
50
|
+
end
|
data/TODO
ADDED
data/lib/merb_babel.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__) / "merb_babel" / "core_ext")
|
2
|
+
|
3
|
+
# make sure we're running inside Merb
|
4
|
+
if defined?(Merb::Plugins)
|
5
|
+
|
6
|
+
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
|
7
|
+
Merb::Plugins.config[:merb_babel] = {
|
8
|
+
:default_locale => 'en-US',
|
9
|
+
:default_language => 'en',
|
10
|
+
# :default_country => 'US',
|
11
|
+
:localization_dirs => ["#{Merb.root}/lang"]
|
12
|
+
}
|
13
|
+
|
14
|
+
require File.join(File.dirname(__FILE__) / "merb_babel" / "m_locale")
|
15
|
+
require File.join(File.dirname(__FILE__) / "merb_babel" / "m_l10n")
|
16
|
+
require File.join(File.dirname(__FILE__) / "merb_babel" / "m_i18n")
|
17
|
+
|
18
|
+
Merb::BootLoader.before_app_loads do
|
19
|
+
# require code that must be loaded before the application
|
20
|
+
module Merb
|
21
|
+
module GlobalHelpers
|
22
|
+
|
23
|
+
# Used to translate words using localizations
|
24
|
+
def babelize(key, *args)
|
25
|
+
begin
|
26
|
+
options = args.first
|
27
|
+
options ||= {}
|
28
|
+
options.merge!(:key => key)
|
29
|
+
options.merge!(:language => language) unless options.has_key?(:language)
|
30
|
+
options.merge!(:country => country) unless options.has_key?(:country)
|
31
|
+
MI18n.lookup(options)
|
32
|
+
rescue
|
33
|
+
key.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias :translate :babelize
|
37
|
+
alias :t :babelize
|
38
|
+
alias :_ :babelize
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Merb::Controller.send(:include, MLocale)
|
44
|
+
ML10n.load_localization!
|
45
|
+
end
|
46
|
+
|
47
|
+
Merb::BootLoader.after_app_loads do
|
48
|
+
# code that can be required after the application loads
|
49
|
+
end
|
50
|
+
|
51
|
+
Merb::Plugins.add_rakefiles "merb_babel/merbtasks"
|
52
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module MerbBabel
|
2
|
+
|
3
|
+
module HashExtension
|
4
|
+
|
5
|
+
def symbolize_keys
|
6
|
+
inject({}) do |options, (key, value)|
|
7
|
+
options[key.to_sym || key] = value
|
8
|
+
options
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def symbolize_keys!
|
13
|
+
self.replace(self.symbolize_keys)
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid_localization_hash?
|
17
|
+
self.has_key?(:mloc_language_code)
|
18
|
+
end
|
19
|
+
|
20
|
+
def localization_hash_with_locale?
|
21
|
+
self.has_key?(:mloc_country_code)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
Hash.send :include, MerbBabel::HashExtension
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module MI18n
|
2
|
+
|
3
|
+
def self.lookup(options)
|
4
|
+
key = options[:key]
|
5
|
+
language = options[:language]
|
6
|
+
country = options[:country]
|
7
|
+
raise ArgumentError, "You need to pass a language reference" unless language
|
8
|
+
raise ArgumentError, "You need to pass a localization key" unless key
|
9
|
+
raise ArgumentError, "language: #{language} not found" unless ML10n.localizations[language]
|
10
|
+
|
11
|
+
full_location = nil
|
12
|
+
full_location = lookup_with_full_locale(key, language, country) if country
|
13
|
+
|
14
|
+
if full_location
|
15
|
+
return full_location
|
16
|
+
else
|
17
|
+
return ML10n.localizations[language][key]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.lookup_with_full_locale(key, language, country)
|
22
|
+
if ML10n.localizations.has_key?(language)
|
23
|
+
ML10n.localizations[language].has_key?(country) ? ML10n.localizations[language][country][key] : nil
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module ML10n
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# TODO add a mutex for when we load the localizations, in case people want to load the localizations
|
6
|
+
# at runtime
|
7
|
+
|
8
|
+
# all localizations are saved in this class variable
|
9
|
+
# localizations are namespaced using the language or locale they belong to
|
10
|
+
#
|
11
|
+
# for instance:
|
12
|
+
# ML10n.localizations['en'][:right] => 'right'
|
13
|
+
# ML10n.localizations['en'][:left] => 'left'
|
14
|
+
# ML10n.localizations['en']['US'][:greeting] => 'Howdie'
|
15
|
+
# ML10n.localizations['en']['AU'][:greeting] => "Good'ay"
|
16
|
+
#
|
17
|
+
# locales, including languages and countries use string keys while localization keys themselves are symbols
|
18
|
+
def localizations
|
19
|
+
@@localizations ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
# files containing localizations
|
23
|
+
def localization_files
|
24
|
+
@@localization_files ||= ML10n.find_localization_files
|
25
|
+
end
|
26
|
+
|
27
|
+
# locations to look for localization files
|
28
|
+
def localization_dirs
|
29
|
+
@@localization_dirs ||= Merb::Plugins.config[:merb_babel][:localization_dirs].dup
|
30
|
+
end
|
31
|
+
|
32
|
+
# add a dir to look for localizations
|
33
|
+
def add_localization_dir(dir_path)
|
34
|
+
return ML10n.localization_dirs if dir_path.empty?
|
35
|
+
unless ML10n.localization_dirs.include?(dir_path)
|
36
|
+
ML10n.localization_dirs << dir_path
|
37
|
+
ML10n.reload_localization_files!
|
38
|
+
end
|
39
|
+
return ML10n.localization_dirs
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_localization!
|
43
|
+
|
44
|
+
# look for localization files directly just in case new files were added
|
45
|
+
ML10n.reset_localization_files!
|
46
|
+
ML10n.find_localization_files.each do |l_file|
|
47
|
+
begin
|
48
|
+
l_hash = YAML.load_file(l_file).symbolize_keys
|
49
|
+
rescue Exception => e
|
50
|
+
# might raise a real error here in the future
|
51
|
+
p e.inspect
|
52
|
+
else
|
53
|
+
load_localization_hash(l_hash)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
# go through the localization dirs and find the localization files
|
60
|
+
def find_localization_files
|
61
|
+
l_files = []
|
62
|
+
ML10n.localization_dirs.map do |l_dir|
|
63
|
+
Dir["#{l_dir}/*", '*.{yml,yaml}'].each do |file|
|
64
|
+
l_files << file unless l_files.include?(file)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
return l_files
|
68
|
+
end
|
69
|
+
|
70
|
+
# reset the localization dirs and files to the plugin config
|
71
|
+
# careful when using this method since it will remove any localization files
|
72
|
+
# you loaded after the plugin started
|
73
|
+
#
|
74
|
+
# note that it won't clear the localization already loaded in memory
|
75
|
+
def reset_localization_files_and_dirs!
|
76
|
+
ML10n.reset_localization_dirs!
|
77
|
+
ML10n.reset_localization_files!
|
78
|
+
end
|
79
|
+
|
80
|
+
def reset_localization_dirs!
|
81
|
+
@@localization_dirs = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def reset_localization_files!
|
85
|
+
@@localization_files = nil
|
86
|
+
ML10n.find_localization_files
|
87
|
+
end
|
88
|
+
|
89
|
+
def reload_localization_files!
|
90
|
+
ML10n.reset_localization_files!
|
91
|
+
ML10n.find_localization_files
|
92
|
+
end
|
93
|
+
|
94
|
+
# localization helper
|
95
|
+
def localize(key, *options)
|
96
|
+
MI18n.localize(options.merge({:locale => locale}))
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
def load_localization_hash(l_hash)
|
102
|
+
if l_hash.valid_localization_hash?
|
103
|
+
language = l_hash[:mloc_language_code]
|
104
|
+
if l_hash.localization_hash_with_locale?
|
105
|
+
country = l_hash[:mloc_country_code]
|
106
|
+
# load localization under the full locale namespace
|
107
|
+
ML10n.localizations[language] ||= {}
|
108
|
+
(ML10n.localizations[language][country] ||= {}).merge!(l_hash)
|
109
|
+
else
|
110
|
+
# load generic language localization
|
111
|
+
(ML10n.localizations[language] ||= {}).merge!(l_hash)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# The MLocale module helps you set up a locale, language, country
|
2
|
+
# You don't have to use a locale, in some cases you might just want to use the language
|
3
|
+
module MLocale
|
4
|
+
|
5
|
+
# A locale is made of a language + country code, such as en-UK or en-US
|
6
|
+
def locale
|
7
|
+
request.env[:locale] || params[:locale] || (session ? session[:locale] : nil) || default_locale
|
8
|
+
end
|
9
|
+
|
10
|
+
# Many people don't care about locales, they might just want to use languages instead
|
11
|
+
def language
|
12
|
+
request.env[:language] || params[:language] || language_from_locale || (session ? session[:language] : nil) || default_language
|
13
|
+
end
|
14
|
+
|
15
|
+
# The country is used when localizing currency or time
|
16
|
+
def country
|
17
|
+
request.env[:country] || params[:country] || country_from_locale || (session ? session[:country] : nil) || default_country
|
18
|
+
end
|
19
|
+
|
20
|
+
# Extract the language from the locale
|
21
|
+
def language_from_locale
|
22
|
+
if request.env[:locale] && request.env[:locale] =~ locale_regexp
|
23
|
+
language, country = request.env[:locale].match(locale_regexp).captures
|
24
|
+
return language
|
25
|
+
else
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Extract the country from the locale
|
31
|
+
def country_from_locale
|
32
|
+
request.env[:locale] ? request.env[:locale][3..5].upcase : nil
|
33
|
+
end
|
34
|
+
|
35
|
+
# Defaults set in the plugin settings
|
36
|
+
# You can change the default settings by overwriting
|
37
|
+
# the Merb::Plugins.config[:merb_abel] hash in your settings
|
38
|
+
#
|
39
|
+
def default_locale
|
40
|
+
Merb::Plugins.config[:merb_babel] ? Merb::Plugins.config[:merb_babel][:default_locale] : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def default_language
|
44
|
+
Merb::Plugins.config[:merb_babel] ? Merb::Plugins.config[:merb_babel][:default_language] : nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_country
|
48
|
+
Merb::Plugins.config[:merb_babel] ? Merb::Plugins.config[:merb_babel][:default_country] : nil
|
49
|
+
end
|
50
|
+
#
|
51
|
+
#### end of defaults
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def locale_regexp
|
56
|
+
/(.+)\-([a-z]{2})/i
|
57
|
+
end
|
58
|
+
|
59
|
+
# takes a locale as in fr-FR or en-US
|
60
|
+
def set_locale
|
61
|
+
|
62
|
+
if locale =~ locale_regexp
|
63
|
+
language, country = locale.match(locale_regexp).captures
|
64
|
+
# Set the locale, language and country
|
65
|
+
language = language.downcase
|
66
|
+
country = country.upcase
|
67
|
+
request.env[:locale] = "#{language}-#{country}"
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_language
|
73
|
+
request.env[:language] = language.downcase
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/spec/lang/en-UK.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#################################################
|
2
|
+
# en-UK only localization
|
3
|
+
#
|
4
|
+
# only add localization specific to this locale
|
5
|
+
# other comman localizations must go in en.yml
|
6
|
+
#################################################
|
7
|
+
# required
|
8
|
+
mloc_language_code: en
|
9
|
+
# required for a locale localization file
|
10
|
+
mloc_country_code: UK
|
11
|
+
#################################################
|
12
|
+
|
13
|
+
greetings: Heya
|
data/spec/lang/en-US.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#################################################
|
2
|
+
# en-US only localization
|
3
|
+
#
|
4
|
+
# only add localization specific to this locale
|
5
|
+
# other comman localizations must go in en.yml
|
6
|
+
#################################################
|
7
|
+
# required
|
8
|
+
mloc_language_code: en
|
9
|
+
# required for a locale localization file
|
10
|
+
mloc_country_code: US
|
11
|
+
#################################################
|
12
|
+
|
13
|
+
greetings: Howdie
|
data/spec/lang/en.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#################################################
|
2
|
+
# English localization
|
3
|
+
#
|
4
|
+
# localization specific must go in their own file
|
5
|
+
# see en-US.yml for instance
|
6
|
+
#################################################
|
7
|
+
mloc_language_code: en
|
8
|
+
# Optional, the following key has the name of the localized language in its ow language.
|
9
|
+
mloc_language_name: English
|
10
|
+
# mloc_country:
|
11
|
+
#################################################
|
12
|
+
|
13
|
+
|
14
|
+
right: right
|
15
|
+
left: left
|
16
|
+
greetings: Hello
|
data/spec/m_i18n_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe '#babelize' do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Merb::Controller.send :include, Merb::GlobalHelpers
|
7
|
+
@c = dispatch_to(TestController, :index)
|
8
|
+
ML10n.add_localization_dir(File.expand_path(File.dirname(__FILE__) + "/lang"))
|
9
|
+
ML10n.add_localization_dir(File.expand_path(File.dirname(__FILE__) + "/other_lang_dir"))
|
10
|
+
ML10n.load_localization!
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should babelize a word in English " do
|
14
|
+
@c.locale.should == 'en-US'
|
15
|
+
@c.language.should == 'en'
|
16
|
+
@c.country.should == 'US'
|
17
|
+
@c.babelize(:left).should == 'left'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should translate a word in English" do
|
21
|
+
@c.t(:left).should == 'left'
|
22
|
+
@c.translate(:left).should == 'left'
|
23
|
+
@c._(:left).should == 'left'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should translate a word in american English" do
|
27
|
+
@c.t(:greetings).should == 'Howdie'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should translate a word in british English" do
|
31
|
+
@c.request.env[:locale] = 'en-UK'
|
32
|
+
@c.t(:greetings).should == 'Heya'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should translate a word in French" do
|
36
|
+
@c.request.env[:language] = 'fr'
|
37
|
+
@c.t(:greetings).should == 'Salut'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should translate passing the full locale" do
|
41
|
+
@c.t(:greetings, :language => 'en', :country => 'UK').should == 'Heya'
|
42
|
+
@c.t(:greetings, :language => 'en', :country => 'US').should == 'Howdie'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should translate passing the language" do
|
46
|
+
@c.t(:greetings, :language => 'fr').should == 'Salut'
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/spec/m_l10n_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "ML10n" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@lang_test_path = File.expand_path(File.dirname(__FILE__) + "/lang")
|
7
|
+
@lang_test_path_2 = File.expand_path(File.dirname(__FILE__) + "/other_lang_dir")
|
8
|
+
ML10n.reset_localization_files_and_dirs!
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have a list of localization directories" do
|
12
|
+
ML10n.localization_dirs.should == Merb::Plugins.config[:merb_babel][:localization_dirs]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to add a new localization directory" do
|
16
|
+
ML10n.add_localization_dir(@lang_test_path)
|
17
|
+
ML10n.localization_dirs.include?(@lang_test_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have a list of localization source files" do
|
21
|
+
ML10n.localization_files.should == []
|
22
|
+
ML10n.add_localization_dir(@lang_test_path)
|
23
|
+
ML10n.localization_files.include?("#{@lang_test_path}/en.yml").should be_true
|
24
|
+
ML10n.localization_files.include?("#{@lang_test_path}/en-US.yml").should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should load localization files and have them available" do
|
28
|
+
ML10n.add_localization_dir(@lang_test_path)
|
29
|
+
ML10n.load_localization!
|
30
|
+
ML10n.localizations['en'][:right].should == 'right'
|
31
|
+
ML10n.localizations['en'][:left].should == 'left'
|
32
|
+
ML10n.localizations['en']['US'][:greetings].should == 'Howdie'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should load more localization files and have them available" do
|
36
|
+
ML10n.add_localization_dir(@lang_test_path)
|
37
|
+
ML10n.load_localization!
|
38
|
+
ML10n.localizations['en'][:right].should == 'right'
|
39
|
+
ML10n.localizations.has_key?('fr').should be_false
|
40
|
+
|
41
|
+
ML10n.add_localization_dir(@lang_test_path_2)
|
42
|
+
ML10n.load_localization!
|
43
|
+
ML10n.localizations['en'][:right].should == 'right'
|
44
|
+
ML10n.localizations.has_key?('fr').should be_true
|
45
|
+
ML10n.localizations['fr'][:right].should == 'la droite'
|
46
|
+
ML10n.localizations['fr'][:left].should == 'la gauche'
|
47
|
+
ML10n.localizations['fr'][:greetings].should == 'Salut'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'using set_locale before filter, ' do
|
5
|
+
describe 'a controller' do
|
6
|
+
|
7
|
+
describe 'locale' do
|
8
|
+
|
9
|
+
it "should be set by default" do
|
10
|
+
c = dispatch_to(TestController, :index)
|
11
|
+
c.locale.should == 'en-US'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be able to be set by passing a param" do
|
15
|
+
c = dispatch_to(TestController, :index, :locale => 'fr-FR')
|
16
|
+
c.locale.should == 'fr-FR'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to be set using the session" do
|
20
|
+
c = dispatch_to(TestController, :index) do |controller|
|
21
|
+
controller.stub!(:session).and_return( :locale => "es-BO" )
|
22
|
+
end
|
23
|
+
c.locale.should == 'es-BO'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be set using an url (when the routes are set properly)" do
|
27
|
+
#c = get('tests')
|
28
|
+
#c.locale.should == 'en-US'
|
29
|
+
c = get('en-US/tests')
|
30
|
+
c.locale.should == 'en-US'
|
31
|
+
c = get('en-UK/tests')
|
32
|
+
c.locale.should == 'en-UK'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should support longer locales (like zh-Hans-CN)" do
|
36
|
+
c = dispatch_to(TestController, :index, :locale => 'zh-Hans-CN')
|
37
|
+
c.locale.should == 'zh-hans-CN'
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'language' do
|
43
|
+
|
44
|
+
it "should be set by default" do
|
45
|
+
c = dispatch_to(TestController, :index)
|
46
|
+
c.language.should == 'en'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be able to be set by passing a param" do
|
50
|
+
c = dispatch_to(TestController, :index, :language => 'fr')
|
51
|
+
c.language.should == 'fr'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should bet set when a locale was set by params" do
|
55
|
+
c = dispatch_to(TestController, :index, :locale => 'fr-FR')
|
56
|
+
c.locale.should == 'fr-FR'
|
57
|
+
c.language.should == 'fr'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should be set when a locale was set by params even with a long locale" do
|
61
|
+
c = dispatch_to(TestController, :index, :locale => 'zh-Hans-CN')
|
62
|
+
c.language.should == 'zh-hans'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should bet set when a locale was set by session" do
|
66
|
+
c = dispatch_to(TestController, :index) do |controller|
|
67
|
+
controller.stub!(:session).and_return( :locale => "es-BO" )
|
68
|
+
end
|
69
|
+
c.language.should == 'es'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should be set by the router" do
|
73
|
+
c = get('fr/languages')
|
74
|
+
c.language.should == 'fr'
|
75
|
+
c.locale.should == 'en-US'
|
76
|
+
# c = get('languages')
|
77
|
+
# c.language.should == 'en'
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'country' do
|
83
|
+
|
84
|
+
it "should be set by default" do
|
85
|
+
c = dispatch_to(TestController, :index)
|
86
|
+
c.country.should == 'US'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should be able to be set by passing a param" do
|
90
|
+
c = dispatch_to(TestController, :index, :country => 'ES')
|
91
|
+
c.country.should == 'ES'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should bet set when a locale was set by params" do
|
95
|
+
c = dispatch_to(TestController, :index, :locale => 'fr-FR')
|
96
|
+
c.country.should == 'FR'
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should bet set when a locale was set by session" do
|
100
|
+
c = dispatch_to(TestController, :index) do |controller|
|
101
|
+
controller.stub!(:session).and_return( :locale => "es-BO" )
|
102
|
+
end
|
103
|
+
c.country.should == 'BO'
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'using set_language, ' do
|
112
|
+
describe 'a controller' do
|
113
|
+
describe 'language' do
|
114
|
+
|
115
|
+
it "should be set by default" do
|
116
|
+
c = dispatch_to(LanguageController, :index)
|
117
|
+
c.language.should == 'en'
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to be set by passing a param" do
|
121
|
+
c = dispatch_to(LanguageController, :index, :language => 'fr')
|
122
|
+
c.language.should == 'fr'
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#################################################
|
2
|
+
# French localization
|
3
|
+
#
|
4
|
+
# localization specific must go in their own file
|
5
|
+
# see en-US.yml for instance
|
6
|
+
#################################################
|
7
|
+
mloc_language_code: fr
|
8
|
+
# mloc_country:
|
9
|
+
#################################################
|
10
|
+
|
11
|
+
right: la droite
|
12
|
+
left: la gauche
|
13
|
+
greetings: Salut
|
14
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
$TESTING=true
|
2
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require "rubygems"
|
4
|
+
require "spec"
|
5
|
+
require "merb-core"
|
6
|
+
require File.join(File.dirname(__FILE__), "..", 'lib', 'merb_babel')
|
7
|
+
|
8
|
+
default_options = {
|
9
|
+
:environment => 'test',
|
10
|
+
:adapter => 'runner',
|
11
|
+
:session_store => 'cookie',
|
12
|
+
:session_secret_key => '187a66e27674660418cf4499471d5a0587f360d0'
|
13
|
+
}
|
14
|
+
|
15
|
+
options = default_options.merge($START_OPTIONS || {})
|
16
|
+
|
17
|
+
Merb.disable(:initfile)
|
18
|
+
Merb.start_environment(options)
|
19
|
+
|
20
|
+
Spec::Runner.configure do |config|
|
21
|
+
config.include Merb::Test::ViewHelper
|
22
|
+
config.include Merb::Test::RouteHelper
|
23
|
+
config.include Merb::Test::RequestHelper
|
24
|
+
config.include Merb::Test::ControllerHelper
|
25
|
+
end
|
26
|
+
|
27
|
+
Merb.load_dependencies(:environment => 'test')
|
28
|
+
|
29
|
+
Merb::Router.prepare do |r|
|
30
|
+
r.match(/\/?(en\-US|en\-UK|es\-ES|es\-AR)?/).to(:locale => "[1]") do |l|
|
31
|
+
l.match("/tests").to(:controller => "test_controller")
|
32
|
+
end
|
33
|
+
r.match(/\/?(en|es|fr|de)?/).to(:language => "[1]") do |l|
|
34
|
+
l.match("/languages").to(:controller => "language_controller")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
class TestController < Merb::Controller
|
41
|
+
|
42
|
+
before :set_locale
|
43
|
+
def index; end
|
44
|
+
end
|
45
|
+
|
46
|
+
class LanguageController < Merb::Controller
|
47
|
+
|
48
|
+
before :set_language
|
49
|
+
def index; end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: genki-merb_babel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Aimonetti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-02 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: merb
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.7.1
|
23
|
+
version:
|
24
|
+
description: Merb plugin that provides simple localization/internationalisation
|
25
|
+
email: mattaimonetti@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README.markdown
|
32
|
+
- LICENSE
|
33
|
+
- TODO
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README.markdown
|
37
|
+
- Rakefile
|
38
|
+
- TODO
|
39
|
+
- lib/merb_babel
|
40
|
+
- lib/merb_babel/core_ext.rb
|
41
|
+
- lib/merb_babel/m_i18n.rb
|
42
|
+
- lib/merb_babel/m_l10n.rb
|
43
|
+
- lib/merb_babel/m_locale.rb
|
44
|
+
- lib/merb_babel/merbtasks.rb
|
45
|
+
- lib/merb_babel.rb
|
46
|
+
- spec/lang
|
47
|
+
- spec/lang/en-UK.yml
|
48
|
+
- spec/lang/en-US.yml
|
49
|
+
- spec/lang/en.yml
|
50
|
+
- spec/m_i18n_spec.rb
|
51
|
+
- spec/m_l10n_spec.rb
|
52
|
+
- spec/merb_babel_spec.rb
|
53
|
+
- spec/other_lang_dir
|
54
|
+
- spec/other_lang_dir/fr.yml
|
55
|
+
- spec/spec_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/mattetti/merb_babel/
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
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: merb
|
78
|
+
rubygems_version: 1.2.0
|
79
|
+
signing_key:
|
80
|
+
specification_version: 2
|
81
|
+
summary: Merb plugin that provides simple localization/internationalisation
|
82
|
+
test_files: []
|
83
|
+
|