tilt 1.0.1 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -34,6 +34,9 @@ Support for these template engines is included with the package:
34
34
  RedCloth .textile redcloth
35
35
  RDoc .rdoc rdoc
36
36
  Radius .radius radius
37
+ Markaby .mab markaby
38
+ Nokogiri .nokogiri nokogiri
39
+ CoffeeScript .coffee coffee-script (+node coffee)
37
40
 
38
41
  See [TEMPLATES.md][t] for detailed information on template engine
39
42
  options and supported features.
@@ -1,7 +1,7 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  module Tilt
4
- VERSION = '1.0.1'
4
+ VERSION = '1.1'
5
5
 
6
6
  @template_mappings = {}
7
7
 
@@ -59,7 +59,7 @@ module Tilt
59
59
  end
60
60
 
61
61
  # Base class for template implementations. Subclasses must implement
62
- # the #prepare method and one of the #evaluate or #evaluate_source
62
+ # the #prepare method and one of the #evaluate or #precompiled_template
63
63
  # methods.
64
64
  class Template
65
65
  # Template source; loaded from a file or given directly.
@@ -282,13 +282,18 @@ module Tilt
282
282
 
283
283
  def compile_template_method(method_name, locals)
284
284
  source, offset = precompiled(locals)
285
- offset += 1
286
- CompileSite.module_eval <<-RUBY, eval_file, line - offset
285
+ offset += 5
286
+ CompileSite.class_eval <<-RUBY, eval_file, line - offset
287
287
  def #{method_name}(locals)
288
- #{source}
288
+ Thread.current[:tilt_vars] = [self, locals]
289
+ class << self
290
+ this, locals = Thread.current[:tilt_vars]
291
+ this.instance_eval do
292
+ #{source}
293
+ end
294
+ end
289
295
  end
290
296
  RUBY
291
-
292
297
  ObjectSpace.define_finalizer self,
293
298
  Template.compiled_template_method_remover(CompileSite, method_name)
294
299
  end
@@ -306,6 +311,27 @@ module Tilt
306
311
  end
307
312
  end
308
313
  end
314
+
315
+ # Special case Ruby 1.9.1's broken yield.
316
+ #
317
+ # http://github.com/rtomayko/tilt/commit/20c01a5
318
+ # http://redmine.ruby-lang.org/issues/show/3601
319
+ #
320
+ # Remove when 1.9.2 dominates 1.9.1 installs in the wild.
321
+ if RUBY_VERSION =~ /^1.9.1/
322
+ undef compile_template_method
323
+ def compile_template_method(method_name, locals)
324
+ source, offset = precompiled(locals)
325
+ offset += 1
326
+ CompileSite.module_eval <<-RUBY, eval_file, line - offset
327
+ def #{method_name}(locals)
328
+ #{source}
329
+ end
330
+ RUBY
331
+ ObjectSpace.define_finalizer self,
332
+ Template.compiled_template_method_remover(CompileSite, method_name)
333
+ end
334
+ end
309
335
  end
310
336
 
311
337
  # Extremely simple template cache implementation. Calling applications
@@ -528,11 +554,19 @@ module Tilt
528
554
 
529
555
  private
530
556
  def sass_options
531
- options.merge(:filename => eval_file, :line => line)
557
+ options.merge(:filename => eval_file, :line => line, :syntax => :sass)
532
558
  end
533
559
  end
534
560
  register 'sass', SassTemplate
535
561
 
562
+ # Sass's new .scss type template implementation.
563
+ class ScssTemplate < SassTemplate
564
+ private
565
+ def sass_options
566
+ options.merge(:filename => eval_file, :line => line, :syntax => :scss)
567
+ end
568
+ end
569
+ register 'scss', ScssTemplate
536
570
 
537
571
  # Lessscss template implementation. See:
538
572
  # http://lesscss.org/
@@ -555,6 +589,65 @@ module Tilt
555
589
  register 'less', LessTemplate
556
590
 
557
591
 
