trimmer 0.0.3
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 +4 -0
- data/Gemfile +4 -0
- data/History.md +12 -0
- data/README.md +6 -0
- data/Rakefile +2 -0
- data/lib/trimmer/controller.rb +123 -0
- data/lib/trimmer/core.rb +23 -0
- data/lib/trimmer/i18n.rb +99 -0
- data/lib/trimmer/version.rb +3 -0
- data/lib/trimmer.rb +5 -0
- data/test/spec_trimmer_controller.rb +160 -0
- data/test/test_data/locales/ca.yml +3 -0
- data/test/test_data/locales/en.yml +3 -0
- data/test/test_data/locales/es.yml +3 -0
- data/test/test_data/templates/foo/bar.haml +1 -0
- data/test/test_data/templates_missing_t/baz/bif.haml +2 -0
- data/test/test_helper.rb +54 -0
- data/trimmer.gemspec +26 -0
- metadata +186 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/History.md
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'rack/request'
|
3
|
+
require 'json'
|
4
|
+
require 'tilt'
|
5
|
+
require 'i18n'
|
6
|
+
|
7
|
+
module Trimmer
|
8
|
+
|
9
|
+
class Controller
|
10
|
+
attr_accessor :templates_path, :allowed_keys, :renderer_scope
|
11
|
+
|
12
|
+
def initialize(app, opts={})
|
13
|
+
@app = app
|
14
|
+
|
15
|
+
@templates_path = opts[:templates_path] || File.expand_path(File.dirname(__FILE__))
|
16
|
+
@allowed_keys = opts[:allowed_keys] || "*"
|
17
|
+
@renderer_scope = opts[:renderer_scope] || Object.new
|
18
|
+
end
|
19
|
+
|
20
|
+
# Handle trimmer routes
|
21
|
+
# else call the next middleware with the environment.
|
22
|
+
def call(env)
|
23
|
+
request = Rack::Request.new(env)
|
24
|
+
response = nil
|
25
|
+
case request.path
|
26
|
+
when /\/trimmer(\/([^\/]+))*\/translations\.([js]+)$/
|
27
|
+
validate_locale($2) if $2 || ($2 && $2.empty?)
|
28
|
+
response = translations($2, $3)
|
29
|
+
when /\/trimmer\/([^\/]+)\/templates\.([js]+)$/
|
30
|
+
validate_locale($1)
|
31
|
+
response = templates($1, $2)
|
32
|
+
when /\/trimmer\/([^\.|\/]+)\.([js]+)$/
|
33
|
+
validate_locale($1)
|
34
|
+
response = resources($1, $2)
|
35
|
+
else
|
36
|
+
response = @app.call(env)
|
37
|
+
end
|
38
|
+
|
39
|
+
response
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def templates(locale, ext)
|
45
|
+
[200, {'Content-Type' => 'text/javascript'}, templates_to_js(locale)]
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def translations(locale, ext)
|
50
|
+
[200, {'Content-Type' => 'text/javascript'}, translations_to_js(:locale => locale, :only => allowed_keys)]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Exports templates and translations in a single request
|
54
|
+
def resources(locale, ext)
|
55
|
+
opts = {:only => allowed_keys}
|
56
|
+
opts[:locale] = locale if locale && !locale.empty?
|
57
|
+
|
58
|
+
response = translations_to_js(opts)
|
59
|
+
response << "\n"
|
60
|
+
response << templates_to_js(locale)
|
61
|
+
[200, {'Content-Type' => 'text/javascript'}, [response]]
|
62
|
+
end
|
63
|
+
|
64
|
+
#Render a template (using Tilt)
|
65
|
+
def render_to_string(path, opts={})
|
66
|
+
if ENV['RACK_ENV'] == 'production'
|
67
|
+
template = Thread.current[:"#{path}"] || Thread.current[:"#{path}"] = Tilt.new(path, opts)
|
68
|
+
else
|
69
|
+
template = Tilt.new(path, opts)
|
70
|
+
end
|
71
|
+
|
72
|
+
::I18n.with_exception_handler(:raise_all_exceptions) do
|
73
|
+
string = template.render(renderer_scope)
|
74
|
+
string.respond_to?(:force_encoding) ? string.force_encoding("utf-8") : string
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#Validates locale is one recognised by I18n::Locale::Tag implementation
|
79
|
+
def validate_locale(locale)
|
80
|
+
raise "Invalid locale" unless ::I18n::Locale::Tag.tag(locale)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Gets all templates and renders them as JSON, to be used as Mustache templates
|
84
|
+
def templates_to_js(locale)
|
85
|
+
::I18n.with_locale(locale) do
|
86
|
+
templates = JSON.dump(get_templates_from(templates_path))
|
87
|
+
"Templates = (#{templates});"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Traverses recursively base_path and fetches templates
|
92
|
+
def get_templates_from(base_path)
|
93
|
+
templates = {}
|
94
|
+
Dir.glob("#{base_path}/**").each do |entry|
|
95
|
+
if File.directory? entry
|
96
|
+
templates[File.basename(entry)] = get_templates_from entry
|
97
|
+
elsif File.file? entry
|
98
|
+
name = File.basename(entry).split('.').first
|
99
|
+
if !name.empty?
|
100
|
+
templates[name] = render_to_string(entry, :ugly => true)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
templates
|
105
|
+
end
|
106
|
+
|
107
|
+
# Dumps all the translations. Options you can pass:
|
108
|
+
# :locale. If specified, will dump only translations for the given locale.
|
109
|
+
# :only. If specified, will dump only keys that match the pattern. "*.date"
|
110
|
+
def translations_to_js(options = {})
|
111
|
+
"if(typeof(I18n) == 'undefined') { I18n = {}; };\n" +
|
112
|
+
"I18n.translations = (#{locale_with_fallback(options).to_json});"
|
113
|
+
end
|
114
|
+
|
115
|
+
def locale_with_fallback options
|
116
|
+
original_translation = ::I18n.to_hash(options) || {}
|
117
|
+
fallback_translation = ::I18n.to_hash(options.merge(:locale => ::I18n.default_locale))
|
118
|
+
fallback_translation ||= {}
|
119
|
+
fallback_translation.deep_merge original_translation
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
data/lib/trimmer/core.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def reverse_merge(other_hash)
|
4
|
+
other_hash.merge(self)
|
5
|
+
end
|
6
|
+
|
7
|
+
def reverse_merge!(other_hash)
|
8
|
+
merge!( other_hash ){|k,o,n| o }
|
9
|
+
end
|
10
|
+
|
11
|
+
def deep_merge!(other_hash)
|
12
|
+
other_hash.each_pair do |k,v|
|
13
|
+
tv = self[k]
|
14
|
+
self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def deep_merge(other_hash)
|
20
|
+
dup.deep_merge!(other_hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/lib/trimmer/i18n.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
module Trimmer
|
4
|
+
module I18n
|
5
|
+
|
6
|
+
def raise_all_exceptions(*args)
|
7
|
+
raise args.first
|
8
|
+
end
|
9
|
+
|
10
|
+
def with_exception_handler(tmp_exception_handler = nil)
|
11
|
+
if tmp_exception_handler
|
12
|
+
current_exception_handler = self.exception_handler
|
13
|
+
self.exception_handler = tmp_exception_handler
|
14
|
+
end
|
15
|
+
yield
|
16
|
+
ensure
|
17
|
+
self.exception_handler = current_exception_handler if tmp_exception_handler
|
18
|
+
end
|
19
|
+
|
20
|
+
def without_fallbacks
|
21
|
+
current_translate_method = ::I18n.backend.method(:translate)
|
22
|
+
::I18n.backend.class.send(:define_method, 'translate', translate_without_fallbacks)
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
::I18n.backend.class.send(:remove_method, 'translate')
|
26
|
+
end
|
27
|
+
|
28
|
+
# deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
29
|
+
MERGER = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2 }
|
30
|
+
|
31
|
+
# Exports translations from the I18n backend to a Hash
|
32
|
+
# :locale. If specified, will dump only translations for the given locale.
|
33
|
+
# :only. If specified, will dump only keys that match the pattern. "*.date"
|
34
|
+
def to_hash options = {}
|
35
|
+
options.reverse_merge!(:only => "*")
|
36
|
+
|
37
|
+
if options[:only] == "*"
|
38
|
+
data = translations
|
39
|
+
else
|
40
|
+
data = scoped_translations options[:only]
|
41
|
+
end
|
42
|
+
|
43
|
+
if options[:locale]
|
44
|
+
data[options[:locale].to_sym]
|
45
|
+
else
|
46
|
+
data
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def scoped_translations(scopes) # :nodoc:
|
51
|
+
result = {}
|
52
|
+
|
53
|
+
[scopes].flatten.each do |scope|
|
54
|
+
deep_merge! result, filter(translations, scope)
|
55
|
+
end
|
56
|
+
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
# Filter translations according to the specified scope.
|
61
|
+
def filter(translations, scopes)
|
62
|
+
scopes = scopes.split(".") if scopes.is_a?(String)
|
63
|
+
scopes = scopes.clone
|
64
|
+
scope = scopes.shift
|
65
|
+
|
66
|
+
if scope == "*"
|
67
|
+
results = {}
|
68
|
+
translations.each do |scope, translations|
|
69
|
+
tmp = scopes.empty? ? translations : filter(translations, scopes)
|
70
|
+
results[scope.to_sym] = tmp unless tmp.nil?
|
71
|
+
end
|
72
|
+
return results
|
73
|
+
elsif translations.has_key?(scope.to_sym)
|
74
|
+
return {scope.to_sym => scopes.empty? ? translations[scope.to_sym] : filter(translations[scope.to_sym], scopes)}
|
75
|
+
end
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Initialize and return translations
|
80
|
+
def translations
|
81
|
+
self.backend.instance_eval do
|
82
|
+
init_translations unless initialized?
|
83
|
+
translations
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def deep_merge!(target, hash) # :nodoc:
|
88
|
+
target.merge!(hash, &MERGER)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def translate_without_fallbacks
|
94
|
+
method_name = RUBY_VERSION =~ /1\.9/ ? :translate : 'translate'
|
95
|
+
ancestor_module_with_translate = (::I18n.backend.class.included_modules - [::I18n::Backend::Fallbacks]).select {|m| m.instance_methods(false).include?(method_name) rescue false}
|
96
|
+
ancestor_module_with_translate.first.instance_method(method_name) rescue nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/trimmer.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
context Trimmer::Controller do
|
4
|
+
F = ::File
|
5
|
+
|
6
|
+
def request(opts={}, &block)
|
7
|
+
Rack::MockRequest.new(Trimmer::Controller.new(@def_app,
|
8
|
+
:templates_path => (opts[:templates_dir] || templates_dir),
|
9
|
+
:allowed_keys => (opts[:allowed_keys] || nil))).send(opts[:meth]||:get, opts[:path]||@def_path, opts[:headers]||{})
|
10
|
+
end
|
11
|
+
|
12
|
+
setup do
|
13
|
+
# @def_disk_cache = F.join(F.dirname(__FILE__), 'response_cache_test_disk_cache')
|
14
|
+
|
15
|
+
@def_resources_en = <<-VALUE.strip
|
16
|
+
if(typeof(I18n) == 'undefined') { I18n = {}; };
|
17
|
+
I18n.translations = ({\"foo\":{\"trimmer\":\"trimmer\"}});
|
18
|
+
Templates = ({"foo":{"bar":"<span>trimmer</span>\\n"}});
|
19
|
+
VALUE
|
20
|
+
|
21
|
+
@def_translations_en = <<-VALUE.strip
|
22
|
+
if(typeof(I18n) == 'undefined') { I18n = {}; };
|
23
|
+
I18n.translations = ({\"foo\":{\"trimmer\":\"trimmer\"}});
|
24
|
+
VALUE
|
25
|
+
|
26
|
+
@def_templates_en = <<-VALUE.strip
|
27
|
+
Templates = ({"foo":{"bar":"<span>trimmer</span>\\n"}});
|
28
|
+
VALUE
|
29
|
+
|
30
|
+
@def_resources_es = <<-VALUE.strip
|
31
|
+
if(typeof(I18n) == 'undefined') { I18n = {}; };
|
32
|
+
I18n.translations = ({\"foo\":{\"trimmer\":\"recortadora\"}});
|
33
|
+
Templates = ({"foo":{"bar":"<span>recortadora</span>\\n"}});
|
34
|
+
VALUE
|
35
|
+
|
36
|
+
@def_translations_es = <<-VALUE.strip
|
37
|
+
if(typeof(I18n) == 'undefined') { I18n = {}; };
|
38
|
+
I18n.translations = ({\"foo\":{\"trimmer\":\"recortadora\"}});
|
39
|
+
VALUE
|
40
|
+
|
41
|
+
@def_templates_es = <<-VALUE.strip
|
42
|
+
Templates = ({"foo":{"bar":"<span>recortadora</span>\\n"}});
|
43
|
+
VALUE
|
44
|
+
|
45
|
+
@def_resources_ca = <<-VALUE.strip
|
46
|
+
if(typeof(I18n) == 'undefined') { I18n = {}; };
|
47
|
+
I18n.translations = ({\"foo\":{\"trimmer\":\"trimmer\"}});
|
48
|
+
Templates = ({"foo":{"bar":"<span>recortadora</span>\\n"}});
|
49
|
+
VALUE
|
50
|
+
|
51
|
+
|
52
|
+
@def_path = '/trimmer/en.js'
|
53
|
+
@def_value = 'hello world'
|
54
|
+
@def_app = lambda { |env| [200, {'Content-Type' => env['CT'] || 'text/html'}, @def_value]}
|
55
|
+
end
|
56
|
+
|
57
|
+
teardown do
|
58
|
+
# FileUtils.rm_rf(@def_disk_cache)
|
59
|
+
end
|
60
|
+
|
61
|
+
specify "should return a response for /trimmer/:locale.js" do
|
62
|
+
request(:path=>'/trimmer/en.js').body.should.equal(@def_resources_en)
|
63
|
+
request(:path=>'/trimmer/es.js').body.should.equal(@def_resources_es)
|
64
|
+
end
|
65
|
+
|
66
|
+
specify "should return a response for /trimmer/:locale/templates.js" do
|
67
|
+
request(:path=>'/trimmer/en/templates.js').body.should.equal(@def_templates_en)
|
68
|
+
request(:path=>'/trimmer/es/templates.js').body.should.equal(@def_templates_es)
|
69
|
+
end
|
70
|
+
|
71
|
+
specify "should return a response for /trimmer/:locale/translations.js" do
|
72
|
+
request(:path=>'/trimmer/en/translations.js').body.should.equal(@def_translations_en)
|
73
|
+
request(:path=>'/trimmer/es/translations.js').body.should.equal(@def_translations_es)
|
74
|
+
end
|
75
|
+
|
76
|
+
specify "should forward request to next middleware if it doesn't match path" do
|
77
|
+
request(:path=>'/trimmer/en/translations.json').body.should.equal(@def_value)
|
78
|
+
end
|
79
|
+
|
80
|
+
specify "should return a response for /trimmer/:locale/templates.js if fallback found" do
|
81
|
+
lambda {
|
82
|
+
request(:path=>'/trimmer/ca/templates.js').body.should.equal(@def_templates_es)
|
83
|
+
}.should.not.raise(::I18n::MissingTranslationData)
|
84
|
+
end
|
85
|
+
|
86
|
+
specify "should return a response for /trimmer/:locale.js if fallback found" do
|
87
|
+
lambda {
|
88
|
+
request(:path=>'/trimmer/ca.js').body.should.equal(@def_resources_ca)
|
89
|
+
}.should.not.raise(::I18n::MissingTranslationData)
|
90
|
+
end
|
91
|
+
|
92
|
+
specify "should reraise i18n exceptions if no fallback found when rendering all resources" do
|
93
|
+
lambda {
|
94
|
+
request(:path=>'/trimmer/ca.js', :templates_dir => templates_missing_t_dir)
|
95
|
+
}.should.raise(::I18n::MissingTranslationData)
|
96
|
+
end
|
97
|
+
|
98
|
+
specify "should reraise i18n exceptions if no fallback found when rendering templates" do
|
99
|
+
lambda {
|
100
|
+
request(:path=>'/trimmer/ca/templates.js', :templates_dir => templates_missing_t_dir)
|
101
|
+
}.should.raise(::I18n::MissingTranslationData)
|
102
|
+
end
|
103
|
+
|
104
|
+
specify "should reraise i18n exceptions if no fallbacks when rendering all resources" do
|
105
|
+
lambda {
|
106
|
+
::I18n.without_fallbacks do
|
107
|
+
request(:path=>'/trimmer/pl.js')
|
108
|
+
end
|
109
|
+
}.should.raise(::I18n::MissingTranslationData)
|
110
|
+
end
|
111
|
+
|
112
|
+
specify "should reraise i18n exceptions if no fallback when rendering templates" do
|
113
|
+
lambda {
|
114
|
+
::I18n.without_fallbacks do
|
115
|
+
request(:path=>'/trimmer/pl/templates.js')
|
116
|
+
end
|
117
|
+
}.should.raise(::I18n::MissingTranslationData)
|
118
|
+
end
|
119
|
+
|
120
|
+
specify "should reraise i18n exceptions if no fallbacks and locale is invalid when rendering all resources" do
|
121
|
+
lambda {
|
122
|
+
::I18n.without_fallbacks do
|
123
|
+
request(:path=>'/trimmer/foobar.js')
|
124
|
+
end
|
125
|
+
}.should.raise(::I18n::MissingTranslationData)
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "should reraise i18n exceptions if no fallbacks and locale is invalid when rendering templates" do
|
129
|
+
lambda {
|
130
|
+
::I18n.without_fallbacks do
|
131
|
+
request(:path=>'/trimmer/foobar/templates.js')
|
132
|
+
end
|
133
|
+
}.should.raise(::I18n::MissingTranslationData)
|
134
|
+
end
|
135
|
+
|
136
|
+
specify "should filter translations if allowed_keys option set on Trimmer::Controller instance" do
|
137
|
+
request(:path=>'/trimmer/en/translations.js', :allowed_keys => "*.baz").body.should.equal("if(typeof(I18n) == 'undefined') { I18n = {}; };\nI18n.translations = ({});")
|
138
|
+
request(:path=>'/trimmer/en/translations.js', :allowed_keys => "*.foo").body.should.equal(@def_translations_en)
|
139
|
+
end
|
140
|
+
|
141
|
+
specify "should render all translations if no locale" do
|
142
|
+
request(:path=>'/trimmer/translations.js').body.should.equal(<<-RESP.strip)
|
143
|
+
if(typeof(I18n) == 'undefined') { I18n = {}; };\nI18n.translations = ({\"foo\":{\"trimmer\":\"trimmer\"},\"en\":{\"foo\":{\"trimmer\":\"trimmer\"}},\"es\":{\"foo\":{\"trimmer\":\"recortadora\"}}});
|
144
|
+
RESP
|
145
|
+
end
|
146
|
+
|
147
|
+
specify "should forward request to next middleware if no local when rendering templates" do
|
148
|
+
::I18n.without_fallbacks do
|
149
|
+
request(:path=>'/trimmer//templates.js').body.should.equal(@def_value)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
specify "should forward request to next middleware if no local when rendering resources" do
|
154
|
+
::I18n.without_fallbacks do
|
155
|
+
request(:path=>'/trimmer.js').body.should.equal(@def_value)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
%span=I18n.t('foo.trimmer')
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
require 'test/spec'
|
3
|
+
require 'rack/mock'
|
4
|
+
require File.dirname(__FILE__) + '/../lib/trimmer'
|
5
|
+
|
6
|
+
class Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
I18n.backend = I18n::Backend::Simple.new
|
10
|
+
I18n.default_locale = :en
|
11
|
+
|
12
|
+
%w(en es).each do |locale|
|
13
|
+
I18n.load_path << [locales_dir + "/#{locale}.yml"]
|
14
|
+
end
|
15
|
+
|
16
|
+
I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
|
17
|
+
# => [:ca, :es, :en]
|
18
|
+
I18n.fallbacks.map(:ca => :es)
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
I18n.locale = nil
|
23
|
+
I18n.default_locale = :en
|
24
|
+
I18n.load_path = []
|
25
|
+
I18n.available_locales = nil
|
26
|
+
I18n.backend = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def translations
|
30
|
+
I18n.backend.instance_variable_get(:@translations)
|
31
|
+
end
|
32
|
+
|
33
|
+
def store_translations(*args)
|
34
|
+
data = args.pop
|
35
|
+
locale = args.pop || :en
|
36
|
+
I18n.backend.store_translations(locale, data)
|
37
|
+
end
|
38
|
+
|
39
|
+
def locales_dir
|
40
|
+
File.dirname(__FILE__) + '/test_data/locales'
|
41
|
+
end
|
42
|
+
|
43
|
+
def templates_dir
|
44
|
+
File.dirname(__FILE__) + '/test_data/templates'
|
45
|
+
end
|
46
|
+
|
47
|
+
def templates_missing_t_dir
|
48
|
+
File.dirname(__FILE__) + '/test_data/templates_missing_t'
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
data/trimmer.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "trimmer/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "trimmer"
|
7
|
+
s.version = Trimmer::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Pablo Villalba", "Saimon Moore"]
|
10
|
+
s.email = ["pablo@teambox.com", "saimon@teambox.com"]
|
11
|
+
s.homepage = "https://github.com/teambox/trimmer"
|
12
|
+
s.summary = %q{Rack endpoint to make templates and i18n translations available in javascript}
|
13
|
+
|
14
|
+
s.rubyforge_project = "trimmer"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.add_dependency 'rack', '~> 1.1'
|
21
|
+
s.add_dependency 'i18n', '~> 0.6.0'
|
22
|
+
s.add_dependency 'tilt', '~> 1.3.3'
|
23
|
+
s.add_development_dependency 'test-spec', '~> 0.9.0'
|
24
|
+
s.add_development_dependency 'haml', '~> 3.0.25'
|
25
|
+
s.add_development_dependency 'json', '~> 1.1'
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: trimmer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Pablo Villalba
|
14
|
+
- Saimon Moore
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-10-13 00:00:00 +02:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: rack
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 13
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 1
|
34
|
+
version: "1.1"
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: i18n
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 6
|
49
|
+
- 0
|
50
|
+
version: 0.6.0
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: tilt
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 29
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 3
|
65
|
+
- 3
|
66
|
+
version: 1.3.3
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: test-spec
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 59
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
- 9
|
81
|
+
- 0
|
82
|
+
version: 0.9.0
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: haml
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 53
|
94
|
+
segments:
|
95
|
+
- 3
|
96
|
+
- 0
|
97
|
+
- 25
|
98
|
+
version: 3.0.25
|
99
|
+
type: :development
|
100
|
+
version_requirements: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: json
|
103
|
+
prerelease: false
|
104
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 13
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 1
|
113
|
+
version: "1.1"
|
114
|
+
type: :development
|
115
|
+
version_requirements: *id006
|
116
|
+
description:
|
117
|
+
email:
|
118
|
+
- pablo@teambox.com
|
119
|
+
- saimon@teambox.com
|
120
|
+
executables: []
|
121
|
+
|
122
|
+
extensions: []
|
123
|
+
|
124
|
+
extra_rdoc_files: []
|
125
|
+
|
126
|
+
files:
|
127
|
+
- .gitignore
|
128
|
+
- Gemfile
|
129
|
+
- History.md
|
130
|
+
- README.md
|
131
|
+
- Rakefile
|
132
|
+
- lib/trimmer.rb
|
133
|
+
- lib/trimmer/controller.rb
|
134
|
+
- lib/trimmer/core.rb
|
135
|
+
- lib/trimmer/i18n.rb
|
136
|
+
- lib/trimmer/version.rb
|
137
|
+
- test/spec_trimmer_controller.rb
|
138
|
+
- test/test_data/locales/ca.yml
|
139
|
+
- test/test_data/locales/en.yml
|
140
|
+
- test/test_data/locales/es.yml
|
141
|
+
- test/test_data/templates/foo/bar.haml
|
142
|
+
- test/test_data/templates_missing_t/baz/bif.haml
|
143
|
+
- test/test_helper.rb
|
144
|
+
- trimmer.gemspec
|
145
|
+
has_rdoc: true
|
146
|
+
homepage: https://github.com/teambox/trimmer
|
147
|
+
licenses: []
|
148
|
+
|
149
|
+
post_install_message:
|
150
|
+
rdoc_options: []
|
151
|
+
|
152
|
+
require_paths:
|
153
|
+
- lib
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
hash: 3
|
160
|
+
segments:
|
161
|
+
- 0
|
162
|
+
version: "0"
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
hash: 3
|
169
|
+
segments:
|
170
|
+
- 0
|
171
|
+
version: "0"
|
172
|
+
requirements: []
|
173
|
+
|
174
|
+
rubyforge_project: trimmer
|
175
|
+
rubygems_version: 1.3.7
|
176
|
+
signing_key:
|
177
|
+
specification_version: 3
|
178
|
+
summary: Rack endpoint to make templates and i18n translations available in javascript
|
179
|
+
test_files:
|
180
|
+
- test/spec_trimmer_controller.rb
|
181
|
+
- test/test_data/locales/ca.yml
|
182
|
+
- test/test_data/locales/en.yml
|
183
|
+
- test/test_data/locales/es.yml
|
184
|
+
- test/test_data/templates/foo/bar.haml
|
185
|
+
- test/test_data/templates_missing_t/baz/bif.haml
|
186
|
+
- test/test_helper.rb
|