tilt 0.8 → 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/README.md CHANGED
@@ -30,9 +30,10 @@ Support for these template engines is included with the package:
30
30
  Less CSS .less less
31
31
  Builder .builder builder
32
32
  Liquid .liquid liquid
33
- Mustache .mustache mustache
34
33
  RDiscount .markdown rdiscount
35
34
  RedCloth .textile redcloth
35
+ RDoc .rdoc rdoc
36
+ Radius .radius radius
36
37
 
37
38
  See [TEMPLATES.md][t] for detailed information on template engine
38
39
  options and supported features.
data/Rakefile CHANGED
@@ -11,11 +11,17 @@ end
11
11
  desc 'Run tests (default)'
12
12
  Rake::TestTask.new(:test) do |t|
13
13
  t.test_files = FileList['test/*_test.rb']
14
- t.ruby_opts = ['-rubygems'] if defined? Gem
14
+ t.ruby_opts = ['-Itest']
15
+ t.ruby_opts << '-rubygems' if defined? Gem
15
16
  end
16
17
 
17
18
  # PACKAGING =================================================================
18
19
 
20
+ begin
21
+ require 'rubygems'
22
+ rescue LoadError
23
+ end
24
+
19
25
  if defined?(Gem)
20
26
  SPEC = eval(File.read('tilt.gemspec'))
21
27
 
@@ -72,26 +78,3 @@ file 'tilt.gemspec' => FileList['{lib,test}/**','Rakefile'] do |f|
72
78
  File.open(f.name, 'w') { |io| io.write(spec) }
73
79
  puts "updated #{f.name}"
74
80
  end