592
+ # CoffeeScript template implementation. See:
593
+ # http://coffeescript.org/
594
+ #
595
+ # CoffeeScript templates do not support object scopes, locals, or yield.
596
+ class CoffeeScriptTemplate < Template
597
+ @@default_no_wrap = false
598
+
599
+ def self.default_no_wrap
600
+ @@default_no_wrap
601
+ end
602
+
603
+ def self.default_no_wrap=(value)
604
+ @@default_no_wrap = value
605
+ end
606
+
607
+ def initialize_engine
608
+ return if defined? ::CoffeeScript
609
+ require_template_library 'coffee_script'
610
+ end
611
+
612
+ def prepare
613
+ @no_wrap = options.key?(:no_wrap) ? options[:no_wrap] :
614
+ self.class.default_no_wrap
615
+ end
616
+
617
+ def evaluate(scope, locals, &block)
618
+ @output ||= CoffeeScript.compile(data, :no_wrap => @no_wrap)
619
+ end
620
+ end
621
+ register 'coffee', CoffeeScriptTemplate
622
+
623
+
624
+ # Nokogiri template implementation. See:
625
+ # http://nokogiri.org/
626
+ class NokogiriTemplate < Template
627
+ def initialize_engine
628
+ return if defined?(::Nokogiri)
629
+ require_template_library 'nokogiri'
630
+ end
631
+
632
+ def prepare; end
633
+
634
+ def evaluate(scope, locals, &block)
635
+ xml = ::Nokogiri::XML::Builder.new
636
+ if data.respond_to?(:to_str)
637
+ locals[:xml] = xml
638
+ super(scope, locals, &block)
639
+ elsif data.kind_of?(Proc)
640
+ data.call(xml)
641
+ end
642
+ xml.to_xml
643
+ end
644
+
645
+ def precompiled_template(locals)
646
+ data.to_str
647
+ end
648
+ end
649
+ register 'nokogiri', NokogiriTemplate
650
+
558
651
  # Builder template implementation. See:
559
652
  # http://builder.rubyforge.org/
560
653
  class BuilderTemplate < Template
@@ -729,4 +822,47 @@ module Tilt
729
822
  end
730
823
  end
731
824
  register 'radius', RadiusTemplate
825
+
826
+
827
+ # Markaby
828
+ # http://github.com/markaby/markaby
829
+ class MarkabyTemplate < Template
830
+ def self.builder_class
831
+ @builder_class ||= Class.new(Markaby::Builder) do
832
+ def __capture_markaby_tilt__(&block)
833
+ __run_markaby_tilt__ do
834
+ text capture(&block)
835
+ end
836
+ end
837
+ end
838
+ end
839
+
840
+ def initialize_engine
841
+ return if defined? ::Markaby
842
+ require_template_library 'markaby'
843
+ end
844
+
845
+ def prepare
846
+ end
847
+
848
+ def evaluate(scope, locals, &block)
849
+ builder = self.class.builder_class.new({}, scope)
850
+ builder.locals = locals
851
+
852
+ if block
853
+ builder.instance_eval <<-CODE, __FILE__, __LINE__
854
+ def __run_markaby_tilt__
855
+ #{data}
856
+ end
857
+ CODE
858
+
859
+ builder.__capture_markaby_tilt__(&block)
860
+ else
861
+ builder.instance_eval(data, __FILE__, __LINE__)
862
+ end
863
+
864
+ builder.to_s
865
+ end
866
+ end
867
+ register 'mab', MarkabyTemplate
732
868
  end
@@ -0,0 +1 @@
1
+ li foo
@@ -0,0 +1 @@
1
+ text "hello from markaby!"
@@ -0,0 +1 @@
1
+ text "_why?"
@@ -0,0 +1 @@
1
+ text "foo"
@@ -0,0 +1 @@
1
+ li foo
@@ -0,0 +1,2 @@
1
+ text("Hey ")
2
+ yield
@@ -14,10 +14,9 @@ class TiltCacheTest < Test::Unit::TestCase
14
14
 
15
15
  test "caching with multiple complex arguments to #fetch" do
16
16
  template = nil
17
- args = ['hello', {:foo => 'bar', :baz => 'bizzle'}]
18
- result = @cache.fetch(*args) { template = Tilt::StringTemplate.new {''} }
17
+ result = @cache.fetch('hello', {:foo => 'bar', :baz => 'bizzle'}) { template = Tilt::StringTemplate.new {''} }
19
18
  assert_same template, result
20
- result = @cache.fetch(*args) { fail 'should be cached' }
19
+ result = @cache.fetch('hello', {:foo => 'bar', :baz => 'bizzle'}) { fail 'should be cached' }
21
20
  assert_same template, result
22
21
  end
23
22
 
