sinatra-ghetto_i18n 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/LICENSE +22 -0
- data/README.rdoc +17 -0
- data/lib/sinatra/ghetto_i18n.rb +174 -0
- data/sinatra-ghetto_i18n.gemspec +26 -0
- metadata +70 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2011 Nicolas Sanguinetti, http://nicolassanguinetti.info
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= Ghetto I18N
|
2
|
+
|
3
|
+
This is the simplest, hackiest way to add translations to your Sinatra
|
4
|
+
application.
|
5
|
+
|
6
|
+
== How do I use it?
|
7
|
+
|
8
|
+
The code is (or should be) fairly well documented. Read it :)
|
9
|
+
|
10
|
+
If you want a live demo, we use it at http://rubyconfuruguay.org
|
11
|
+
|
12
|
+
And that's open source, so you can see its code[http://github.com/foca/rubyconfuruguay-website].
|
13
|
+
|
14
|
+
== Credits
|
15
|
+
|
16
|
+
Author:: Nicolas Sanguinetti (foca[http://github.com/foca])
|
17
|
+
License:: MIT (Check LICENSE for details)
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
# Extension that provides simplified I18N for your Sinatra applications.
|
5
|
+
#
|
6
|
+
# When you register this extension you gain access to 3 application settings,
|
7
|
+
# a couple of useful methods, and new options when definining routes and
|
8
|
+
# rendering views.
|
9
|
+
#
|
10
|
+
# The idea behind this is that all the routes in your application are
|
11
|
+
# namespaced by the language you want to use.
|
12
|
+
#
|
13
|
+
# So for example, if you want to provide the "/events" URL in english,
|
14
|
+
# spanish, and portuguese, using this extension you would have:
|
15
|
+
#
|
16
|
+
# GET /en/events
|
17
|
+
# GET /es/events
|
18
|
+
# GET /pt/events
|
19
|
+
#
|
20
|
+
# Then, when you render a view (by passing a symbol to erb etc), the view is
|
21
|
+
# automatically looked up in a way that will include the language.
|
22
|
+
#
|
23
|
+
# This assumes you want a separate view file for each language. This means
|
24
|
+
# more work maintaining the site, yes, but for very simple websites this is
|
25
|
+
# often easier than keeping a translations file.
|
26
|
+
#
|
27
|
+
# This also helps when you have two widely different languages in which the
|
28
|
+
# design is affected by the translation (for example, an LTR and a RTL
|
29
|
+
# language.)
|
30
|
+
#
|
31
|
+
# = Options =
|
32
|
+
#
|
33
|
+
# When using this extension, you have access to the following settings:
|
34
|
+
#
|
35
|
+
# == +:languages+ ==
|
36
|
+
#
|
37
|
+
# You *must* set this to an enumerable that has the language codes your
|
38
|
+
# application supports. Any object that responds to #include? and #each works.
|
39
|
+
#
|
40
|
+
# For example:
|
41
|
+
#
|
42
|
+
# set :languages, ["en", "es", "pt"]
|
43
|
+
# set :languages, "en" => "English", "es" => "Español"
|
44
|
+
#
|
45
|
+
# (The rationale for this is that you might want to use a hash for setting
|
46
|
+
# names in order to build links to switch languages, but you can just pass an
|
47
|
+
# array if you don't need that)
|
48
|
+
#
|
49
|
+
# == +:default_language+ ==
|
50
|
+
#
|
51
|
+
# A string with the 2-letter language code of the default language for your
|
52
|
+
# application. Defaults to English.
|
53
|
+
#
|
54
|
+
# == +:i18n_view_format: ==
|
55
|
+
#
|
56
|
+
# The path to the internationalized view files. This should be a block that
|
57
|
+
# takes two arguments (the original view file, and the language) and must
|
58
|
+
# return a symbol.
|
59
|
+
#
|
60
|
+
# For example:
|
61
|
+
#
|
62
|
+
# set :i18n_view_format do |view, lang|
|
63
|
+
# :"#{lang}_#{view}"
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# That means when you render the ":some_view" view, you are actually rendering
|
67
|
+
# the ":en_some_view" if the user is browsing the English site, or the
|
68
|
+
# ":fr_some_view" file if the user is browsing the French site.
|
69
|
+
#
|
70
|
+
# The default is +lang/view+, so your typical sinatra application will look
|
71
|
+
# like this (in case the languages you support are English and Spanish ("en"
|
72
|
+
# and "es"):
|
73
|
+
#
|
74
|
+
# .
|
75
|
+
# |- website.rb
|
76
|
+
# \- views
|
77
|
+
# |- en
|
78
|
+
# | |- view_a.erb
|
79
|
+
# | \- view_b.erb
|
80
|
+
# \- es
|
81
|
+
# |- view_a.erb
|
82
|
+
# \- view_b.erb
|
83
|
+
#
|
84
|
+
module GhettoI18n
|
85
|
+
def self.registered(app) # :nodoc:
|
86
|
+
app.helpers Sinatra::GhettoI18n::Helpers
|
87
|
+
app.get("/", :skip_i18n => true) { redirect "/#{language}" }
|
88
|
+
|
89
|
+
unless app.respond_to? :i18n_view_format
|
90
|
+
app.set(:i18n_view_format) { |view, lang| :"#{lang}/#{view}" }
|
91
|
+
end
|
92
|
+
|
93
|
+
unless app.respond_to? :languages
|
94
|
+
app.set(:languages, {})
|
95
|
+
end
|
96
|
+
|
97
|
+
unless app.respond_to? :default_language
|
98
|
+
app.set(:default_language, "en")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Define an internationalized GET route for the root. For example:
|
103
|
+
#
|
104
|
+
# home do
|
105
|
+
# erb :home
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# is equivalent to defining:
|
109
|
+
#
|
110
|
+
# get "/:lang", :skip_i18n => true do
|
111
|
+
# erb :home
|
112
|
+
# end
|
113
|
+
def home(&block)
|
114
|
+
check_language!
|
115
|
+
route("GET", "/:lang", { :skip_i18n => true }, &block)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Define a condition that makes sure the language provided in the parameters
|
119
|
+
# matches the languages defined as an option.
|
120
|
+
def check_language!
|
121
|
+
condition { self.class.languages.include?(params[:lang]) }
|
122
|
+
end
|
123
|
+
|
124
|
+
def route(method, path, options={}, &block) # :nodoc:
|
125
|
+
return super if options.delete(:skip_i18n)
|
126
|
+
|
127
|
+
path.gsub! /^\//, ''
|
128
|
+
|
129
|
+
if %W(GET HEAD).include? method
|
130
|
+
super method, path, options do
|
131
|
+
redirect "/#{language}/#{path}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
super method, "/:lang/#{path}", options, &block
|
136
|
+
end
|
137
|
+
|
138
|
+
module Helpers
|
139
|
+
# The language for the current request. If the user is browsing to a
|
140
|
+
# language specific URL (ie, :lang is included in the params), then use
|
141
|
+
# that.
|
142
|
+
#
|
143
|
+
# If not, try to figure it out from the Accept-Language HTTP header.
|
144
|
+
#
|
145
|
+
# If that fails as well, resort to the +default_language+ setting.
|
146
|
+
def language
|
147
|
+
@_lang ||= params[:lang] || language_from_http ||
|
148
|
+
self.class.default_language
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def language_from_http # :nodoc:
|
154
|
+
env["HTTP_ACCEPT_LANGUAGE"].to_s.split(",").each do |lang|
|
155
|
+
self.class.languages.each do |code, *|
|
156
|
+
return code if lang =~ /^#{code}/
|
157
|
+
end
|
158
|
+
end
|
159
|
+
nil
|
160
|
+
end
|
161
|
+
|
162
|
+
def render(engine, data, options={}, locals={}, &block) # :nodoc:
|
163
|
+
skip_i18n = options.delete(:skip_i18n)
|
164
|
+
|
165
|
+
if Symbol === data && !skip_i18n
|
166
|
+
view = self.class.i18n_view_format(data, language)
|
167
|
+
super(engine, view, options, locals, &block)
|
168
|
+
else
|
169
|
+
super
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "sinatra-ghetto_i18n"
|
3
|
+
s.version = "0.1.0"
|
4
|
+
s.date = "2011-07-04"
|
5
|
+
|
6
|
+
s.description = "Oversimplified I18N for your Sinatra application."
|
7
|
+
s.summary = "I18n for simple apps."
|
8
|
+
s.homepage = "http://github.com/foca/sinatra-ghetto_i18n"
|
9
|
+
|
10
|
+
s.authors = ["Nicolas Sanguinetti"]
|
11
|
+
s.email = "contacto@nicolassanguinetti.info"
|
12
|
+
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.rubygems_version = "1.3.5"
|
16
|
+
|
17
|
+
s.add_dependency "sinatra"
|
18
|
+
|
19
|
+
s.files = %w[
|
20
|
+
.gitignore
|
21
|
+
LICENSE
|
22
|
+
README.rdoc
|
23
|
+
sinatra-ghetto_i18n.gemspec
|
24
|
+
lib/sinatra/ghetto_i18n.rb
|
25
|
+
]
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-ghetto_i18n
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nicolas Sanguinetti
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-04 00:00:00 -03:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: sinatra
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
description: Oversimplified I18N for your Sinatra application.
|
28
|
+
email: contacto@nicolassanguinetti.info
|
29
|
+
executables: []
|
30
|
+
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- sinatra-ghetto_i18n.gemspec
|
40
|
+
- lib/sinatra/ghetto_i18n.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/foca/sinatra-ghetto_i18n
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.5.2
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: I18n for simple apps.
|
69
|
+
test_files: []
|
70
|
+
|