75
-
76
- # DOC =======================================================================
77
-
78
- # requires the hanna gem:
79
- # gem install mislav-hanna --source=http://gems.github.com
80
- desc 'Build API documentation (doc/api)'
81
- task 'rdoc' => 'rdoc/index.html'
82
- file 'rdoc/index.html' => FileList['lib/**/*.rb'] do |f|
83
- rm_rf 'rdoc'
84
- sh((<<-SH).gsub(/[\s\n]+/, ' ').strip)
85
- hanna
86
- --op doc/api
87
- --promiscuous
88
- --charset utf8
89
- --fmt html
90
- --inline-source
91
- --line-numbers
92
- --accessor option_accessor=RW
93
- --main Tilt
94
- --title 'Tilt API Documentation'
95
- #{f.prerequisites.join(' ')}
96
- SH
97
- end
data/TEMPLATES.md CHANGED
@@ -9,7 +9,6 @@ documentation on each supported template engine is provided below.
9
9
  * [Erubis](#erubis) - `Tilt::ErubisTemplate`
10
10
  * [Haml](#haml) - `Tilt::HamlTemplate`
11
11
  * [Liquid](#liquid) - `Tilt::LiquidTemplate`
12
- * [Mustache](#mustache) - `Tilt::MustachTemplate`
13
12
 
14
13
  Tilt includes support for CSS processors like [lesscss](http://lesscss.org)
15
14
  and [sass](http://sass-lang.com/), in addition, it also supports simple
@@ -94,15 +93,16 @@ the extensions as follows:
94
93
 
95
94
  ### Options
96
95
 
97
- #### `:trim => true`
98
-
99
- Delete spaces around '<% %>'. (But, spaces around '<%= %>' are preserved.)
96
+ #### `:engine_class => Erubis::Eruby`
100
97
 
101
- #### `:pattern => '<% %>'`
98
+ Allows you to specify a custom engine class to use instead of the
99
+ default which is `Erubis::Eruby`.
102
100
 
103
- Set pattern for embedded Ruby code.
101
+ #### `:escape_html => false`
104
102
 
105
- See the [ERB](#erb) template documentation for examples, usage, and options.
103
+ When `true`, `Erubis::EscapedEruby` will be used as the engine class
104
+ instead of the default. All content within `<%= %>` blocks will be
105
+ automatically html escaped.
106
106
 
107
107
  #### `:outvar => '_erbout'`
108
108
 
@@ -110,6 +110,16 @@ The name of the variable used to accumulate template output. This can be
110
110
  any valid Ruby expression but must be assignable. By default a local
111
111
  variable named `_erbout` is used.
112
112
 
113
+ #### `:pattern => '<% %>'`
114
+
115
+ Set pattern for embedded Ruby code.
116
+
117
+ See the [ERB](#erb) template documentation for examples, usage, and options.
118
+
119
+ #### `:trim => true`
120
+
121
+ Delete spaces around '<% %>'. (But, spaces around '<%= %>' are preserved.)
122
+
113
123
  ### See also
114
124
 
115
125
  * [Erubis Home](http://www.kuwata-lab.com/erubis/)
@@ -293,53 +303,6 @@ time when using this template engine within a threaded environment.
293
303
  * [Liquid Docs](http://liquid.rubyforge.org/)
294
304
  * GitHub: [tobi/liquid](http://github.com/tobi/liquid/)
295
305
 
296
- <a name='mustache'></a>
297
- Mustache (`mustache`)
298
- ---------------------
299
-
300
- Mustache is a framework-agnostic way to render logic-free views.
301
-
302
- __NOTE:__ It's suggested that your program `require 'mustache'` at load time
303
- when using this template engine in a threaded environment.
304
-
305
- ### Options
306
-
307
- #### `:path => Dir.pwd`
308
-
309
- The base path where mustache templates (`.html` files) are located. Defaults to
310
- the current working directory.
311
-
312
- #### `:template_extension => 'html'`
313
-
314
- The file extension used on mustache templates. Default is `'html'`.
315
-
316
- #### `:namespace => Object`
317
-
318
- The class or module where View classes are located. If you have
319
- `Hurl::App::Views`, namespace should be `Hurl:App`. This defaults to `Object`,
320
- causing `::Views` to be searched for classes.
321
-
322
- #### `:mustaches => nil` or `:view_path => nil`
323
-
324
- Where mustache views (`.rb` files) are located, or `nil` to disable auto-requiring
325
- of views based on template names. By default, the view file is assumed to be in
326
- the same directory as the template file.
327
-
328
- All other options are assumed to be attribute writer's on the Mustache
329
- class and are set when a template is compiled. They are:
330
-
331
- #### `:view => nil`
332
-
333
- The Mustache subclass that should be used a the view. When this option is
334
- specified, the template file will be determined from the view class, and the
335
- `:namespace` and `:mustaches` options are irrelevant.
336
-
337
- ### See also
338
-
339
- * [Mustache Docs](http://defunkt.github.com/mustache/)
340
- * GitHub: [defunkt/mustache](http://github.com/defunkt/mustache)
341
-
342
-
343
306
  <a name='markdown'></a>
344
307
  Markdown (`markdown`, `md`, `mkd`)
345
308
  ----------------------------------
@@ -421,3 +384,56 @@ engine in a threaded environment.
421
384
  ### See also
422
385
 
423
386
  * [RDoc](http://rdoc.sourceforge.net/doc/index.html)
387
+
388
+
389
+ <a name='radius'></a>
390
+ Radius (`radius`)
391
+ -----------------
392
+
393
+ Radius is the template language used by Radiant CMS. It is a tag
394
+ language designed to be valid XML/HTML.
395
+
396
+ ### Example
397
+
398
+ <html>
399
+ <body>
400
+ <h1><r:title /></h1>
401
+ <ul class="<r:type />">
402
+ <r:repeat times="3">
403
+ <li><r:hello />!</li>
404
+ </r:repeat>
405
+ </ul>
406
+ <r:yield />
407
+ </body>
408
+ </html>
409
+
410
+ ### Usage
411
+
412
+ To render a template such as the one above.
413
+
414
+ scope = OpenStruct.new
415
+ scope.title = "Radius Example"
416
+ scope.hello = "Hello, World!"
417
+
418
+ require 'radius'
419
+ template = Tilt::RadiusTemplate.new('example.radius', :tag_prefix=>'r')
420
+ template.render(scope, :type=>'hlist'){ "Jackpot!" }
421
+
422
+ The result will be:
423
+
424
+ <html>
425
+ <body>
426
+ <h1>Radius Example</h1>
427
+ <ul class="hlist">
428
+ <li>Hello, World!</li>
429
+ <li>Hello, World!</li>
430
+ <li>Hello, World!</li>
431
+ </ul>
432
+ Jackpot!
433
+ </body>
434
+ </html>
435
+
436
+ ### See also
437
+
438
+ * [Radius](http://radius.rubyforge.org/)
439
+ * [Radiant](http://radiantcms.org/)
data/lib/tilt.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  module Tilt
4
- VERSION = '0.8'
4
+ VERSION = '1.0'
5
5
 
6
6
  @template_mappings = {}
7
7
 
@@ -16,6 +16,11 @@ module Tilt
16
16
  mappings[ext.downcase] = template_class
17
17
  end
18
18
 
19
+ # Returns true when a template exists on an exact match of the provided file extension
20
+ def self.registered?(ext)
21
+ mappings.key?(ext.downcase)
22
+ end
23
+
19
24
  # Create a new template for the given file using the file's extension
20
25
  # to determine the the template mapping.
21
26
  def self.new(file, line=nil, options={}, &block)
@@ -29,20 +34,12 @@ module Tilt
29
34
  # Lookup a template class for the given filename or file
30
35
  # extension. Return nil when no implementation is found.
31
36
  def self.[](file)
32
- if @template_mappings.key?(pattern = file.to_s.downcase)
33
- @template_mappings[pattern]
34
- elsif @template_mappings.key?(pattern = File.basename(pattern))
35
- @template_mappings[pattern]
36
- else
37
- while !pattern.empty?
38
- if @template_mappings.key?(pattern)
39
- return @template_mappings[pattern]
40
- else
41
- pattern = pattern.sub(/^[^.]*\.?/, '')
42
- end
43
- end
44
- nil
37
+ pattern = file.to_s.downcase
38
+ unless registered?(pattern)
39
+ pattern = File.basename(pattern)
40
+ pattern.sub!(/^[^.]*\.?/, '') until (pattern.empty? || registered?(pattern))
45
41
  end
42
+ @template_mappings[pattern]
46
43
  end
47
44
 
48
45
  # Mixin allowing template compilation on scope objects.
@@ -100,7 +97,7 @@ module Tilt
100
97
  case
101
98
  when arg.respond_to?(:to_str) ; @file = arg.to_str
102
99
  when arg.respond_to?(:to_int) ; @line = arg.to_int
103
- when arg.respond_to?(:to_hash) ; @options = arg.to_hash
100
+ when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
104
101
  else raise TypeError
105
102
  end
106
103
  end
@@ -353,18 +350,29 @@ module Tilt
353
350
  # ERB template implementation. See:
354
351
  # http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html
355
352
  class ERBTemplate < Template
353
+ @@default_output_variable = '_erbout'
354
+
355
+ def self.default_output_variable
356
+ @@default_output_variable
357
+ end
358
+
359
+ def self.default_output_variable=(name)
360
+ @@default_output_variable = name
361
+ end
362
+
356
363
  def initialize_engine
357
364
  return if defined? ::ERB
358
365
  require_template_library 'erb'
359
366
  end
360
367
 
361
368
  def prepare
362
- @outvar = (options[:outvar] || '_erbout').to_s
369
+ @outvar = options[:outvar] || self.class.default_output_variable
363
370
  @engine = ::ERB.new(data, options[:safe], options[:trim], @outvar)
364
371
  end
365
372
 
366
373
  def precompiled_template(locals)
367
- @engine.src
374
+ source = @engine.src
375
+ source
368
376
  end
369
377
 
370
378
  def precompiled_preamble(locals)
@@ -399,6 +407,16 @@ module Tilt
399
407
 
400
408
  # Erubis template implementation. See:
401
409
  # http://www.kuwata-lab.com/erubis/
410
+ #
411
+ # ErubisTemplate supports the following additional options, which are not
412
+ # passed down to the Erubis engine:
413
+ #
414
+ # :engine_class allows you to specify a custom engine class to use
415
+ # instead of the default (which is ::Erubis::Eruby).
416
+ #
417
+ # :escape_html when true, ::Erubis::EscapedEruby will be used as
418
+ # the engine class instead of the default. All content
419
+ # within <%= %> blocks will be automatically html escaped.
402
420
  class ErubisTemplate < ERBTemplate
403
421
  def initialize_engine
404
422
  return if defined? ::Erubis
@@ -407,8 +425,10 @@ module Tilt
407
425
 
408
426
  def prepare
409
427
  @options.merge!(:preamble => false, :postamble => false)
410
- @outvar = (options.delete(:outvar) || '_erbout').to_s
411
- @engine = ::Erubis::Eruby.new(data, options)
428
+ @outvar = options.delete(:outvar) || self.class.default_output_variable
429
+ engine_class = options.delete(:engine_class)
430
+ engine_class = ::Erubis::EscapedEruby if options.delete(:escape_html)
431
+ @engine = (engine_class || ::Erubis::Eruby).new(data, options)
412
432
  end
413
433
 
414
434
  def precompiled_preamble(locals)
@@ -651,55 +671,6 @@ module Tilt
651
671
  register 'textile', RedClothTemplate
652
672
 
653
673
 
654
- # Mustache is written and maintained by Chris Wanstrath. See:
655
- # http://github.com/defunkt/mustache
656
- #
657
- # When a scope argument is provided to MustacheTemplate#render, the
658
- # instance variables are copied from the scope object to the Mustache
659
- # view.
660
- class MustacheTemplate < Template
661
- attr_reader :engine
662
-
663
- def initialize_engine
664
- return if defined? ::Mustache
665
- require_template_library 'mustache'
666
- end
667
-
668
- def prepare
669
- Mustache.view_namespace = options[:namespace]
670
- Mustache.view_path = options[:view_path] || options[:mustaches]
671
- @engine = options[:view] || Mustache.view_class(name)
672
- options.each do |key, value|
673
- next if %w[view view_path namespace mustaches].include?(key.to_s)
674
- @engine.send("#{key}=", value) if @engine.respond_to? "#{key}="
675
- end
676
- end
677
-
678
- def evaluate(scope=nil, locals={}, &block)
679
- instance = @engine.new
680
-
681
- # copy instance variables from scope to the view
682
- scope.instance_variables.each do |name|
683
- instance.instance_variable_set(name, scope.instance_variable_get(name))
684
- end
685
-
686
- # locals get added to the view's context
687
- locals.each do |local, value|
688
- instance[local] = value
689
- end
690
-
691
- # if we're passed a block it's a subview. Sticking it in yield
692
- # lets us use {{yield}} in layout.html to render the actual page.
693
- instance[:yield] = block.call if block
694
-
695
- instance.template = data unless instance.compiled?
696
-
697
- instance.to_html
698
- end
699
- end
700
- register 'mustache', MustacheTemplate
701
-
702
-
703
674
  # RDoc template. See:
704
675
  # http://rdoc.rubyforge.org/
705
676
  #
@@ -726,21 +697,36 @@ module Tilt
726
697
  register 'rdoc', RDocTemplate
727
698
 
728
699
 
729
- # CoffeeScript info:
730
- # http://jashkenas.github.com/coffee-script/
731
- class CoffeeTemplate < Template
700
+ # Radius Template
701
+ # http://github.com/jlong/radius/
702
+ class RadiusTemplate < Template
732
703
  def initialize_engine
733
- return if defined? ::CoffeeScript
734
- require_template_library 'coffee-script'
704
+ return if defined? ::Radius
705
+ require_template_library 'radius'
735
706
  end
736
707
 
737
708
  def prepare
738
- @output = nil
739
709
  end
740
710
 
741
711
  def evaluate(scope, locals, &block)
742
- @output ||= ::CoffeeScript::compile(data, options)
712
+ context = Class.new(Radius::Context).new
713
+ context.define_tag("yield") do
714
+ block.call
715
+ end
716
+ locals.each do |tag, value|
717
+ context.define_tag(tag) do
718
+ value
719
+ end
720
+ end
721
+ (class << context; self; end).class_eval do
722
+ define_method :tag_missing do |tag, attr, &block|
723
+ scope.__send__(tag) # any way to support attr as args?
724
+ end
725
+ end
726
+ options = {:tag_prefix => 'r'}.merge(@options)
727
+ parser = Radius::Parser.new(context, options)
728
+ parser.parse(data)
743
729
  end
744
730
  end
745
- register 'coffee', CoffeeTemplate
731
+ register 'radius', RadiusTemplate
746
732
  end
data/test/contest.rb ADDED
@@ -0,0 +1,68 @@
1
+ require "test/unit"
2
+
3
+ # Test::Unit loads a default test if the suite is empty, whose purpose is to
4
+ # fail. Since having empty contexts is a common practice, we decided to
5
+ # overwrite TestSuite#empty? in order to allow them. Having a failure when no
6
+ # tests have been defined seems counter-intuitive.
7
+ class Test::Unit::TestSuite
8
+ def empty?
9
+ false
10
+ end
11
+ end
12
+
13
+ # Contest adds +teardown+, +test+ and +context+ as class methods, and the
14
+ # instance methods +setup+ and +teardown+ now iterate on the corresponding
15
+ # blocks. Note that all setup and teardown blocks must be defined with the
16
+ # block syntax. Adding setup or teardown instance methods defeats the purpose
17
+ # of this library.
18
+ class Test::Unit::TestCase
19
+ def self.setup(&block)
20
+ define_method :setup do
21
+ super(&block)
22
+ instance_eval(&block)
23
+ end
24
+ end
25
+
26
+ def self.teardown(&block)
27
+ define_method :teardown do
28
+ instance_eval(&block)
29
+ super(&block)
30
+ end
31
+ end
32
+
33
+ def self.context(name, &block)
34
+ subclass = Class.new(self)
35
+ remove_tests(subclass)
36
+ subclass.class_eval(&block) if block_given?
37
+ const_set(context_name(name), subclass)
38
+ end
39
+
40
+ def self.test(name, &block)
41
+ define_method(test_name(name), &block)
42
+ end
43
+
44
+ class << self
45
+ alias_method :should, :test
46
+ alias_method :describe, :context
47
+ end
48
+
49
+ private
50
+
51
+ def self.context_name(name)
52
+ "Test#{sanitize_name(name).gsub(/(^| )(\w)/) { $2.upcase }}".to_sym
53
+ end
54
+
55
+ def self.test_name(name)
56
+ "test_#{sanitize_name(name).gsub(/\s+/,'_')}".to_sym
57
+ end
58
+
59
+ def self.sanitize_name(name)
60
+ name.gsub(/\W+/, ' ').strip
61
+ end
62
+
63
+ def self.remove_tests(subclass)
64
+ subclass.public_instance_methods.grep(/^test_/).each do |meth|
65
+ subclass.send(:undef_method, meth.to_sym)
66
+ end
67
+ end
68
+ end
@@ -29,6 +29,23 @@ class ERBTemplateTest < Test::Unit::TestCase
29
29
  assert_equal "Hey Joe!", template.render(scope)
30
30
  end
31
31
 
32
+ class MockOutputVariableScope
33
+ attr_accessor :exposed_buffer
34
+ end
35
+
36
+ test "exposing the buffer to the template by default" do
37
+ begin
38
+ Tilt::ERBTemplate.default_output_variable = '@_out_buf'
39
+ template = Tilt::ERBTemplate.new { '<% self.exposed_buffer = @_out_buf %>hey' }
40
+ scope = MockOutputVariableScope.new
41
+ template.render(scope)
42
+ assert_not_nil scope.exposed_buffer
43
+ assert_equal scope.exposed_buffer, 'hey'
44
+ ensure
45
+ Tilt::ERBTemplate.default_output_variable = '_erbout'
46
+ end
47
+ end
48
+
32
49
  test "passing a block for yield" do
33
50
  template = Tilt::ERBTemplate.new { 'Hey <%= yield %>!' }
34
51
  assert_equal "Hey Joe!", template.render { 'Joe' }
@@ -26,6 +26,23 @@ begin
26
26
  assert_equal "Hey Joe!", template.render(scope)
27
27
  end
28
28
 
29
+ class MockOutputVariableScope
30
+ attr_accessor :exposed_buffer
31
+ end
32
+
33
+ test "exposing the buffer to the template by default" do
34
+ begin
35
+ Tilt::ErubisTemplate.default_output_variable = '@_out_buf'
36
+ template = Tilt::ErubisTemplate.new { '<% self.exposed_buffer = @_out_buf %>hey' }
37
+ scope = MockOutputVariableScope.new
38
+ template.render(scope)
39
+ assert_not_nil scope.exposed_buffer
40
+ assert_equal scope.exposed_buffer, 'hey'
41
+ ensure
42
+ Tilt::ErubisTemplate.default_output_variable = '_erbout'
43
+ end
44
+ end
45
+
29
46
  test "passing a block for yield" do
30
47
  template = Tilt::ErubisTemplate.new { 'Hey <%= yield %>!' }
31
48
  assert_equal "Hey Joe!", template.render { 'Joe' }
@@ -77,6 +94,32 @@ begin
77
94
  assert_equal '2', template.render(scope)
78
95
  assert_equal 'original value', scope.instance_variable_get(:@buf)
79
96
  end
97
+
98
+ test "using Erubis::EscapedEruby subclass via :engine_class option" do
99
+ template = Tilt::ErubisTemplate.new(nil, :engine_class => ::Erubis::EscapedEruby) { |t| %(<%= "<p>Hello World!</p>" %>) }
100
+ assert_equal "&lt;p&gt;Hello World!&lt;/p&gt;", template.render
101
+ end
102
+
103
+ test "using :escape_html => true option" do
104
+ template = Tilt::ErubisTemplate.new(nil, :escape_html => true) { |t| %(<%= "<p>Hello World!</p>" %>) }
105
+ assert_equal "&lt;p&gt;Hello World!&lt;/p&gt;", template.render
106
+ end
107
+
108
+ test "using :escape_html => false option" do
109
+ template = Tilt::ErubisTemplate.new(nil, :escape_html => false) { |t| %(<%= "<p>Hello World!</p>" %>) }
110
+ assert_equal "<p>Hello World!</p>", template.render
111
+ end
112
+
113
+ test "erubis default does not escape html" do
114
+ template = Tilt::ErubisTemplate.new { |t| %(<%= "<p>Hello World!</p>" %>) }
115
+ assert_equal "<p>Hello World!</p>", template.render
116
+ end
117
+
118
+ test "does not modify options argument" do
119
+ options_hash = {:escape_html => true}
120
+ template = Tilt::ErubisTemplate.new(nil, options_hash) { |t| "Hello World!" }
121
+ assert_equal({:escape_html => true}, options_hash)
122
+ end
80
123
  end
81
124
  rescue LoadError => boom
82
125
  warn "Tilt::ErubisTemplate (disabled)\n"
@@ -0,0 +1,66 @@
1
+ require 'contest'
2
+ require 'tilt'
3
+
4
+ begin
5
+ require 'radius'
6
+
7
+ class RadiusTemplateTest < Test::Unit::TestCase
8
+ test "registered for '.radius' files" do
9
+ assert_equal Tilt::RadiusTemplate, Tilt['test.radius']
10
+ end
11
+
12
+ test "preparing and evaluating templates on #render" do
13
+ template = Tilt::RadiusTemplate.new { |t| "Hello World!" }
14
+ assert_equal "Hello World!", template.render
15
+ end
16
+
17
+ test "passing locals" do
18
+ template = Tilt::RadiusTemplate.new { "Hey <r:name />!" }
19
+ assert_equal "Hey Joe!", template.render(nil, :name => 'Joe')
20
+ end
21
+
22
+ class ExampleRadiusScope
23
+ def beer; 'wet'; end
24
+ def whisky; 'wetter'; end
25
+ end
26
+
27
+ test "combining scope and locals when scope responds" do
28
+ template = Tilt::RadiusTemplate.new {
29
+ 'Beer is <r:beer /> but Whisky is <r:whisky />.'
30
+ }
31
+ scope = ExampleRadiusScope.new
32
+ assert_equal "Beer is wet but Whisky is wetter.", template.render(scope)
33
+ end
34
+
35
+ test "precedence when locals and scope define same variables" do
36
+ template = Tilt::RadiusTemplate.new {
37
+ 'Beer is <r:beer /> but Whisky is <r:whisky />.'
38
+ }
39
+ scope = ExampleRadiusScope.new
40
+ assert_equal "Beer is great but Whisky is greater.",
41
+ template.render(scope, :beer => 'great', :whisky => 'greater')
42
+ end
43
+
44
+ #test "handles local scope" do
45
+ # beer = 'wet'
46
+ # whisky = 'wetter'
47
+ #
48
+ # template = Tilt::RadiusTemplate.new {
49
+ # 'Beer is <r:beer /> but Whisky is <r:whisky />.'
50
+ # }
51
+ # assert_equal "Beer is wet but Whisky is wetter.", template.render(self)
52
+ #end
53
+
54
+ test "passing a block for yield" do
55
+ template = Tilt::RadiusTemplate.new {
56
+ 'Beer is <r:yield /> but Whisky is <r:yield />ter.'
57
+ }
58
+ assert_equal "Beer is wet but Whisky is wetter.",
59
+ template.render({}) { 'wet' }
60
+ end
61
+ end
62
+
63
+ rescue LoadError => boom
64
+ warn "Tilt::RadiusTemplate (disabled)\n"
65
+ end
66
+
@@ -11,8 +11,8 @@ begin
11
11
  end
12
12
 
13
13
  test "compiles and evaluates the template on #render" do
14
- template = Tilt::SassTemplate.new { |t| "#main\n :background-color #0000ff" }
15
- assert_equal "#main {\n background-color: #0000ff; }\n", template.render
14
+ template = Tilt::SassTemplate.new { |t| "#main\n :background-color #0000f1" }
15
+ assert_equal "#main {\n background-color: #0000f1; }\n", template.render
16
16
  end
17
17
  end
18
18
 
@@ -122,6 +122,8 @@ class TiltTemplateTest < Test::Unit::TestCase
122
122
  end
123
123
 
124
124
  class Person
125
+ CONSTANT = "Bob"
126
+
125
127
  attr_accessor :name
126
128
  def initialize(name)
127
129
  @name = name
@@ -138,4 +140,20 @@ class TiltTemplateTest < Test::Unit::TestCase
138
140
  inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{yield}!' }
139
141
  assert_equal "Hey Joe!", inst.render(Object.new){ 'Joe' }
140
142
  end
143
+
144
+ test "template which accesses a constant" do
145
+ inst = SourceGeneratingMockTemplate.new { |t| 'Hey #{CONSTANT}!' }
146
+ assert_equal "Hey Bob!", inst.render(Person.new("Joe"))
147
+ end
148
+
149
+ class FastPerson < Person
150
+ include Tilt::CompileSite
151
+ end
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
141
159
  end
data/test/tilt_test.rb CHANGED
@@ -14,15 +14,23 @@ class TiltTest < Test::Unit::TestCase
14
14
  Tilt.register('mock', MockTemplate)
15
15
  end
16
16
 
17
+ test "an extension is registered if explicit handle is found" do
18
+ Tilt.register('mock', MockTemplate)
19
+ assert Tilt.registered?('mock')
20
+ end
21
+
17
22
  test "registering template classes by symbol file extension" do
18
23
  Tilt.register(:mock, MockTemplate)
19
24
  end
20
25
 
21
- test "looking up template classes by file extension" do
26
+ test "looking up template classes by exact file extension" do
22
27
  Tilt.register('mock', MockTemplate)
23
28
  impl = Tilt['mock']
24
29
  assert_equal MockTemplate, impl
30
+ end
25
31
 
32
+ test "looking up template classes by implicit file extension" do
33
+ Tilt.register('mock', MockTemplate)
26
34
  impl = Tilt['.mock']
27
35
  assert_equal MockTemplate, impl
28
36
  end
data/tilt.gemspec CHANGED
@@ -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 = '0.8'
7
- s.date = '2010-03-07'
6
+ s.version = '1.0'
7
+ s.date = '2010-06-15'
8
8
 
9
9
  s.description = "Generic interface to multiple Ruby template engines"
10
10
  s.summary = s.description
@@ -20,17 +20,16 @@ Gem::Specification.new do |s|
20
20
  TEMPLATES.md
21
21
  bin/tilt
22
22
  lib/tilt.rb
23
+ test/contest.rb
23
24
  test/tilt_buildertemplate_test.rb
24
25
  test/tilt_cache_test.rb
25
- test/tilt_coffeetemplate_test.rb
26
26
  test/tilt_compilesite_test.rb
27
27
  test/tilt_erbtemplate_test.rb
28
28
  test/tilt_erubistemplate_test.rb
29
29
  test/tilt_hamltemplate_test.rb
30
30
  test/tilt_lesstemplate_test.rb
31
31
  test/tilt_liquidtemplate_test.rb
32
- test/tilt_mustache_views/external.rb
33
- test/tilt_mustachetemplate_test.rb
32
+ test/tilt_radiustemplate_test.rb
34
33
  test/tilt_rdiscounttemplate_test.rb
35
34
  test/tilt_rdoctemplate_test.rb
36
35
  test/tilt_redclothtemplate_test.rb
@@ -42,6 +41,9 @@ Gem::Specification.new do |s|
42
41
  ]
43
42
  # = MANIFEST =
44
43
 
44
+ s.default_executable = 'tilt'
45
+ s.executables = ['tilt']
46
+
45
47
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
46
48
  s.add_development_dependency 'contest'
47
49
  s.add_development_dependency 'builder'
@@ -52,6 +54,7 @@ Gem::Specification.new do |s|
52
54
  s.add_development_dependency 'liquid'
53
55
  s.add_development_dependency 'less'
54
56
  s.add_development_dependency 'coffee-script'
57
+ s.add_development_dependency 'radius'
55
58
 
56
59
  s.extra_rdoc_files = %w[COPYING]
57
60
 
metadata CHANGED
@@ -3,9 +3,9 @@ name: tilt
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
- - 8
8
- version: "0.8"
8
+ version: "1.0"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Ryan Tomayko
@@ -13,8 +13,8 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-03-07 00:00:00 -08:00
17
- default_executable:
16
+ date: 2010-06-15 00:00:00 -07:00
17
+ default_executable: tilt
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: contest
@@ -126,10 +126,22 @@ dependencies:
126
126
  version: "0"
127
127
  type: :development
128
128
  version_requirements: *id009
129
+ - !ruby/object:Gem::Dependency
130
+ name: radius
131
+ prerelease: false
132
+ requirement: &id010 !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ segments:
137
+ - 0
138
+ version: "0"
139
+ type: :development
140
+ version_requirements: *id010
129
141
  description: Generic interface to multiple Ruby template engines
130
142
  email: r@tomayko.com
131
- executables: []
132
-
143
+ executables:
144
+ - tilt
133
145
  extensions: []
134
146
 
135
147
  extra_rdoc_files:
@@ -141,17 +153,16 @@ files:
141
153
  - TEMPLATES.md
142
154
  - bin/tilt
143
155
  - lib/tilt.rb
156
+ - test/contest.rb
144
157
  - test/tilt_buildertemplate_test.rb
145
158
  - test/tilt_cache_test.rb
146
- - test/tilt_coffeetemplate_test.rb
147
159
  - test/tilt_compilesite_test.rb
148
160
  - test/tilt_erbtemplate_test.rb
149
161
  - test/tilt_erubistemplate_test.rb
150
162
  - test/tilt_hamltemplate_test.rb
151
163
  - test/tilt_lesstemplate_test.rb
152
164
  - test/tilt_liquidtemplate_test.rb
153
- - test/tilt_mustache_views/external.rb
154
- - test/tilt_mustachetemplate_test.rb
165
+ - test/tilt_radiustemplate_test.rb
155
166
  - test/tilt_rdiscounttemplate_test.rb
156
167
  - test/tilt_rdoctemplate_test.rb
157
168
  - test/tilt_redclothtemplate_test.rb
@@ -198,14 +209,13 @@ summary: Generic interface to multiple Ruby template engines
198
209
  test_files:
199
210
  - test/tilt_buildertemplate_test.rb
200
211
  - test/tilt_cache_test.rb
201
- - test/tilt_coffeetemplate_test.rb
202
212
  - test/tilt_compilesite_test.rb
203
213
  - test/tilt_erbtemplate_test.rb
204
214
  - test/tilt_erubistemplate_test.rb
205
215
  - test/tilt_hamltemplate_test.rb
206
216
  - test/tilt_lesstemplate_test.rb
207
217
  - test/tilt_liquidtemplate_test.rb
208
- - test/tilt_mustachetemplate_test.rb
218
+ - test/tilt_radiustemplate_test.rb
209
219
  - test/tilt_rdiscounttemplate_test.rb
210
220
  - test/tilt_rdoctemplate_test.rb
211
221
  - test/tilt_redclothtemplate_test.rb
@@ -1,20 +0,0 @@
1
- require 'contest'
2
- require 'tilt'
3
-
4
- begin
5
- require 'coffee-script'
6
-
7
- class CoffeeTemplateTest < Test::Unit::TestCase
8
- test "is registered for '.coffee' files" do
9
- assert_equal Tilt::CoffeeTemplate, Tilt['test.coffee']
10
- end
11
-
12
- test "compiles and evaluates the template on #render" do
13
- template = Tilt::CoffeeTemplate.new { |t| "greeting: \"Hello CoffeeScript\"" }
14
- assert_equal "(function(){\n var greeting;\n greeting = \"Hello CoffeeScript\";\n})();", template.render
15
- end
16
- end
17
-
18
- rescue LoadError => boom
19
- warn "Tilt::CoffeeTemplate (disabled)\n"
20
- end
@@ -1,9 +0,0 @@
1
- require 'mustache'
2
-
3
- module Views
4
- class External < Mustache
5
- def hello
6
- "Stached"
7
- end
8
- end
9
- end
@@ -1,70 +0,0 @@
1
- require 'contest'
2
- require 'tilt'
3
-
4
- begin
5
- require 'mustache'
6
- raise LoadError, "mustache version must be > 0.2.2" if !Mustache.respond_to?(:compiled?)
7
-
8
- module Views
9
- class Foo < Mustache
10
- attr_reader :foo
11
- end
12
- end
13
-
14
- class MustacheTemplateTest < Test::Unit::TestCase
15
- test "registered for '.mustache' files" do
16
- assert_equal Tilt::MustacheTemplate, Tilt['test.mustache']
17
- end
18
-
19
- test "preparing and evaluating templates on #render" do
20
- template = Tilt::MustacheTemplate.new { |t| "Hello World!" }
21
- assert_equal "Hello World!", template.render
22
- end
23
-
24
- test "passing locals" do
25
- template = Tilt::MustacheTemplate.new { "<p>Hey {{name}}!</p>" }
26
- assert_equal "<p>Hey Joe!</p>", template.render(nil, :name => 'Joe')
27
- end
28
-
29
- test "passing a block for yield" do
30
- template = Tilt::MustacheTemplate.new { "<p>Hey {{yield}}!</p>" }
31
- assert_equal "<p>Hey Joe!</p>", template.render { 'Joe' }
32
- end
33
-
34
- test "locating views defined at the top-level" do
35
- template = Tilt::MustacheTemplate.new('foo.mustache') { "<p>Hey {{foo}}!</p>" }
36
- assert_equal Views::Foo, template.engine
37
- end
38
-
39
- module Bar
40
- module Views
41
- class Bizzle < Mustache
42
- end
43
- end
44
- end
45
-
46
- test "locating views defined in a custom namespace" do
47
- template = Tilt::MustacheTemplate.new('bizzle.mustache', :namespace => Bar) { "<p>Hello World!</p>" }
48
- assert_equal Bar::Views::Bizzle, template.engine
49
- assert_equal "<p>Hello World!</p>", template.render
50
- end
51
-
52
- test "locating views in files" do
53
- view_path = File.expand_path('../tilt_mustache_views', __FILE__)
54
- template = Tilt::MustacheTemplate.new('external.mustache', :view_path => view_path) { "<p>{{hello}}!</p>" }
55
- assert defined?(Views::External), "external.rb should have been required"
56
- assert_equal Views::External, template.engine
57
- assert_equal "<p>Stached!</p>", template.render
58
- end
59
-
60
- test "copying instance variables from scope object" do
61
- template = Tilt::MustacheTemplate.new('foo.mustache') { "<p>Hey {{foo}}!</p>" }
62
- scope = Object.new
63
- scope.instance_variable_set(:@foo, 'Jane!')
64
- assert_equal "<p>Hey Jane!!</p>", template.render(scope)
65
- end
66
- end
67
-
68
- rescue LoadError => boom
69
- warn "Tilt::MustacheTemplate (disabled)\n"
70
- end