@@ -0,0 +1,25 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ begin
5
+ require 'coffee_script'
6
+
7
+ class CoffeeScriptTemplateTest < Test::Unit::TestCase
8
+ test "is registered for '.coffee' files" do
9
+ assert_equal Tilt::CoffeeScriptTemplate, Tilt['test.coffee']
10
+ end
11
+
12
+ test "compiles and evaluates the template on #render" do
13
+ template = Tilt::CoffeeScriptTemplate.new { |t| "puts 'Hello, World!'\n" }
14
+ assert_equal "(function() {\n puts('Hello, World!');\n})();\n", template.render
15
+ end
16
+
17
+ test "disabling coffee-script wrapper" do
18
+ template = Tilt::CoffeeScriptTemplate.new(:no_wrap => true) { |t| "puts 'Hello, World!'\n" }
19
+ assert_equal "puts('Hello, World!');", template.render
20
+ end
21
+ end
22
+
23
+ rescue LoadError => boom
24
+ warn "Tilt::CoffeeScriptTemplate (disabled)\n"
25
+ end
@@ -0,0 +1,73 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ begin
5
+ require 'markaby'
6
+
7
+ class MarkabyTiltTest < Test::Unit::TestCase
8
+ def setup
9
+ @block = lambda do |t|
10
+ File.read(File.dirname(__FILE__) + "/#{t.file}")
11
+ end
12
+ end
13
+
14
+ test "should be able to render a markaby template with static html" do
15
+ tilt = Tilt::MarkabyTemplate.new("markaby/markaby.mab", &@block)
16
+ assert_equal "hello from markaby!", tilt.render
17
+ end
18
+
19
+ test "should use the contents of the template" do
20
+ tilt = ::Tilt::MarkabyTemplate.new("markaby/markaby_other_static.mab", &@block)
21
+ assert_equal "_why?", tilt.render
22
+ end
23
+
24
+ test "should render from a string (given as data)" do
25
+ tilt = ::Tilt::MarkabyTemplate.new { "html do; end" }
26
+ assert_equal "<html></html>", tilt.render
27
+ end
28
+
29
+ test "should evaluate a template file in the scope given" do
30
+ scope = Object.new
31
+ def scope.foo
32
+ "bar"
33
+ end
34
+
35
+ tilt = ::Tilt::MarkabyTemplate.new("markaby/scope.mab", &@block)
36
+ assert_equal "<li>bar</li>", tilt.render(scope)
37
+ end
38
+
39
+ test "should pass locals to the template" do
40
+ tilt = ::Tilt::MarkabyTemplate.new("markaby/locals.mab", &@block)
41
+ assert_equal "<li>bar</li>", tilt.render(Object.new, { :foo => "bar" })
42
+ end
43
+
44
+ test "should yield to the block given" do
45
+ tilt = ::Tilt::MarkabyTemplate.new("markaby/yielding.mab", &@block)
46
+ eval_scope = Markaby::Builder.new
47
+
48
+ output = tilt.render(Object.new, {}) do
49
+ text("Joe")
50
+ end
51
+
52
+ assert_equal "Hey Joe", output
53
+ end
54
+
55
+ test "should be able to render two templates in a row" do
56
+ tilt = ::Tilt::MarkabyTemplate.new("markaby/render_twice.mab", &@block)
57
+
58
+ assert_equal "foo", tilt.render
59
+ assert_equal "foo", tilt.render
60
+ end
61
+
62
+ test "should retrieve a Tilt::MarkabyTemplate when calling Tilt['hello.mab']" do
63
+ assert_equal Tilt::MarkabyTemplate, ::Tilt['./markaby/markaby.mab']
64
+ end
65
+
66
+ test "should return a new instance of the implementation class (when calling Tilt.new)" do
67
+ assert ::Tilt.new(File.dirname(__FILE__) + "/markaby/markaby.mab").kind_of?(Tilt::MarkabyTemplate)
68
+ end
69
+ end
70
+
71
+ rescue LoadError => boom
72
+ warn "Tilt::MarkabyTemplate (disabled)\n"
73
+ end
@@ -0,0 +1,54 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ begin
5
+ require 'nokogiri'
6
+ class NokogiriTemplateTest < Test::Unit::TestCase
7
+ test "registered for '.nokogiri' files" do
8
+ assert_equal Tilt::NokogiriTemplate, Tilt['test.nokogiri']
9
+ assert_equal Tilt::NokogiriTemplate, Tilt['test.xml.nokogiri']
10
+ end
11
+
12
+ test "preparing and evaluating the template on #render" do
13
+ template = Tilt::NokogiriTemplate.new { |t| "xml.em 'Hello World!'" }
14
+ doc = Nokogiri.XML template.render
15
+ assert_equal 'Hello World!', doc.root.text
16
+ assert_equal 'em', doc.root.name
17
+ end
18
+
19
+ test "passing locals" do
20
+ template = Tilt::NokogiriTemplate.new { "xml.em('Hey ' + name + '!')" }
21
+ doc = Nokogiri.XML template.render(Object.new, :name => 'Joe')
22
+ assert_equal 'Hey Joe!', doc.root.text
23
+ assert_equal 'em', doc.root.name
24
+ end
25
+
26
+ test "evaluating in an object scope" do
27
+ template = Tilt::NokogiriTemplate.new { "xml.em('Hey ' + @name + '!')" }
28
+ scope = Object.new
29
+ scope.instance_variable_set :@name, 'Joe'
30
+ doc = Nokogiri.XML template.render(scope)
31
+ assert_equal 'Hey Joe!', doc.root.text
32
+ assert_equal 'em', doc.root.name
33
+ end
34
+
35
+ test "passing a block for yield" do
36
+ template = Tilt::NokogiriTemplate.new { "xml.em('Hey ' + yield + '!')" }
37
+ doc = Nokogiri.XML template.render { 'Joe' }
38
+ assert_equal 'Hey Joe!', doc.root.text
39
+ assert_equal 'em', doc.root.name
40
+ end
41
+
42
+ test "block style templates" do
43
+ template =
44
+ Tilt::NokogiriTemplate.new do |t|
45
+ lambda { |xml| xml.em('Hey Joe!') }
46
+ end
47
+ doc = Nokogiri.XML template.render template.render
48
+ assert_equal 'Hey Joe!', doc.root.text
49
+ assert_equal 'em', doc.root.name
50
+ end
51
+ end
52
+ rescue LoadError
53
+ warn "Tilt::NokogiriTemplate (disabled)"
54
+ end
@@ -2,6 +2,10 @@ require 'contest'
2
2
  require 'tilt'
