tr8n 3.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,324 +0,0 @@
1
- <%= tr8n_with_options_tag(:default_locale => 'en-US', :admin => true) do %>
2
-
3
- <style>
4
- h2 {
5
- font-weight: bold;
6
- }
7
- h3 {
8
- padding-top: 10px;
9
- }
10
- .snippet {
11
- border: 1px solid #ccc;
12
- margin-top:10px;
13
- margin-bottom:10px;
14
- padding:10px;
15
- background-color: #f8f8ff;
16
- }
17
- .snippet2 {
18
- border: 1px solid #ccc;
19
- margin-top:10px;
20
- margin-bottom:10px;
21
- padding:10px;
22
- background-color: #fff8f8;
23
- }
24
- .try_it {
25
- font-style:italic;
26
- }
27
- .toc {
28
- margin-left:20px;
29
- margin-bottom:20px;
30
- list-style-type:upper-roman;
31
- }
32
- .toc li div {
33
- border-bottom:1px dotted #ccc;
34
- font-size:16px;
35
- }
36
- .toc1 {
37
- margin-left:20px;
38
- list-style-type:lower-roman;
39
- }
40
- </style>
41
- <div style="text-align:center; margin:15px;">
42
- <%=image_tag("/tr8n/images/tr8n_logo.png", :style => "height:120px;")%>
43
- </div>
44
-
45
- <h2 class="underscore content_hd">
46
- <%=tr("Tr8n Label Internationalization")%>
47
- </h2>
48
-
49
- <div class="content_bd">
50
- <h2><%=tr("Table of Content") %></h2>
51
- <p>
52
- <ul class='toc'>
53
- <li><div><a href="#methods_introduction"><%=tr("Introduction") %></a></li>
54
- <li><div><a href="#token_defintion"><%=tr("Definition of Tr8n Tokens") %></a></li>
55
- <li><div><a href="#data_tokens"><%=tr("Data Tokens") %></a></li>
56
- <li><div><a href="#method_tokens"><%=tr("Method Tokens") %></a></li>
57
- <li><div><a href="#hidden_tokens"><%=tr("Hidden Tokens") %></a></li>
58
- <li><div><a href="#transform_tokens"><%=tr("Transform Tokens") %></a></li>
59
- <li><div><a href="#decoration_tokens"><%=tr("Decoration Tokens") %></a></li>
60
- <li><div><a href="#next"><%=tr("What's next?") %></a></div></li>
61
- </ul>
62
- </p>
63
-
64
- <a name="methods_introduction">&nbsp;</a>
65
- <h3>Introduction</h3>
66
-
67
- <p>
68
- The function for internationalizing labels has the following signature:
69
-
70
- <div class="snippet">
71
- &lt;%= tr(LABEL, DESCRIPTION = "", TOKENS = {}, OPTIONS = {}) %&gt;<br><br>
72
- * LABEL is a required string<br>
73
- * DESCRIPTION is an optional, but highly recommended string<br>
74
- * TOKENS is an optional hash of token values - it is required if tokens are used in the label<br>
75
- * OPTIONS is an optional hash of options<br>
76
- </div>
77
- </p>
78
-
79
- <p>
80
- The following is the first simplest example of an internationalized phrase:
81
-
82
- <div class="snippet">
83
- &lt;%= tr("Hello World") %&gt;
84
- </div>
85
-
86
- or alternatively:
87
-
88
- <div class="snippet">
89
- &lt;%= "Hello World".translate %&gt;
90
- </div>
91
- </p>
92
-
93
- <p class="try_it">Try it yourself:</p>
94
- <div class="snippet2">
95
- <%= tr("Hello World") %>
96
- </div>
97
-
98
- <p>As you might have noticed, the DESCRIPTION is not mandatory, but it should be used in cases when the label alone is not sufficient enough to determine the meaning of the sentence being translated. For example, when the translators use the bulk translation mode and look at the list of strings, they won’t be able to tell what the "Invite" by itself means. In that case DESCRIPTION will be very helpful.
99
- </p>
100
-
101
- <p>Tr8n translation engine uses label and description to create a unique key for each phrase. So the description serves two purposes: it creates a unique key for each label and it also gives a hint to the translators for the context in which the label is used. For example, the following two phrases will be registered as two independent entries in a database even though the have the same label, but a different description. The user will have to translate each one of them separately as they will have different translated labels in other languages.
102
- </p>
103
-
104
- <div class="snippet">
105
- &lt;%= tr("Invite", "Link to invite your friends to join the site") %&gt;<br>
106
- &lt;%= tr("Invite", "An invitation you recieved from your friend") %&gt;
107
- </div>
108
-
109
- <p>It is important to provide the best possible description for each phrase from the start. Keep in mind that changing a description in the future, after it has already been translated, will register a new phrase in the database and invalidate all of its translations. On the other hand, labels that are complete sentences may not need a description as they are fully self-contained.
110
- </p>
111
-
112
- <p class="try_it">Try it yourself:</p>
113
- <div class="snippet2">
114
- <%= tr("Invite", "Link to invite your friends to join the site") %><br>
115
- <%= tr("Invite", "An invitation you recieved from your friend") %>
116
- </div>
117
-
118
- <p>There are a number of other flavors of the "tr" function like trl, trfe, trfn that set default options for various reasons. You can read more about them in the Tr8n Integration Guide.
119
- </p>
120
-
121
- <p>The following is a short summary of the tr8n’s internationalization notations.</p>
122
-
123
- <a name="token_defintion">&nbsp;</a>
124
- <h3>Definition of Tr8n Tokens</h3>
125
-
126
- <p>It would have been boring if all of the labels in a site were just simple sentences without any dynamic data or decorations. Tr8n tokens are there to support the dynamic information in a label.
127
- </p>
128
-
129
- <p>Currently there are two major types of tokens defined in the extensible Tr8n syntax: data tokens and decoration tokens. Data tokens are defined as any strings surrounded by curly brackets inside of a label. So anything of this form {TOKEN_NAME} is considered a data token.
130
- </p>
131
-
132
- <p>Decoration tokens are defined as any string surrounded by squared brackets inside of a label. So anything of this form &#91;TOKEN_NAME: decorated value&#92; is considered a decoration token.
133
- </p>
134
-
135
- <p>There are a number of different flavors of data tokens. Below are some of the flavors with some examples.
136
- </p>
137
-
138
- <a name="data_tokens">&nbsp;</a>
139
- <h3>Data Tokens</h3>
140
-
141
- <p>There is a number of ways to substitute a data token with a value. Below are some of the main examples.
142
- </p>
143
-
144
- <strong>Simple string substitution:</strong>
145
-
146
- <div class="snippet">
147
- &lt;%= tr("Dear {user}", "Fragment sample", :user => current_user) %&gt;
148
- </div>
149
-
150
- <p>The to_s function will be applied on the value of the current_user variable and substituted into the {user} token.
151
- </p>
152
-
153
- <strong>Value substitution:</strong>
154
-
155
- <div class="snippet">
156
- &lt;%= tr("Dear {user}", "Fragment sample", :user => [current_user, display_user(current_user)]) %&gt;
157
- </div>
158
-
159
- <p>Notice one important thing that current_user is passed as a first element in the array. This is done for gender rules evaluation - i will describe this in the later sections. The second value is the actual value we want to subsitute into the {user} token.
160
- </p>
161
-
162
- <strong>Value substitution using symbol method call:</strong>
163
- <div class="snippet">
164
- &lt;%= tr("Dear {user}", "Fragment sample", :user => [current_user, :first_name]) %&gt;
165
- </div>
166
-
167
- <p>As in the previous example, first object for rules engine, second is a symbol that represents a method that will be called on the object and the result will be placed into the {user} token.
168
- </p>
169
-
170
- <strong>Value substitution using symbol method call with parameters:</strong>
171
- <div class="snippet">
172
- &lt;%= tr("Dear {user}", "Fragment sample", :user => [current_user, :some_method, "value"]) %&gt;
173
- </div>
174
-
175
- <p>Same as the above example, but the method can be called with some parameters.</p>
176
-
177
- <strong>Value substitution using lambda method call:</strong>
178
-
179
- <div class="snippet">
180
- &lt;%= tr("Dear {user}", "Fragment sample", :user => [current_user, lambda{|val| html_for(val)}]) %&gt;
181
- </div>
182
- <p>The second parameter can also be a lambda. In that case current_user will be passed as a val into the lambda and the result of the lambda evaluation will be placed into the {user} token.
183
- </p>
184
-
185
- <strong>Value substitution using lambda method call with parameters:</strong>
186
- <div class="snippet">
187
- &lt;%= tr("Dear {user}", "Fragment sample", :user => [current_user, lambda{|val, test| html_for(val, test)}], "test"]) %&gt;
188
- </div>
189
-
190
- <p>Same as the above, but lambda has some additional parameters.</p>
191
-
192
- <p>You may be wondering why we need so many variations. Well, they are all useful, as you will see later.
193
- </p>
194
-
195
- <p class="try_it">Try it yourself:</p>
196
- <div class="snippet2">
197
- <%= tr("Dear {user}", "Fragment sample", :user => [Tr8n::Config.current_user, :name]) %>
198
- </div>
199
-
200
- <a name="method_tokens">&nbsp;</a>
201
- <h3>Method Tokens</h3>
202
-
203
- <p>Method token allows you to call a method on a token itself. It is useful if you have multiple method calls on the same token in one sentence. Consider the following example:
204
- </p>
205
-
206
- <div class="snippet">
207
- &lt;%= tr("Dear {user.first_name} {user.last_name}", "Fragment sample", :user => current_user) %&gt;
208
- </div>
209
-
210
- <p>Since the substitution is implied in the token definition itself, you don’t have to use any of the basic data token substitution forms.
211
- </p>
212
-
213
- <a name="hidden_tokens">&nbsp;</a>
214
- <h3>Hidden Tokens</h3>
215
-
216
- <p>Hidden tokens are used primarely for the default language dynamic data substitution that would not make sense in the translated label. Hidden tokens will not appear as tokens when translator opens the translation dialog. Consider the following examples:
217
- </p>
218
-
219
- <div class="snippet">
220
- &lt;%= tr("{user} changed {_his_her} name", "Fragment sample", :user => current_user, :_his_her => current_user.his_her) %&gt;<br>
221
- &lt;%= tr("you have {count} {_messages}", "Fragment sample", :count => NUM, :_messages => "message".pluralize_for(NUM)) %&gt;
222
- </div>
223
-
224
- <p>In the first cases _his_her will be subsituted in English to the appropriate phrase based on the current_user gender. And in the second case the correct form of message will be used based on whether the number is 1 or other.
225
- </p>
226
-
227
- <p>There is a better approach for the above examples, using the Transform tokens. But there may still be situations when hidden token can be useful.
228
- </p>
229
-
230
- <a name="transform_tokens">&nbsp;</a>
231
- <h3>Transform tokens</h3>
232
-
233
- <p>Transform tokens are used together with rules defined in the rules engine. Their primary job is to provide shortcuts for rule based tokens in the site native language. Consider the following example:
234
- </p>
235
-
236
- <div class="snippet">
237
- &lt;%= tr("{user} changed {user| his, her} name", "Fragment sample", :user => current_user) %&gt;
238
- </div>
239
-
240
- <p>Notice that the hidden token has been replaced by the transform token. Keep in mind that {user} token must be registered as a gender based token. Consider another example:
241
- </p>
242
-
243
- <div class="snippet">
244
- &lt;%= tr("You have {count|| message, messages}", "Fragment sample", :count => messages.size) %&gt;
245
- </div>
246
-
247
- <p>Notice that, in this case, {count} must be registered as a number based token. When the native language rule is evaluated it will use the singular or plural form of the word "message" based on the value of count. A single pipe indicates that the comma delimited word(s) that follow it are dependent on the token value, but the token itself should not be displayed. A double pipe indicates that the value of the token should be displayd as well. You don’t have to provide the plural form of the word if it can be derived from a singular form. So {count|| message} will be good enough and it will be pluralized by the engine automatically. Every rule has support for a transform token. For example:
248
- </p>
249
-
250
- <div class="snippet">
251
- &lt;%= tr("Michael {date| turned, turns, will turn} 33 on {date}", "Fragment sample", :date => some_date) %&gt;
252
- </div>
253
-
254
- <p>This is the case when piped token is used for a date token object. And one more example for a list:
255
- </p>
256
-
257
- <div class="snippet">
258
- &lt;%= tr("{users|| likes, like} this link", "Fragment sample", :users => [users_list, lambda{|user| user.first_name}]) %&gt;
259
- </div>
260
-
261
- <p>In this case if the users array contains a single element it will use the first form, otherwise it will use the plural form.
262
- </p>
263
-
264
- <a name="decoration_tokens">&nbsp;</a>
265
- <h3>Decoration tokens</h3>
266
-
267
- <p>Decoration tokens are used to decorate some text in a label. Consider the following example:
268
- </p>
269
-
270
- <div class="snippet">
271
- &lt;%= tr("[link: Click here] to visit our site", "Fragment sample", :link => lambda{|text| link_to(text, 'http://www.google.com')}) %&gt;
272
- </div>
273
- <p>When this label is rendered "Click here" will be turned into a link. </p>
274
-
275
- <p class="try_it">Try it yourself:</p>
276
- <div class="snippet2">
277
- <%= tr("[link: Click here] to visit our site", "Fragment sample", :link => lambda{|text| link_to(text, 'http://www.google.com')}) %>
278
- </div>
279
-
280
- <p>Similarly you can do any kind of HTML decorations inside of the label. Alternative ways for using decorations are:</p>
281
- <div class="snippet">
282
- &lt;%= tr("[link: Click here] to visit Google", "Fragment sample", :link => "&lt;a href='http://www.google.com'&gt;{$0}&lt;/a&gt;") %&gt;
283
- </div>
284
-
285
- <p>{$0} is the translated value of the link. And another way, using a default decoration:
286
- </p>
287
-
288
- <div class="snippet">
289
- &lt;%= tr("[link: Click here] to visit Google", "Fragment sample", :link => ['http://www.google.com']) %&gt;
290
- </div>
291
-
292
- <p class="try_it">Try it yourself:</p>
293
- <div class="snippet2">
294
- <%= tr("[link: Click here] to visit Google", "Fragment sample", :link => ['http://www.google.com']) %>
295
- </div>
296
-
297
- <p>The default decorations are defined in the config/tr8n/tokens/decorations.yml file. The are presented in the following form:
298
- </p>
299
-
300
- <div class="snippet">
301
- bold: "&lt;strong>{$0}&lt;/strong>"<br>
302
- italic: "&lt;i>{$0}&lt;/i>"<br>
303
- link: "&lt;a href='{$1}' style='{$2}'>{$0}&lt;/a>"<br>
304
- </div>
305
-
306
- <p>You can edit the file and add as many of the default decorations as you need. Notice that you do not need to provide token parameters for decorations that only use {$0} token. So this would work just fine:
307
- </p>
308
-
309
- <div class="snippet">
310
- &lt;%= tr("This is some [bold: very cool] stuff!") %&gt;
311
- </div>
312
-
313
- <p class="try_it">Try it yourself:</p>
314
- <div class="snippet2">
315
- <%= tr("This is some [bold: very cool] stuff!") %>
316
- </div>
317
-
318
- <a name="next">&nbsp;</a>
319
- <h2>What's next?</h2>
320
-
321
- Cnogratulations! You have completed the second part of the integration guide. Now read on about <%=link_to("Tr8n Rules Engine Configuration", "/tr8n/home/rules")%>.
322
-
323
- </div>
324
- <% end %>
@@ -1,61 +0,0 @@
1
- #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- module Tr8n::CommonMethods
25
-
26
- # translation functions
27
- def tr(label, desc = "", tokens = {}, options = {})
28
- unless desc.nil? or desc.is_a?(String)
29
- raise Tr8n::Exception.new("The second parameter of the tr function must be a description")
30
- end
31
-
32
- begin
33
- url = request.url
34
- host = request.env['HTTP_HOST']
35
- source = "#{controller.class.name.underscore.gsub("_controller", "")}/#{controller.action_name}"
36
- rescue Exception => ex
37
- source = self.class.name
38
- url = nil
39
- host = 'localhost'
40
- end
41
-
42
- options.merge!(:source => source) unless options[:source]
43
- options.merge!(:caller => caller)
44
- options.merge!(:url => url)
45
- options.merge!(:host => host)
46
-
47
- # pp [source, options[:source], url]
48
-
49
- unless Tr8n::Config.enabled?
50
- return Tr8n::TranslationKey.substitute_tokens(label, tokens, options)
51
- end
52
-
53
- Tr8n::Config.current_language.translate(label, desc, tokens, options)
54
- end
55
-
56
- # for translating labels
57
- def trl(label, desc = "", tokens = {}, options = {})
58
- tr(label, desc, tokens, options.merge(:skip_decorations => true))
59
- end
60
-
61
- end
@@ -1,304 +0,0 @@
1
- #--
2
- # Copyright (c) 2010-2011 Michael Berkovich
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- module Tr8n::HelperMethods
25
- include Tr8n::CommonMethods
26
-
27
- def tr8n_options_for_select(options, selected = nil, description = nil, lang = Tr8n::Config.current_language)
28
- options_for_select(options.tro(description), selected)
29
- end
30
-
31
- def tr8n_phrases_link_tag(search = "", phrase_type = :without, phrase_status = :any)
32
- return unless Tr8n::Config.enabled?
33
- return if Tr8n::Config.current_language.default?
34
- return unless Tr8n::Config.open_registration_mode? or Tr8n::Config.current_user_is_translator?
35
- return unless Tr8n::Config.current_translator.enable_inline_translations?
36
-
37
- link_to(image_tag("/tr8n/images/translate_icn.gif", :style => "vertical-align:middle; border: 0px;", :title => search),
38
- :controller => "/tr8n/phrases", :action => :index,
39
- :search => search, :phrase_type => phrase_type, :phrase_status => phrase_status).html_safe
40
- end
41
-
42
- def tr8n_dir_attribute_tag
43
- "dir='<%=Tr8n::Config.current_language.dir%>'".html_safe
44
- end
45
-
46
- def tr8n_splash_screen_tag
47
- html = "<div id='tr8n_splash_screen' style='display:none'>"
48
- html << (render :partial => Tr8n::Config.splash_screen)
49
- html << "</div>"
50
- html.html_safe
51
- end
52
-
53
- def tr8n_language_flag_tag(lang = Tr8n::Config.current_language, opts = {})
54
- return "" unless Tr8n::Config.enable_language_flags?
55
- html = image_tag("/tr8n/images/flags/#{lang.flag}.png", :style => "vertical-align:middle;", :title => lang.native_name)
56
- html << "&nbsp;".html_safe
57
- html.html_safe
58
- end
59
-
60
- def tr8n_language_name_tag(lang = Tr8n::Config.current_language, opts = {})
61
- show_flag = opts[:flag].nil? ? true : opts[:flag]
62
- name_type = opts[:name].nil? ? :full : opts[:name] # :full, :native, :english, :locale
63
- linked = opts[:linked].nil? ? true : opts[:linked]
64
-
65
- html = "<span style='white-space: nowrap'>"
66
- html << tr8n_language_flag_tag(lang, opts) if show_flag
67
-
68
- name = case name_type
69
- when :native then lang.native_name
70
- when :english then lang.english_name
71
- when :locale then lang.locale
72
- else lang.full_name
73
- end
74
-
75
- if linked
76
- html << link_to(name.html_safe, :controller => "/tr8n/language",
77
- :action => :switch, :language_action => :switch_language,
78
- :locale => lang.locale,
79
- :source_url => opts[:source_url])
80
- else
81
- html << name
82
- end
83
-
84
- html << "</span>"
85
- html.html_safe
86
- end
87
-
88
- def tr8n_language_selector_tag(opts = {})
89
- opts[:style] ||= "color:#1166bb;"
90
- opts[:show_arrow] ||= true
91
- opts[:arrow_style] ||= "font-size:8px;"
92
- render(:partial => '/tr8n/common/language_selector', :locals => {:opts => opts})
93
- end
94
-
95
- def tr8n_language_strip_tag(opts = {})
96
- opts[:flag] = opts[:flag].nil? ? false : opts[:flag]
97
- opts[:name] = opts[:name].nil? ? :native : opts[:name]
98
- opts[:linked] = opts[:linked].nil? ? true : opts[:linked]
99
- opts[:javascript] = opts[:javascript].nil? ? false : opts[:javascript]
100
-
101
- render(:partial => '/tr8n/common/language_strip', :locals => {:opts => opts})
102
- end
103
-
104
- def tr8n_language_table_tag(opts = {})
105
- opts[:cols] = opts[:cols].nil? ? 4 : opts[:cols]
106
- opts[:col_size] = opts[:col_size].nil? ? "300px" : opts[:col_size]
107
- render(:partial => '/tr8n/common/language_table', :locals => {:opts => opts.merge(:name => :english)})
108
- end
109
-
110
- def tr8n_translator_login_tag(opts = {})
111
- opts[:class] ||= 'tr8n_right_horiz_list'
112
- render(:partial => '/tr8n/common/translator_login', :locals => {:opts => opts})
113
- end
114
-
115
- def tr8n_flashes_tag(opts = {})
116
- render(:partial => '/tr8n/common/flashes', :locals => {:opts => opts})
117
- end
118
-
119
- def tr8n_scripts_tag(opts = {})
120
- render(:partial => '/tr8n/common/scripts', :locals => {:opts => opts})
121
- end
122
-
123
- def tr8n_client_sdk_scripts_tag(opts = {})
124
- javascript_include_tag("/tr8n/javascripts/tr8n_client_sdk.js", :locals => {:opts => opts})
125
- end
126
-
127
- def tr8n_translator_rank_tag(translator, rank = nil)
128
- return "" unless translator
129
-
130
- rank ||= translator.rank || 0
131
-
132
- html = "<span dir='ltr'>"
133
- 1.upto(5) do |i|
134
- if rank > i * 20 - 10 and rank < i * 20
135
- html << image_tag("/tr8n/images/rating_star05.png")
136
- elsif rank < i * 20 - 10
137
- html << image_tag("/tr8n/images/rating_star0.png")
138
- else
139
- html << image_tag("/tr8n/images/rating_star1.png")
140
- end
141
- end
142
- html << "</span>"
143
- html.html_safe
144
- end
145
-
146
- def tr8n_help_icon_tag(filename = "index")
147
- link_to(image_tag("/tr8n/images/help.png", :style => "border:0px; vertical-align:middle;", :title => trl("Help")), {:controller => "/tr8n/help", :action => filename}, :target => "_new").html_safe
148
- end
149
-
150
- def tr8n_help_link(text, opts = {})
151
- filename = opts[:filename].nil? ? text.downcase.gsub(' ', '_') : opts[:filename]
152
- classname = "tr8n_selected" if filename == controller.action_name
153
- link_to(text, { :controller => "/tr8n/help", :action => filename }, :class => classname).html_safe
154
- end
155
-
156
- def tr8n_spinner_tag(id = "spinner", label = nil, cls='spinner')
157
- html = "<div id='#{id}' class='#{cls}' style='display:none'>"
158
- html << image_tag("/tr8n/images/spinner.gif", :style => "vertical-align:middle;")
159
- html << " #{trl(label)}" if label
160
- html << "</div>"
161
- html.html_safe
162
- end
163
-
164
- def tr8n_toggler_tag(content_id, label = "", open = true)
165
- html = "<span id='#{content_id}_open' "
166
- html << "style='display:none'" unless open
167
- html << ">"
168
- html << link_to_function("#{image_tag("/tr8n/images/arrow_down.gif", :style=>'text-align:center; vertical-align:middle')} #{label}".html_safe, "Tr8n.Effects.hide('#{content_id}_open'); Tr8n.Effects.show('#{content_id}_closed'); Tr8n.Effects.blindUp('#{content_id}');", :style=> "text-decoration:none")
169
- html << "</span>"
170
- html << "<span id='#{content_id}_closed' "
171
- html << "style='display:none'" if open
172
- html << ">"
173
- html << link_to_function("#{image_tag("/tr8n/images/arrow_right.gif", :style=>'text-align:center; vertical-align:middle')} #{label}".html_safe, "Tr8n.Effects.show('#{content_id}_open'); Tr8n.Effects.hide('#{content_id}_closed'); Tr8n.Effects.blindDown('#{content_id}');", :style=> "text-decoration:none")
174
- html << "</span>"
175
- html.html_safe
176
- end
177
-
178
- def tr8n_sitemap(sections, splitters, options = {})
179
- html = ""
180
- html << "<table style='width:100%'>"
181
- html << "<tr>"
182
- splitters.each do |splitter|
183
- html << "<td style='vertical-align:top; width:" << (100 / splitters.size).to_s << "%;'>"
184
- html << generate_sitemap(sections[splitter.first..splitter.last], options)
185
- html << "</td>"
186
- end
187
- html << "</tr>"
188
- html << "</table>"
189
- html.html_safe
190
- end
191
-
192
- def tr8n_breadcrumb_tag(source = nil, opts = {})
193
- source ||= "#{controller.class.name.underscore.gsub("_controller", "")}/#{controller.action_name}"
194
- section = Tr8n::SiteMap.section_for_source(source)
195
- return "" unless section
196
- opts[:separator] ||= " >> "
197
- opts[:min_elements] ||= 1
198
- opts[:skip_root] ||= opts[:skip_root].nil? ? false : opts[:skip_root]
199
-
200
- links = section.parents.collect{|node| link_to(node.title(params), node.link(params))}
201
- return "" if links.size <= opts[:min_elements]
202
-
203
- links.delete(links.first) if opts[:skip_root]
204
- links.unshift(link_to(opts[:root].first, opts[:root].last)) if opts[:root]
205
-
206
- html = "<div id='tr8n_breadcrumb' class='tr8n_breadcrumb'>"
207
- html << links.join(opts[:separator])
208
- html << '</div>'
209
- html.html_safe
210
- end
211
-
212
- def tr8n_user_tag(translator, options = {})
213
- return "Deleted Translator" unless translator
214
-
215
- if options[:linked]
216
- link_to(translator.name, translator.link).html_safe
217
- else
218
- translator.name
219
- end
220
- end
221
-
222
- def tr8n_user_mugshot_tag(translator, options = {})
223
- if translator and !translator.mugshot.blank?
224
- img_url = translator.mugshot
225
- else
226
- img_url = Tr8n::Config.silhouette_image
227
- end
228
-
229
- img_tag = "<img src='#{img_url}' style='width:48px'>".html_safe
230
-
231
- if translator and options[:linked]
232
- link_to(img_tag, translator.link).html_safe
233
- else
234
- img_tag.html_safe
235
- end
236
- end
237
-
238
- def tr8n_will_paginate(collection = nil, options = {})
239
- will_paginate(collection, options.merge(:previous_label => tr("&laquo; Previous", "Previous entries in a list", {}, options),
240
- :next_label => tr("Next &raquo;", "Next entries in a list", {}, options))).html_safe
241
- end
242
-
243
- def tr8n_page_entries_info(collection, options = {})
244
- entry_name = options[:entry_name] || (collection.empty? ? 'entry' : collection.first.class.name.underscore.sub('_', ' '))
245
-
246
- if collection.total_pages < 2
247
- case collection.size
248
- when 0
249
- tr("None found", "Paginator no entries message", {}, options)
250
- when 1
251
- tr("Displaying [bold: 1] #{entry_name}", "Paginator one page message", {}, options)
252
- else
253
- tr("Displaying [bold: all {count}] #{entry_name.pluralize}", "Paginator all entries message", {:count => collection.size}, options)
254
- end
255
- else
256
- tr("Displaying #{entry_name.pluralize} [bold: {start_num} - {end_num}] of [bold: {total_count}] in total",
257
- "Paginator custom message", {
258
- :start_num => collection.offset + 1,
259
- :end_num => collection.offset + collection.length,
260
- :total_count => collection.total_entries
261
- }, options
262
- )
263
- end
264
- end
265
-
266
- def tr8n_select_month(date, options = {}, html_options = {})
267
- month_names = options[:use_short_month] ? Tr8n::Config.default_abbr_month_names : Tr8n::Config.default_month_names
268
- select_month(date, options.merge(
269
- :use_month_names => month_names.collect{|month_name| Tr8n::Language.translate(month_name, options[:description] || "Month name")}
270
- ), html_options)
271
- end
272
-
273
- def tr8n_with_options_tag(opts, &block)
274
- Thread.current[:tr8n_block_options] = opts
275
- if block_given?
276
- ret = capture(&block)
277
- end
278
- Thread.current[:tr8n_block_options] = {}
279
- ret
280
- end
281
-
282
- def tr8n_button_tag(label, function, opts = {})
283
- link_to_function("<span>#{label}</span>".html_safe, function, :class => "tr8n_grey_button tr8n_pcb")
284
- end
285
-
286
- private
287
-
288
- def generate_sitemap(sections, options = {})
289
- html = "<ul class='section_list'>"
290
- sections.each do |section|
291
- html << "<li class='section_list_item'>"
292
- html << "<a href='/tr8n/phrases/index?section_key=#{section.key}'>" << tr(section.label, section.description) << "</a>"
293
- html << "<a href='" << section.data[:link] << "' target='_new'><img src='/tr8n/images/bullet_go.png' style='border:0px; vertical-align:middle'></a>" if section.data[:link]
294
-
295
- if section.children.size > 0
296
- html << generate_sitemap(section.children, options)
297
- end
298
- html << "</li>"
299
- end
300
- html << "</ul>"
301
- html.html_safe
302
- end
303
-
304
- end