r18n-rails 0.4

Sign up to get free protection for your applications and to get access to all the features.
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
+
@@ -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 &lt; 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>
@@ -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