3
3
 
4
4
  begin
5
+ # Disable radius tests under Ruby versions >= 1.9.1 since it's still buggy.
6
+ # Remove when fixed upstream.
7
+ raise LoadError if RUBY_VERSION >= "1.9.1"
8
+
5
9
  require 'radius'
6
10
 
7
11
  class RadiusTemplateTest < Test::Unit::TestCase
@@ -16,6 +16,17 @@ begin
16
16
  end
17
17
  end
18
18
 
19
+ class ScssTemplateTest < Test::Unit::TestCase
20
+ test "is registered for '.scss' files" do
21
+ assert_equal Tilt::ScssTemplate, Tilt['test.scss']
22
+ end
23
+
24
+ test "compiles and evaluates the template on #render" do
25
+ template = Tilt::ScssTemplate.new { |t| "#main {\n background-color: #0000f1;\n}" }
26
+ assert_equal "#main {\n background-color: #0000f1; }\n", template.render
27
+ end
28
+ end
29
+
19
30
  rescue LoadError => boom
20
31
  warn "Tilt::SassTemplate (disabled)\n"
21
32
  end
@@ -150,10 +150,9 @@ class TiltTemplateTest < Test::Unit::TestCase
150
150
  include Tilt::CompileSite
151
151
  end
152
152
 
153
- # FAILING CONSTANT TEST. DISABLED FOR 1.0.
154
-
155
- # test "template which accesses a constant with Tilt::CompileSite" do
156
- # inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{CONSTANT}!' }
157
- # assert_equal "Hey Bob!", inst.render(FastPerson.new("Joe"))
158
- # end
153
+ test "template which accesses a constant with Tilt::CompileSite" do
154
+ flunk "known broken under 1.9.1" if RUBY_VERSION =~ /^1.9.1/
155
+ inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{CONSTANT}!' }
156
+ assert_equal "Hey Bob!", inst.render(FastPerson.new("Joe"))
157
+ end
159
158
  end
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'tilt'
6
- s.version = '1.0.1'
7
- s.date = '2010-06-15'
6
+ s.version = '1.1'
7
+ s.date = '2010-09-10'
8
8
 
9
9
  s.description = "Generic interface to multiple Ruby template engines"
10
10
  s.summary = s.description
@@ -21,14 +21,23 @@ Gem::Specification.new do |s|
21
21
  bin/tilt
22
22
  lib/tilt.rb
23
23
  test/contest.rb
24
+ test/markaby/locals.mab
25
+ test/markaby/markaby.mab
26
+ test/markaby/markaby_other_static.mab
27
+ test/markaby/render_twice.mab
28
+ test/markaby/scope.mab
29
+ test/markaby/yielding.mab
24
30
  test/tilt_buildertemplate_test.rb
25
31
  test/tilt_cache_test.rb
32
+ test/tilt_coffeescripttemplate_test.rb
26
33
  test/tilt_compilesite_test.rb
27
34
  test/tilt_erbtemplate_test.rb
