tilt 0.7 → 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/COPYING +1 -1
- data/README.md +47 -4
- data/Rakefile +7 -24
- data/TEMPLATES.md +70 -54
- data/bin/tilt +45 -16
- data/lib/tilt.rb +236 -163
- data/test/contest.rb +68 -0
- data/test/tilt_compilesite_test.rb +28 -4
- data/test/tilt_erbtemplate_test.rb +18 -1
- data/test/tilt_erubistemplate_test.rb +43 -0
- data/test/tilt_hamltemplate_test.rb +11 -0
- data/test/tilt_radiustemplate_test.rb +66 -0
- data/test/tilt_sasstemplate_test.rb +2 -2
- data/test/tilt_stringtemplate_test.rb +1 -1
- data/test/tilt_template_test.rb +19 -1
- data/test/tilt_test.rb +9 -1
- data/tilt.gemspec +10 -7
- metadata +41 -13
- data/test/tilt_coffeetemplate_test.rb +0 -20
- data/test/tilt_mustache_views/external.rb +0 -9
- data/test/tilt_mustachetemplate_test.rb +0 -70
data/COPYING
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (c)
|
|
1
|
+
Copyright (c) 2010 Ryan Tomayko <http://tomayko.com/about>
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
4
|
of this software and associated documentation files (the "Software"), to
|
data/README.md
CHANGED
|
@@ -13,7 +13,8 @@ feature is relevant to the engine):
|
|
|
13
13
|
* Ability to pass locals to template evaluation
|
|
14
14
|
* Support for passing a block to template evaluation for "yield"
|
|
15
15
|
* Backtraces with correct filenames and line numbers
|
|
16
|
-
* Template
|
|
16
|
+
* Template file caching and reloading
|
|
17
|
+
* Fast, method-based template source compilation
|
|
17
18
|
|
|
18
19
|
The primary goal is to get all of the things listed above right for all
|
|
19
20
|
template engines included in the distribution.
|
|
@@ -29,9 +30,10 @@ Support for these template engines is included with the package:
|
|
|
29
30
|
Less CSS .less less
|
|
30
31
|
Builder .builder builder
|
|
31
32
|
Liquid .liquid liquid
|
|
32
|
-
Mustache .mustache mustache
|
|
33
33
|
RDiscount .markdown rdiscount
|
|
34
34
|
RedCloth .textile redcloth
|
|
35
|
+
RDoc .rdoc rdoc
|
|
36
|
+
Radius .radius radius
|
|
35
37
|
|
|
36
38
|
See [TEMPLATES.md][t] for detailed information on template engine
|
|
37
39
|
options and supported features.
|
|
@@ -145,8 +147,49 @@ Or, use BlueCloth for markdown instead of RDiscount:
|
|
|
145
147
|
|
|
146
148
|
Tilt.register 'markdown', Tilt::BlueClothTemplate
|
|
147
149
|
|
|
150
|
+
Template Compilation
|
|
151
|
+
--------------------
|
|
152
|
+
|
|
153
|
+
Tilt can compile generated Ruby source code produced by template engines and
|
|
154
|
+
reuse on subsequent template invocations. Benchmarks show this yields a 5x-10x
|
|
155
|
+
performance increase over evaluating the Ruby source on each invocation.
|
|
156
|
+
|
|
157
|
+
Template compilation is currently supported for these template engines:
|
|
158
|
+
StringTemplate, ERB, Erubis, Haml, and Builder.
|
|
159
|
+
|
|
160
|
+
To enable template compilation, the `Tilt::CompileSite` module must be mixed in
|
|
161
|
+
to the scope object passed to the template's `#render` method. This can be
|
|
162
|
+
accomplished by including (with `Module#include`) the module in the class used
|
|
163
|
+
for scope objects or by extending (with `Object#extend`) scope objects before
|
|
164
|
+
passing to `Template#render`:
|
|
165
|
+
|
|
166
|
+
require 'tilt'
|
|
167
|
+
|
|
168
|
+
template = Tilt::ERBTemplate.new('foo.erb')
|
|
169
|
+
|
|
170
|
+
# Slow. Uses Object#instance_eval to process template
|
|
171
|
+
class Scope
|
|
172
|
+
end
|
|
173
|
+
scope = Scope.new
|
|
174
|
+
template.render(scope)
|
|
175
|
+
|
|
176
|
+
# Fast. Uses compiled template and Object#send to process template
|
|
177
|
+
class Scope
|
|
178
|
+
include Tilt::CompileSite
|
|
179
|
+
end
|
|
180
|
+
scope = Scope.new
|
|
181
|
+
template.render(scope)
|
|
182
|
+
|
|
183
|
+
# Also fast, though a bit a slower due to having to extend each time
|
|
184
|
+
scope = Object.new
|
|
185
|
+
scope.extend Tilt::CompileSite
|
|
186
|
+
template.render(scope)
|
|
187
|
+
|
|
188
|
+
When the `Tilt::CompileSite` module is not present, template execution falls
|
|
189
|
+
back to evaluating the template from source on each invocation.
|
|
190
|
+
|
|
148
191
|
LICENSE
|
|
149
192
|
-------
|
|
150
193
|
|
|
151
|
-
Tilt is Copyright (c)
|
|
152
|
-
distributed under the MIT license. See the COPYING file for more info.
|
|
194
|
+
Tilt is Copyright (c) 2010 [Ryan Tomayko](http://tomayko.com/about) and
|
|
195
|
+
distributed under the MIT license. See the `COPYING` file for more info.
|
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 = ['-
|
|
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
|
-
#### `:
|
|
98
|
-
|
|
99
|
-
Delete spaces around '<% %>'. (But, spaces around '<%= %>' are preserved.)
|
|
96
|
+
#### `:engine_class => Erubis::Eruby`
|
|
100
97
|
|
|
101
|
-
|
|
98
|
+
Allows you to specify a custom engine class to use instead of the
|
|
99
|
+
default which is `Erubis::Eruby`.
|
|
102
100
|
|
|
103
|
-
|
|
101
|
+
#### `:escape_html => false`
|
|
104
102
|
|
|
105
|
-
|
|
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/bin/tilt
CHANGED
|
@@ -3,17 +3,21 @@ require 'ostruct'
|
|
|
3
3
|
require 'optparse'
|
|
4
4
|
require 'tilt'
|
|
5
5
|
|
|
6
|
-
usage = <<
|
|
7
|
-
Usage: tilt
|
|
8
|
-
Process template
|
|
9
|
-
is '-', read template from stdin and use the --type option
|
|
10
|
-
the template's type.
|
|
6
|
+
usage = <<USAGE
|
|
7
|
+
Usage: tilt <options> <file>
|
|
8
|
+
Process template <file> and write output to stdout. With no <file> or
|
|
9
|
+
when <file> is '-', read template from stdin and use the --type option
|
|
10
|
+
to determine the template's type.
|
|
11
11
|
|
|
12
12
|
Options
|
|
13
|
-
-l, --list List
|
|
14
|
-
-t, --type
|
|
13
|
+
-l, --list List template engines + file patterns and exit
|
|
14
|
+
-t, --type=<pattern> Use this template engine; required if no <file>
|
|
15
|
+
-y, --layout=<file> Use <file> as a layout template
|
|
15
16
|
|
|
16
|
-
-
|
|
17
|
+
-D<name>=<value> Define variable <name> as <value>
|
|
18
|
+
-o, --vars=<ruby> Evaluate <ruby> to Hash and use for variables
|
|
19
|
+
|
|
20
|
+
-h, --help Show this help message
|
|
17
21
|
|
|
18
22
|
Convert markdown to HTML:
|
|
19
23
|
$ tilt foo.markdown > foo.html
|
|
@@ -21,11 +25,18 @@ Convert markdown to HTML:
|
|
|
21
25
|
Process ERB template:
|
|
22
26
|
$ echo "Answer: <%= 2 + 2 %>" | tilt -t erb
|
|
23
27
|
Answer: 4
|
|
24
|
-
|
|
28
|
+
|
|
29
|
+
Define variables:
|
|
30
|
+
$ echo "Answer: <%= 2 + n %>" | tilt --locals="{:n=>40, :x=>0}"
|
|
31
|
+
Answer: 42
|
|
32
|
+
$ echo "Answer: <%= 2 + n %>" | tilt -Dn=40 -Dx=0
|
|
33
|
+
Answer: 42
|
|
34
|
+
USAGE
|
|
25
35
|
|
|
26
36
|
script_name = File.basename($0)
|
|
27
37
|
pattern = nil
|
|
28
38
|
layout = nil
|
|
39
|
+
locals = {}
|
|
29
40
|
|
|
30
41
|
ARGV.options do |o|
|
|
31
42
|
o.program_name = script_name
|
|
@@ -44,18 +55,31 @@ ARGV.options do |o|
|
|
|
44
55
|
end
|
|
45
56
|
|
|
46
57
|
# the template type / pattern
|
|
47
|
-
o.on("-t", "--type=PATTERN") do |val|
|
|
48
|
-
|
|
58
|
+
o.on("-t", "--type=PATTERN", String) do |val|
|
|
59
|
+
abort "unknown template type: #{val}" if Tilt[val].nil?
|
|
49
60
|
pattern = val
|
|
50
61
|
end
|
|
51
62
|
|
|
52
63
|
# pass template output into the specified layout template
|
|
53
|
-
o.on("-y", "--layout=FILE") do |file|
|
|
64
|
+
o.on("-y", "--layout=FILE", String) do |file|
|
|
54
65
|
paths = [file, "~/.tilt/#{file}", "/etc/tilt/#{file}"]
|
|
55
66
|
layout = paths.
|
|
56
67
|
map { |p| File.expand_path(p) }.
|
|
57
68
|
find { |p| File.exist?(p) }
|
|
58
|
-
|
|
69
|
+
abort "no such layout: #{file}" if layout.nil?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# define a local variable
|
|
73
|
+
o.on("-D", "--define=PAIR", String) do |pair|
|
|
74
|
+
key, value = pair.split(/[=:]/, 2)
|
|
75
|
+
locals[key.to_sym] = value
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# define local variables using a Ruby hash
|
|
79
|
+
o.on("--vars=RUBY") do |ruby|
|
|
80
|
+
hash = eval(ruby)
|
|
81
|
+
abort "vars must be a Hash, not #{hash.inspect}" if !hash.is_a?(Hash)
|
|
82
|
+
hash.each { |key, value| locals[key.to_sym] = value }
|
|
59
83
|
end
|
|
60
84
|
|
|
61
85
|
o.on_tail("-h", "--help") { puts usage; exit }
|
|
@@ -65,17 +89,22 @@ end
|
|
|
65
89
|
|
|
66
90
|
file = ARGV.first || '-'
|
|
67
91
|
pattern = file if pattern.nil?
|
|
92
|
+
abort "template type not given. see: #{$0} --help" if ['-', ''].include?(pattern)
|
|
93
|
+
|
|
94
|
+
engine = Tilt[pattern]
|
|
95
|
+
abort "template engine not found for: #{pattern}" if engine.nil?
|
|
96
|
+
|
|
68
97
|
template =
|
|
69
|
-
|
|
98
|
+
engine.new(file) {
|
|
70
99
|
if file == '-'
|
|
71
100
|
$stdin.read
|
|
72
101
|
else
|
|
73
102
|
File.read(file)
|
|
74
103
|
end
|
|
75
104
|
}
|
|
76
|
-
output = template.render
|
|
105
|
+
output = template.render(self, locals)
|
|
77
106
|
|
|
78
107
|
# process layout
|
|
79
|
-
output = Tilt.new(layout).render { output } if layout
|
|
108
|
+
output = Tilt.new(layout).render(self, locals) { output } if layout
|
|
80
109
|
|
|
81
110
|
$stdout.write(output)
|