r18n-rails 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +166 -0
- data/README.rdoc +223 -0
- data/lib/r18n-rails.rb +37 -0
- data/lib/r18n-rails/controller.rb +52 -0
- data/lib/r18n-rails/helpers.rb +47 -0
- data/spec/app/app/controllers/application_controller.rb +4 -0
- data/spec/app/app/controllers/test_controller.rb +23 -0
- data/spec/app/app/helpers/application_helper.rb +3 -0
- data/spec/app/app/i18n/en.yml +2 -0
- data/spec/app/app/i18n/ru.yml +2 -0
- data/spec/app/app/models/post.rb +4 -0
- data/spec/app/app/views/test/helpers.html.erb +4 -0
- data/spec/app/config/boot.rb +110 -0
- data/spec/app/config/database.yml +17 -0
- data/spec/app/config/environment.rb +9 -0
- data/spec/app/config/environments/development.rb +17 -0
- data/spec/app/config/environments/production.rb +28 -0
- data/spec/app/config/environments/test.rb +28 -0
- data/spec/app/config/initializers/session_store.rb +15 -0
- data/spec/app/config/locales/en.yml +7 -0
- data/spec/app/config/routes.rb +4 -0
- data/spec/app/db/migrate/20091218123631_create_posts.rb +12 -0
- data/spec/app/db/test.sqlite3 +0 -0
- data/spec/app/log/test.log +789 -0
- data/spec/app/script/server +3 -0
- data/spec/rails_spec.rb +77 -0
- data/spec/spec_helper.rb +6 -0
- metadata +90 -0
data/LICENSE
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
166
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
= R18n for Rails
|
2
|
+
|
3
|
+
R18n-rails is a gem to add out-of-box R18n support to Rails I18n.
|
4
|
+
|
5
|
+
It is just a wrapper for R18n Rails API and R18n core libraries. See R18n core
|
6
|
+
documentation for more information.
|
7
|
+
|
8
|
+
== Features
|
9
|
+
|
10
|
+
R18n for Rails has full compatibility with Rails I18n, but add extra features:
|
11
|
+
|
12
|
+
=== R18n Syntax
|
13
|
+
|
14
|
+
You can use more compact, explicit and ruby-style syntax.
|
15
|
+
|
16
|
+
Translations in R18n format will be loaded from <tt>app/i18n/_locale_.yml</tt>:
|
17
|
+
|
18
|
+
user:
|
19
|
+
name: User name is %1
|
20
|
+
count: !!pl
|
21
|
+
0: No users
|
22
|
+
1: 1 user
|
23
|
+
n: %1 users
|
24
|
+
|
25
|
+
R18n extend +t+ helper to add optional R18n syntax:
|
26
|
+
|
27
|
+
t.user.name('John') #=> "User name is John"
|
28
|
+
t.user.count(5) #=> "5 users"
|
29
|
+
t.not.exists | 'default' #=> "default"
|
30
|
+
|
31
|
+
=== Filters
|
32
|
+
|
33
|
+
R18n has flexible architecture based on filters. Variables, pluralization,
|
34
|
+
untranslated are a common filters, and you can change all of them. For example,
|
35
|
+
write untranslated keys to file:
|
36
|
+
|
37
|
+
R18n::Filters.add(::R18n::Untranslated, :write_untranslated) do
|
38
|
+
|v, c, translated, untranslated, path|
|
39
|
+
File.open('untranslated.list', 'w') do |io|
|
40
|
+
io.puts(path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
R18n already has filters for HTML escaping, lambdas, Textile and Markdown:
|
45
|
+
|
46
|
+
hi: !!markdown
|
47
|
+
**Hi**, people!
|
48
|
+
greater: !!escape
|
49
|
+
1 < 2 is true
|
50
|
+
|
51
|
+
i18n.hi #=> "<p><strong>Hi</strong>, people!</p>"
|
52
|
+
i18n.greater #=> "1 < 2 is true"
|
53
|
+
|
54
|
+
=== Model Translation
|
55
|
+
|
56
|
+
R18n can add i18n support for your ActiveRecord model and any other class:
|
57
|
+
|
58
|
+
1. Add separated column for all supported translations:
|
59
|
+
|
60
|
+
def self.up
|
61
|
+
create_table :posts do |t|
|
62
|
+
t.string :title_en
|
63
|
+
t.string :title_ru
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
2. Add virtual method +title+, which will use <tt>title_<i>locale</i></tt>
|
68
|
+
methods to find actual translation:
|
69
|
+
|
70
|
+
class Post < ActiveRecord::Base
|
71
|
+
include R18n::Translated
|
72
|
+
translations :title
|
73
|
+
end
|
74
|
+
|
75
|
+
# For Russian user
|
76
|
+
post = Post.new
|
77
|
+
post.title_en = 'Post'
|
78
|
+
post.title_ru = 'Запись'
|
79
|
+
post.title = 'Запись'
|
80
|
+
|
81
|
+
post.title = 'Другая' # will user title_ru, by user first locale
|
82
|
+
|
83
|
+
=== Time Fomatters
|
84
|
+
|
85
|
+
R18n add +full+ time formatter based on locale info:
|
86
|
+
|
87
|
+
# English
|
88
|
+
l Time.now, :full #=> "1st of December, 2009 12:00"
|
89
|
+
|
90
|
+
# French
|
91
|
+
l Time.now, :full #=> "1er décembre 2009 12:00"
|
92
|
+
|
93
|
+
=== Locales
|
94
|
+
|
95
|
+
R18n contain locales info, so it out-of-box support locale plural and fallback
|
96
|
+
rules for non-English locales:
|
97
|
+
|
98
|
+
# Russian have different plural rules:
|
99
|
+
user:
|
100
|
+
count: !!pl
|
101
|
+
0: Нет пользователей
|
102
|
+
1: %1 пользователь
|
103
|
+
2: %1 пользователя
|
104
|
+
n: %1 пользователей
|
105
|
+
|
106
|
+
t.user.count(2) #=> "2 пользователя"
|
107
|
+
t.user.count(21) #=> "21 пользователь"
|
108
|
+
|
109
|
+
=== Autodetect User Locales
|
110
|
+
|
111
|
+
R18n automatically generate fallback for current user, based on
|
112
|
+
user locales list from HTTP_ACCEPT_LANGUAGE, locale info (in some country people
|
113
|
+
know several languages) and default locale.
|
114
|
+
|
115
|
+
For example, if user know Kazakh and German, R18n will try find translations in:
|
116
|
+
Kazakh → German → Russian (second language in Kazakhstan) → English (default
|
117
|
+
locale).
|
118
|
+
|
119
|
+
=== Separated I18n
|
120
|
+
|
121
|
+
You can create another R18n I18n instance with another languages. For example,
|
122
|
+
to send e-mail for English admin on error with French user:
|
123
|
+
|
124
|
+
puts I18n.t :error # Show error on French
|
125
|
+
|
126
|
+
admin_i18n = R18n::I18n.new(@admin_locales, Rails.root + 'app/i18n')
|
127
|
+
send_email(admin_i18n.error_messages)
|
128
|
+
|
129
|
+
== How To
|
130
|
+
|
131
|
+
1. Add <tt>r18n-rails</tt> gem to your <tt>config/environment.rb</tt>:
|
132
|
+
|
133
|
+
config.gem 'r18n-rails'
|
134
|
+
|
135
|
+
Now R18n will be autodetect user locales.
|
136
|
+
2. Add your way to set locale manually. R18n will find it in
|
137
|
+
<tt>params[:locale]</tt> or <tt>session[:locale]</tt>. Best way is a put
|
138
|
+
optional locale prefix to URLs:
|
139
|
+
|
140
|
+
map.connect ':controller/:action'
|
141
|
+
map.connect ':locale/:controller/:action'
|
142
|
+
|
143
|
+
3. Print available translations, to choise it manually (and to search engines):
|
144
|
+
|
145
|
+
<ul>
|
146
|
+
<% r18n.available_locales.each do |locale| %>
|
147
|
+
<li>
|
148
|
+
<a href="/<%= locale.code %>/"><%= locale.title %></a>
|
149
|
+
</li>
|
150
|
+
<% end %>
|
151
|
+
</ul>
|
152
|
+
|
153
|
+
4. Translations with I18n format put to <tt>config/locales/_locale_.yml</tt>:
|
154
|
+
|
155
|
+
en:
|
156
|
+
user:
|
157
|
+
name: "User name is {{name}}"
|
158
|
+
count:
|
159
|
+
zero: "No users"
|
160
|
+
one: "One user"
|
161
|
+
many: "{{count}} users"
|
162
|
+
|
163
|
+
Translations with R18n format put to <tt>app/i18n/_locale_.yml</tt>:
|
164
|
+
|
165
|
+
user:
|
166
|
+
name: User name is %1
|
167
|
+
count: !!pl
|
168
|
+
0: No users
|
169
|
+
1: 1 user
|
170
|
+
n: %1 users
|
171
|
+
|
172
|
+
5. Use translated messages in views. You can use Rails I18n syntax:
|
173
|
+
|
174
|
+
t 'user.name', :name => 'John'
|
175
|
+
t 'user.count', :count => 5
|
176
|
+
|
177
|
+
Or R18n syntax:
|
178
|
+
|
179
|
+
t.user.name(:name => 'John') # for Rails I18n named variables
|
180
|
+
t.user.name('John') # for R18n variables
|
181
|
+
t.user.count(5)
|
182
|
+
|
183
|
+
6. Print dates and numbers in user tradition:
|
184
|
+
|
185
|
+
l Date.today, :standard #=> "20/12/2009"
|
186
|
+
l Time.now, :full #=> "20th of December, 2009 12:00"
|
187
|
+
l 1234.5 #=> "1,234.5"
|
188
|
+
|
189
|
+
7. Translate models:
|
190
|
+
|
191
|
+
1. Add to migration columns for each supported locales, with name
|
192
|
+
<tt><i>name</i>_<i>locale</i></tt>:
|
193
|
+
|
194
|
+
t.string :title_en
|
195
|
+
t.string :title_ru
|
196
|
+
|
197
|
+
t.string :text_en
|
198
|
+
t.string :text_ru
|
199
|
+
|
200
|
+
2. Add <tt>R18n::Translated</tt> mixin to model:
|
201
|
+
|
202
|
+
class Post < ActiveRecord::Base
|
203
|
+
include R18n::Translated
|
204
|
+
|
205
|
+
3. Call +translations+ method in model with all columns to translated:
|
206
|
+
|
207
|
+
translations :title, :text
|
208
|
+
|
209
|
+
Now model will be have virtual methods +title+, +text+, <tt>title=</tt>
|
210
|
+
and <tt>text=</tt>, which will call +title_ru+ or +title_en+ and etc based
|
211
|
+
on current user locales.
|
212
|
+
|
213
|
+
You can use <tt>R18n::Translated</tt> mixin for any Ruby class, not only for
|
214
|
+
ActiveRecord models.
|
215
|
+
|
216
|
+
== License
|
217
|
+
|
218
|
+
R18n is licensed under the GNU Lesser General Public License version 3.
|
219
|
+
You can read it in LICENSE file or in http://www.gnu.org/licenses/lgpl.html.
|
220
|
+
|
221
|
+
== Author
|
222
|
+
|
223
|
+
Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
data/lib/r18n-rails.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
=begin
|
2
|
+
R18n support for Rails.
|
3
|
+
|
4
|
+
Copyright (C) 2009 Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
5
|
+
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
This program is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
17
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'pathname'
|
21
|
+
require 'r18n-core'
|
22
|
+
require 'r18n-core/translated'
|
23
|
+
require 'r18n-rails-api'
|
24
|
+
|
25
|
+
dir = Pathname(__FILE__).dirname.expand_path + 'r18n-rails'
|
26
|
+
require dir + 'helpers'
|
27
|
+
require dir + 'controller'
|
28
|
+
|
29
|
+
R18n::Filters.off(:untranslated)
|
30
|
+
R18n::Filters.add(::R18n::Untranslated, :untranslated_html) do
|
31
|
+
|v, c, translated, untranslated, path|
|
32
|
+
"#{translated}<span style='color: red'>#{untranslated}</span>"
|
33
|
+
end
|
34
|
+
|
35
|
+
ActionController::Base.helper(R18n::Rails::Helpers)
|
36
|
+
ActionController::Base.send(:include, R18n::Rails::Controller)
|
37
|
+
ActionController::Base.send(:before_filter, :set_r18n)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
=begin
|
2
|
+
Methods and filters to controllers.
|
3
|
+
|
4
|
+
Copyright (C) 2009 Andrey “A.I.” Sitnik <andrey@sitnik.ru>
|
5
|
+
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
This program is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
17
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
=end
|
19
|
+
|
20
|
+
require 'r18n-rails-api'
|
21
|
+
|
22
|
+
module R18n
|
23
|
+
module Rails
|
24
|
+
module Controller
|
25
|
+
private
|
26
|
+
|
27
|
+
# Return current R18n instance.
|
28
|
+
def r18n
|
29
|
+
R18n.get
|
30
|
+
end
|
31
|
+
|
32
|
+
# Auto detect user locales and change backend.
|
33
|
+
def set_r18n
|
34
|
+
R18n.set do
|
35
|
+
locales = R18n::I18n.parse_http(request.env['HTTP_ACCEPT_LANGUAGE'])
|
36
|
+
|
37
|
+
if params[:locale]
|
38
|
+
locales.insert(0, params[:locale])
|
39
|
+
elsif session[:locale]
|
40
|
+
locales.insert(0, session[:locale])
|
41
|
+
end
|
42
|
+
|
43
|
+
places = [::Rails.root.join('app/i18n'), R18n::Loader::Rails.new]
|
44
|
+
|
45
|
+
R18n::I18n.new(locales, places)
|
46
|
+
end
|
47
|
+
|
48
|
+
::I18n.backend = R18n::Backend.new
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|