28
35
  test/tilt_erubistemplate_test.rb
29
36
  test/tilt_hamltemplate_test.rb
30
37
  test/tilt_lesstemplate_test.rb
31
38
  test/tilt_liquidtemplate_test.rb
39
+ test/tilt_markaby_test.rb
40
+ test/tilt_nokogiritemplate_test.rb
32
41
  test/tilt_radiustemplate_test.rb
33
42
  test/tilt_rdiscounttemplate_test.rb
34
43
  test/tilt_rdoctemplate_test.rb
@@ -53,6 +62,9 @@ Gem::Specification.new do |s|
53
62
  s.add_development_dependency 'liquid'
54
63
  s.add_development_dependency 'less'
55
64
  s.add_development_dependency 'radius'
65
+ s.add_development_dependency 'nokogiri'
66
+ s.add_development_dependency 'markaby'
67
+ s.add_development_dependency 'coffee-script'
56
68
 
57
69
  s.extra_rdoc_files = %w[COPYING]
58
70
 
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tilt
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 0
9
8
  - 1
10
- version: 1.0.1
9
+ version: "1.1"
11
10
  platform: ruby
12
11
  authors:
13
12
  - Ryan Tomayko
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-06-15 00:00:00 -07:00
17
+ date: 2010-09-10 00:00:00 -07:00
19
18
  default_executable: tilt
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -132,6 +131,48 @@ dependencies:
132
131
  version: "0"
133
132
  type: :development
134
133
  version_requirements: *id008
134
+ - !ruby/object:Gem::Dependency
135
+ name: nokogiri
136
+ prerelease: false
137
+ requirement: &id009 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ hash: 3
143
+ segments:
144
+ - 0
145
+ version: "0"
146
+ type: :development
147
+ version_requirements: *id009
148
+ - !ruby/object:Gem::Dependency
149
+ name: markaby
150
+ prerelease: false
151
+ requirement: &id010 !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ type: :development
161
+ version_requirements: *id010
162
+ - !ruby/object:Gem::Dependency
163
+ name: coffee-script
164
+ prerelease: false
165
+ requirement: &id011 !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ hash: 3
171
+ segments:
172
+ - 0
173
+ version: "0"
174
+ type: :development
175
+ version_requirements: *id011
135
176
  description: Generic interface to multiple Ruby template engines
136
177
  email: r@tomayko.com
137
178
  executables:
@@ -148,14 +189,23 @@ files:
148
189
  - bin/tilt
149
190
  - lib/tilt.rb
150
191
  - test/contest.rb
192
+ - test/markaby/locals.mab
193
+ - test/markaby/markaby.mab
194
+ - test/markaby/markaby_other_static.mab
195
+ - test/markaby/render_twice.mab
196
+ - test/markaby/scope.mab
197
+ - test/markaby/yielding.mab
151
198
  - test/tilt_buildertemplate_test.rb
152
199
  - test/tilt_cache_test.rb
200
+ - test/tilt_coffeescripttemplate_test.rb
153
201
  - test/tilt_compilesite_test.rb
154
202
  - test/tilt_erbtemplate_test.rb
155
203
  - test/tilt_erubistemplate_test.rb
156
204
  - test/tilt_hamltemplate_test.rb
157
205
  - test/tilt_lesstemplate_test.rb
158
206
  - test/tilt_liquidtemplate_test.rb
207
+ - test/tilt_markaby_test.rb
208
+ - test/tilt_nokogiritemplate_test.rb
159
209
  - test/tilt_radiustemplate_test.rb
160
210
  - test/tilt_rdiscounttemplate_test.rb
161
211
  - test/tilt_rdoctemplate_test.rb
@@ -207,12 +257,15 @@ summary: Generic interface to multiple Ruby template engines
207
257
  test_files:
208
258
  - test/tilt_buildertemplate_test.rb
209
259
  - test/tilt_cache_test.rb
260
+ - test/tilt_coffeescripttemplate_test.rb
210
261
  - test/tilt_compilesite_test.rb
211
262
  - test/tilt_erbtemplate_test.rb
212
263
  - test/tilt_erubistemplate_test.rb
213
264
  - test/tilt_hamltemplate_test.rb
214
265
  - test/tilt_lesstemplate_test.rb
215
266
  - test/tilt_liquidtemplate_test.rb
267
+ - test/tilt_markaby_test.rb
268
+ - test/tilt_nokogiritemplate_test.rb
216
269
  - test/tilt_radiustemplate_test.rb
217
270
  - test/tilt_rdiscounttemplate_test.rb
218
271
  - test/tilt_rdoctemplate_test.rb