Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 488 lines (414 sloc) 15.843 kb
137cd54 Ryan Tomayko Tilt!
authored
1 module Tilt
5a3017b Magnus Holm fix TOPOBJECT under MRI < 1.9.2
judofyr authored
2 TOPOBJECT = defined?(BasicObject) ? BasicObject : Object
d479395 Ryan Tomayko 1.2.2 release
authored
3 VERSION = '1.2.2'
531c141 Ryan Tomayko add Tilt::VERSION and update gemspec
authored
4
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
5 @preferred_mappings = Hash.new
4a89f7a Magnus Holm Add fallback support
judofyr authored
6 @template_mappings = Hash.new { |h, k| h[k] = [] }
137cd54 Ryan Tomayko Tilt!
authored
7
b748424 Ryan Tomayko misc doc comment fixes
authored
8 # Hash of template path pattern => template implementation class mappings.
c9b44a8 Ryan Tomayko Tilt.mappings exposes the file pattern -> class mappings Hash
authored
9 def self.mappings
10 @template_mappings
11 end
12
e11fef2 Magnus Holm Tilt.register: Switch order of extensions and template_class
judofyr authored
13 def self.normalize(ext)
14 ext.to_s.downcase.sub(/^\./, '')
15 end
16
137cd54 Ryan Tomayko Tilt!
authored
17 # Register a template implementation by file extension.
e11fef2 Magnus Holm Tilt.register: Switch order of extensions and template_class
judofyr authored
18 def self.register(template_class, *extensions)
19 if template_class.respond_to?(:to_str)
20 # Support register(ext, template_class) too
21 ext = template_class
22 template_class = extensions[0]
23 extensions = [ext]
24 end
25
26 extensions.each do |ext|
27 ext = normalize(ext)
28 mappings[ext].unshift(template_class).uniq!
29 end
137cd54 Ryan Tomayko Tilt!
authored
30 end
57dba70 Joshua Peek Cleanup whitespace
josh authored
31
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
32 # Makes a template class preferred for the given file extensions. If you
33 # don't provide any extensions, it will be preferred for all its already
34 # registered extensions:
57dba70 Joshua Peek Cleanup whitespace
josh authored
35 #
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
36 # # Prefer RDiscount for its registered file extensions:
37 # Tilt.prefer(Tilt::RDiscountTemplate)
38 #
39 # # Prefer RDiscount only for the .md extensions:
40 # Tilt.prefer(Tilt::RDiscountTemplate, '.md')
41 def self.prefer(template_class, *extensions)
42 if extensions.empty?
43 mappings.each do |ext, klass|
44 @preferred_mappings[ext] = template_class
45 end
46 else
47 extensions.each do |ext|
e11fef2 Magnus Holm Tilt.register: Switch order of extensions and template_class
judofyr authored
48 ext = normalize(ext)
49 register(template_class, ext)
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
50 @preferred_mappings[ext] = template_class
4a89f7a Magnus Holm Add fallback support
judofyr authored
51 end
52 end
53 end
57dba70 Joshua Peek Cleanup whitespace
josh authored
54
779c398 Justin Knowlden Adding a comment about what to expect from Tilt.registered?
gus authored
55 # Returns true when a template exists on an exact match of the provided file extension
00ce3f7 Justin Knowlden Cleaned up Tilt[](ext) method because the redundancy was bothering me. B...
gus authored
56 def self.registered?(ext)
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
57 mappings.key?(ext.downcase) && !mappings[ext.downcase].empty?
00ce3f7 Justin Knowlden Cleaned up Tilt[](ext) method because the redundancy was bothering me. B...
gus authored
58 end
59
137cd54 Ryan Tomayko Tilt!
authored
60 # Create a new template for the given file using the file's extension
61 # to determine the the template mapping.
62 def self.new(file, line=nil, options={}, &block)
7587c3d Ryan Tomayko allow templates to be registered for full paths
authored
63 if template_class = self[file]
137cd54 Ryan Tomayko Tilt!
authored
64 template_class.new(file, line, options, &block)
65 else
66 fail "No template engine registered for #{File.basename(file)}"
67 end
68 end
69
b748424 Ryan Tomayko misc doc comment fixes
authored
70 # Lookup a template class for the given filename or file
137cd54 Ryan Tomayko Tilt!
authored
71 # extension. Return nil when no implementation is found.
7587c3d Ryan Tomayko allow templates to be registered for full paths
authored
72 def self.[](file)
00ce3f7 Justin Knowlden Cleaned up Tilt[](ext) method because the redundancy was bothering me. B...
gus authored
73 pattern = file.to_s.downcase
4a89f7a Magnus Holm Add fallback support
judofyr authored
74 until pattern.empty? || registered?(pattern)
00ce3f7 Justin Knowlden Cleaned up Tilt[](ext) method because the redundancy was bothering me. B...
gus authored
75 pattern = File.basename(pattern)
57dba70 Joshua Peek Cleanup whitespace
josh authored
76 pattern.sub!(/^[^.]*\.?/, '')
137cd54 Ryan Tomayko Tilt!
authored
77 end
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
78
79 # Try to find a preferred engine.
80 klass = @preferred_mappings[pattern]
81 return klass if klass
82
83 # Fall back to the general list of mappings.
4a89f7a Magnus Holm Add fallback support
judofyr authored
84 klasses = @template_mappings[pattern]
57dba70 Joshua Peek Cleanup whitespace
josh authored
85
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
86 # Try to find an engine which is already loaded.
4a89f7a Magnus Holm Add fallback support
judofyr authored
87 template = klasses.detect do |klass|
88 if klass.respond_to?(:engine_initialized?)
89 klass.engine_initialized?
90 end
91 end
57dba70 Joshua Peek Cleanup whitespace
josh authored
92
4a89f7a Magnus Holm Add fallback support
judofyr authored
93 return template if template
57dba70 Joshua Peek Cleanup whitespace
josh authored
94
4a89f7a Magnus Holm Add fallback support
judofyr authored
95 # Try each of the classes until one succeeds. If all of them fails,
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
96 # we'll raise the error of the first class.
4a89f7a Magnus Holm Add fallback support
judofyr authored
97 first_failure = nil
57dba70 Joshua Peek Cleanup whitespace
josh authored
98
4a89f7a Magnus Holm Add fallback support
judofyr authored
99 klasses.each do |klass|
100 begin
101 klass.new { '' }
102 rescue Exception => ex
103 first_failure ||= ex
104 next
105 else
106 return klass
107 end
108 end
57dba70 Joshua Peek Cleanup whitespace
josh authored
109
7b3aaa2 Magnus Holm Move preferred mappings to its own hash
judofyr authored
110 raise first_failure if first_failure
137cd54 Ryan Tomayko Tilt!
authored
111 end
5574a00 Ryan Tomayko whitespace errors
authored
112
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
113 # Deprecated module.
4b91c5d Ryan Tomayko shared Tilt::CompileSite mixin instead of passing site to new
authored
114 module CompileSite
52ed26c Ryan Tomayko Tilt.enable_global_compile_site! - USE AT YOUR OWN RISK
authored
115 end
116
137cd54 Ryan Tomayko Tilt!
authored
117 # Base class for template implementations. Subclasses must implement
50cb223 Jacek Becela The real typo fix.
ncr authored
118 # the #prepare method and one of the #evaluate or #precompiled_template
137cd54 Ryan Tomayko Tilt!
authored
119 # methods.
93cc8fb Ryan Tomayko Rename "AbstractTemplate" to just "Template"
authored
120 class Template
51ef07e Ryan Tomayko Minor doc additions
authored
121 # Template source; loaded from a file or given directly.
137cd54 Ryan Tomayko Tilt!
authored
122 attr_reader :data
123
124 # The name of the file where the template data was loaded from.
125 attr_reader :file
126
127 # The line number in #file where template data was loaded from.
128 attr_reader :line
129
130 # A Hash of template engine specific options. This is passed directly
131 # to the underlying engine and is not used by the generic template
132 # interface.
133 attr_reader :options
134
b82adf2 Ryan Tomayko misc cleanup of initialize_engine related methods
authored
135 # Used to determine if this class's initialize_engine method has
136 # been called yet.
137 @engine_initialized = false
138 class << self
139 attr_accessor :engine_initialized
140 alias engine_initialized? engine_initialized
90fdb05 Joshua Peek Add Template.default_mime_type
josh authored
141
142 attr_accessor :default_mime_type
b82adf2 Ryan Tomayko misc cleanup of initialize_engine related methods
authored
143 end
144
137cd54 Ryan Tomayko Tilt!
authored
145 # Create a new template with the file, line, and options specified. By
ad91ea1 Ryan Tomayko all Template.new args are optional and may be given in any order
authored
146 # default, template data is read from the file. When a block is given,
147 # it should read template data and return as a String. When file is nil,
148 # a block is required.
54a8604 Ryan Tomayko Template#initialize_engine - called first use of template class
authored
149 #
ad91ea1 Ryan Tomayko all Template.new args are optional and may be given in any order
authored
150 # All arguments are optional.
137cd54 Ryan Tomayko Tilt!
authored
151 def initialize(file=nil, line=1, options={}, &block)
4b91c5d Ryan Tomayko shared Tilt::CompileSite mixin instead of passing site to new
authored
152 @file, @line, @options = nil, 1, {}
ad91ea1 Ryan Tomayko all Template.new args are optional and may be given in any order
authored
153
4b91c5d Ryan Tomayko shared Tilt::CompileSite mixin instead of passing site to new
authored
154 [options, line, file].compact.each do |arg|
ad91ea1 Ryan Tomayko all Template.new args are optional and may be given in any order
authored
155 case
156 when arg.respond_to?(:to_str) ; @file = arg.to_str
157 when arg.respond_to?(:to_int) ; @line = arg.to_int
e9575c9 Geoff Buesing Template#initialize: dup options hash so that we don't modify it in-plac...
gbuesing authored
158 when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
ad91ea1 Ryan Tomayko all Template.new args are optional and may be given in any order
authored
159 else raise TypeError
160 end
161 end
162
163 raise ArgumentError, "file or block required" if (@file || block).nil?
54a8604 Ryan Tomayko Template#initialize_engine - called first use of template class
authored
164
b82adf2 Ryan Tomayko misc cleanup of initialize_engine related methods
authored
165 # call the initialize_engine method if this is the very first time
166 # an instance of this class has been created.
167 if !self.class.engine_initialized?
54a8604 Ryan Tomayko Template#initialize_engine - called first use of template class
authored
168 initialize_engine
169 self.class.engine_initialized = true
170 end
3baad66 Ryan Tomayko load template in initializer instead of on first render
authored
171
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
172 # used to hold compiled template methods
173 @compiled_method = {}
a69686d Ryan Tomayko tighten up compiled method names a bit
authored
174
20a7ce7 Konstantin Haase Allow passing in a :default_encoding option with the encoding that is us...
rkh authored
175 # used on 1.9 to set the encoding if it is not set elsewhere (like a magic comment)
176 # currently only used if template compiles to ruby
177 @default_encoding = @options.delete :default_encoding
178
179 # load template data and prepare (uses binread to avoid encoding issues)
180 @reader = block || lambda { |t| File.respond_to?(:binread) ? File.binread(@file) : File.read(@file) }
3baad66 Ryan Tomayko load template in initializer instead of on first render
authored
181 @data = @reader.call(self)
92c64d8 Ryan Tomayko the #compile! method is now known as #prepare
authored
182 prepare
54a8604 Ryan Tomayko Template#initialize_engine - called first use of template class
authored
183 end
184
c1cb0de Ryan Tomayko Template#compile method is like #compile! but runs once
authored
185 # Render the template in the given scope with the locals specified. If a
186 # block is given, it is typically available within the template via
187 # +yield+.
188 def render(scope=Object.new, locals={}, &block)
137cd54 Ryan Tomayko Tilt!
authored
189 evaluate scope, locals || {}, &block
190 end
191
60c8338 Ryan Tomayko Template#basename and Template#name
authored
192 # The basename of the template file.
193 def basename(suffix='')
194 File.basename(file, suffix) if file
195 end
196
197 # The template file's basename with all extensions chomped off.
198 def name
199 basename.split('.', 2).first if basename
200 end
201
137cd54 Ryan Tomayko Tilt!
authored
202 # The filename used in backtraces to describe the template.
203 def eval_file
df02cf8 Ryan Tomayko #eval_file takes subclass #file implementations into account
authored
204 file || '(__TEMPLATE__)'
137cd54 Ryan Tomayko Tilt!
authored
205 end
206
207 protected
b82adf2 Ryan Tomayko misc cleanup of initialize_engine related methods
authored
208 # Called once and only once for each template subclass the first time
209 # the template class is initialized. This should be used to require the
210 # underlying template library and perform any initial setup.
211 def initialize_engine
212 end
213
c8b818a Ryan Tomayko ditto require_template_library
authored
214 # Like Kernel::require but issues a warning urging a manual require when
215 # running under a threaded environment.
216 def require_template_library(name)
217 if Thread.list.size > 1
218 warn "WARN: tilt autoloading '#{name}' in a non thread-safe way; " +
219 "explicit require '#{name}' suggested."
220 end
221 require name
222 end
223
92c64d8 Ryan Tomayko the #compile! method is now known as #prepare
authored
224 # Do whatever preparation is necessary to setup the underlying template
225 # engine. Called immediately after template data is loaded. Instance
226 # variables set in this method are available when #evaluate is called.
51ef07e Ryan Tomayko Minor doc additions
authored
227 #
228 # Subclasses must provide an implementation of this method.
92c64d8 Ryan Tomayko the #compile! method is now known as #prepare
authored
229 def prepare
230 if respond_to?(:compile!)
231 # backward compat with tilt < 0.6; just in case
1882f27 Ryan Tomayko warn if Template subclass implements #compile!
authored
232 warn 'Tilt::Template#compile! is deprecated; implement #prepare instead.'
92c64d8 Ryan Tomayko the #compile! method is now known as #prepare
authored
233 compile!
234 else
235 raise NotImplementedError
236 end
137cd54 Ryan Tomayko Tilt!
authored
237 end
57dba70 Joshua Peek Cleanup whitespace
josh authored
238
c9b496f Magnus Holm Move caching into #cached_evaluate:
judofyr authored
239 def evaluate(scope, locals, &block)
240 cached_evaluate(scope, locals, &block)
241 end
137cd54 Ryan Tomayko Tilt!
authored
242
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
243 # Process the template and return the result. The first time this
244 # method is called, the template source is evaluated with instance_eval.
245 # On the sequential method calls it will compile the template to an
246 # unbound method which will lead to better performance. In any case,
247 # template executation is guaranteed to be performed in the scope object
248 # with the locals specified and with support for yielding to the block.
c9b496f Magnus Holm Move caching into #cached_evaluate:
judofyr authored
249 def cached_evaluate(scope, locals, &block)
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
250 # Redefine itself to use method compilation the next time:
c9b496f Magnus Holm Move caching into #cached_evaluate:
judofyr authored
251 def self.cached_evaluate(scope, locals, &block)
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
252 method = compiled_method(locals.keys)
c9b496f Magnus Holm Move caching into #cached_evaluate:
judofyr authored
253 method.bind(scope).call(locals, &block)
f75a8c9 Ryan Tomayko basic support for compiling templates to methods on a mixin
authored
254 end
5574a00 Ryan Tomayko whitespace errors
authored
255
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
256 # Use instance_eval the first time:
c9b496f Magnus Holm Move caching into #cached_evaluate:
judofyr authored
257 evaluate_source(scope, locals, &block)
137cd54 Ryan Tomayko Tilt!
authored
258 end
259
e801634 Ryan Tomayko make precompiled template source methods more descriptive
authored
260 # Generates all template source by combining the preamble, template, and
261 # postamble and returns a two-tuple of the form: [source, offset], where
262 # source is the string containing (Ruby) source code for the template and
263 # offset is the integer line offset where line reporting should begin.
264 #
265 # Template subclasses may override this method when they need complete
266 # control over source generation or want to adjust the default line
267 # offset. In most cases, overriding the #precompiled_template method is
268 # easier and more appropriate.
269 def precompiled(locals)
270 preamble = precompiled_preamble(locals)
e1100df Hiroshi Ichikawa Fixing Encoding::CompatibilityError with Ruby 1.9 + ERB, by copying magi...
gimite authored
271 template = precompiled_template(locals)
272 magic_comment = extract_magic_comment(template)
273 if magic_comment
274 # Magic comment e.g. "# coding: utf-8" has to be in the first line.
275 # So we copy the magic comment to the first line.
276 preamble = magic_comment + "\n" + preamble
277 end
e801634 Ryan Tomayko make precompiled template source methods more descriptive
authored
278 parts = [
279 preamble,
e1100df Hiroshi Ichikawa Fixing Encoding::CompatibilityError with Ruby 1.9 + ERB, by copying magi...
gimite authored
280 template,
e801634 Ryan Tomayko make precompiled template source methods more descriptive
authored
281 precompiled_postamble(locals)
282 ]
283 [parts.join("\n"), preamble.count("\n") + 1]
284 end
285
286 # A string containing the (Ruby) source code for the template. The
287 # default Template#evaluate implementation requires either this method
288 # or the #precompiled method be overridden. When defined, the base
289 # Template guarantees correct file/line handling, locals support, custom
290 # scopes, and support for template compilation when the scope object
291 # allows it.
292 def precompiled_template(locals)
137cd54 Ryan Tomayko Tilt!
authored
293 raise NotImplementedError
294 end
295
e801634 Ryan Tomayko make precompiled template source methods more descriptive
authored
296 # Generates preamble code for initializing template state, and performing
297 # locals assignment. The default implementation performs locals
298 # assignment only. Lines included in the preamble are subtracted from the
299 # source line offset, so adding code to the preamble does not effect line
300 # reporting in Kernel::caller and backtraces.
301 def precompiled_preamble(locals)
302 locals.map { |k,v| "#{k} = locals[:#{k}]" }.join("\n")
303 end
304
305 # Generates postamble code for the precompiled template source. The
306 # string returned from this method is appended to the precompiled
307 # template source.
308 def precompiled_postamble(locals)
309 ''
137cd54 Ryan Tomayko Tilt!
authored
310 end
b8381e1 Ryan Tomayko require_template_library is private
authored
311
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
312 # The compiled method for the locals keys provided.
313 def compiled_method(locals_keys)
314 @compiled_method[locals_keys] ||=
315 compile_template_method(locals_keys)
f53c491 Ryan Tomayko fix method checks under ruby 1.9 (string vs. symbol)
authored
316 end
317
dceb4a4 Ryan Tomayko document local_assignment_code and move to protected
authored
318 private
7a241ab Ryan Tomayko fix issues with source eval templates under JRuby
authored
319 # Evaluate the template source in the context of the scope object.
320 def evaluate_source(scope, locals, &block)
321 source, offset = precompiled(locals)
322 scope.instance_eval(source, eval_file, line - offset)
323 end
324
325 # JRuby doesn't allow Object#instance_eval to yield to the block it's
326 # closed over. This is by design and (ostensibly) something that will
327 # change in MRI, though no current MRI version tested (1.8.6 - 1.9.2)
328 # exhibits the behavior. More info here:
329 #
330 # http://jira.codehaus.org/browse/JRUBY-2599
331 #
332 # Additionally, JRuby's eval line reporting is off by one compared to
333 # all MRI versions tested.
334 #
335 # We redefine evaluate_source to work around both issues.
336 if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
337 undef evaluate_source
338 def evaluate_source(scope, locals, &block)
339 source, offset = precompiled(locals)
340 file, lineno = eval_file, (line - offset) - 1
341 scope.instance_eval { Kernel::eval(source, binding, file, lineno) }
342 end
343 end
344
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
345 def compile_template_method(locals)
e801634 Ryan Tomayko make precompiled template source methods more descriptive
authored
346 source, offset = precompiled(locals)
20c01a5 Magnus Holm CompileSite constant access fix
judofyr authored
347 offset += 5
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
348 method_name = "__tilt_#{Thread.current.object_id.abs}"
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
349 Object.class_eval <<-RUBY, eval_file, line - offset
59e04a7 Konstantin Haase Add magic comments for encoding to method compilation, too.
rkh authored
350 #{extract_magic_comment source}
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
351 TOPOBJECT.class_eval do
352 def #{method_name}(locals)
353 Thread.current[:tilt_vars] = [self, locals]
354 class << self
355 this, locals = Thread.current[:tilt_vars]
356 this.instance_eval do
357 #{source}
358 end
20c01a5 Magnus Holm CompileSite constant access fix
judofyr authored
359 end
360 end
4c974cf Ryan Tomayko compile template only when compile_site module given
authored
361 end
362 RUBY
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
363 unbind_compiled_method(method_name)
8d857f9 Ryan Tomayko test compiled method garbage collection
authored
364 end
365
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
366 def unbind_compiled_method(method_name)
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
367 method = TOPOBJECT.instance_method(method_name)
368 TOPOBJECT.class_eval { remove_method(method_name) }
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
369 method
f75a8c9 Ryan Tomayko basic support for compiling templates to methods on a mixin
authored
370 end
b05e8da Ryan Tomayko special case template compilation under 1.9.1
authored
371
e1100df Hiroshi Ichikawa Fixing Encoding::CompatibilityError with Ruby 1.9 + ERB, by copying magi...
gimite authored
372 def extract_magic_comment(script)
20a7ce7 Konstantin Haase Allow passing in a :default_encoding option with the encoding that is us...
rkh authored
373 comment = script.slice(/\A[ \t]*\#.*coding\s*[=:]\s*([[:alnum:]\-_]+).*$/)
374 return comment if comment and not %w[ascii-8bit binary].include?($1.downcase)
375 "# coding: #{@default_encoding}" if @default_encoding
e1100df Hiroshi Ichikawa Fixing Encoding::CompatibilityError with Ruby 1.9 + ERB, by copying magi...
gimite authored
376 end
377
b05e8da Ryan Tomayko special case template compilation under 1.9.1
authored
378 # Special case Ruby 1.9.1's broken yield.
379 #
380 # http://github.com/rtomayko/tilt/commit/20c01a5
381 # http://redmine.ruby-lang.org/issues/show/3601
382 #
383 # Remove when 1.9.2 dominates 1.9.1 installs in the wild.
384 if RUBY_VERSION =~ /^1.9.1/
385 undef compile_template_method
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
386 def compile_template_method(locals)
b05e8da Ryan Tomayko special case template compilation under 1.9.1
authored
387 source, offset = precompiled(locals)
388 offset += 1
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
389 method_name = "__tilt_#{Thread.current.object_id}"
975e89b Ryan Tomayko Revert "Revert "Use method compilation for all scopes:""
authored
390 Object.class_eval <<-RUBY, eval_file, line - offset
391 TOPOBJECT.class_eval do
392 def #{method_name}(locals)
393 #{source}
394 end
b05e8da Ryan Tomayko special case template compilation under 1.9.1
authored
395 end
396 RUBY
e840133 Daniel Mendler use unbound methods for compilation (simpler code, no gc necessary)
minad authored
397 unbind_compiled_method(method_name)
b05e8da Ryan Tomayko special case template compilation under 1.9.1
authored
398 end
399 end
137cd54 Ryan Tomayko Tilt!
authored
400 end
401
3435557 Ryan Tomayko better Tilt::Cache with specs
authored
402 # Extremely simple template cache implementation. Calling applications
403 # create a Tilt::Cache instance and use #fetch with any set of hashable
404 # arguments (such as those to Tilt.new):
405 # cache = Tilt::Cache.new
406 # cache.fetch(path, line, options) { Tilt.new(path, line, options) }
407 #
92c64d8 Ryan Tomayko the #compile! method is now known as #prepare
authored
408 # Subsequent invocations return the already loaded template object.
d169230 Ryan Tomayko Dead simple template cache implementation
authored
409 class Cache
410 def initialize
411 @cache = {}
412 end
413
414 def fetch(*key)
415 @cache[key] ||= yield
416 end
417
418 def clear
419 @cache = {}
420 end
421 end
422
2a4b2c0 Ryan Tomayko add erubis, haml, and mustache docs to TEMPLATES.md
authored
423
d169230 Ryan Tomayko Dead simple template cache implementation
authored
424 # Template Implementations ================================================
425
2a4b2c0 Ryan Tomayko add erubis, haml, and mustache docs to TEMPLATES.md
authored
426
137cd54 Ryan Tomayko Tilt!
authored
427 # The template source is evaluated as a Ruby string. The #{} interpolation
428 # syntax can be used to generated dynamic output.
93cc8fb Ryan Tomayko Rename "AbstractTemplate" to just "Template"
authored
429 class StringTemplate < Template
92c64d8 Ryan Tomayko the #compile! method is now known as #prepare
authored
430 def prepare
8bf1532 Magnus Holm allow "}" in StringTemplates (closes #60)
judofyr authored
431 hash = "TILT#{data.hash.abs}"
432 @code = "<<#{hash}.chomp\n#{data}\n#{hash}"
137cd54 Ryan Tomayko Tilt!
authored
433 end
434
e801634 Ryan Tomayko make precompiled template source methods more descriptive
authored
435 def precompiled_template(locals)
137cd54 Ryan Tomayko Tilt!
authored
436 @code
437 end
8bf1532 Magnus Holm allow "}" in StringTemplates (closes #60)
judofyr authored
438
439 def precompiled(locals)
440 source, offset = super
441 [source, offset + 1]
442 end
137cd54 Ryan Tomayko Tilt!
authored
443 end
57dba70 Joshua Peek Cleanup whitespace
josh authored
444
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
445 register StringTemplate, 'str'
bc66c37 Ryan Tomayko ERB and Erubis templates implement new precompiled methods
authored
446
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
447 require 'tilt/erb'
448 register ERBTemplate, 'erb', 'rhtml'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
449 register ErubisTemplate, 'erb', 'rhtml', 'erubis'
47a5407 Dylan Egan ERubis template implementation
dylanegan authored
450
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
451 require 'tilt/haml'
452 register HamlTemplate, 'haml'
2a4b2c0 Ryan Tomayko add erubis, haml, and mustache docs to TEMPLATES.md
authored
453
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
454 require 'tilt/css'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
455 register SassTemplate, 'sass'
456 register ScssTemplate, 'scss'
457 register LessTemplate, 'less'
4d4b933 Ryan Tomayko whitespace error - go stand in the corner benschwarz
authored
458
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
459 require 'tilt/coffee'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
460 register CoffeeScriptTemplate, 'coffee'
4d4b933 Ryan Tomayko whitespace error - go stand in the corner benschwarz
authored
461
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
462 require 'tilt/nokogiri'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
463 register NokogiriTemplate, 'nokogiri'
d2e2601 Aaron Patterson adding nokogiri template support
tenderlove authored
464
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
465 require 'tilt/builder'
466 register BuilderTemplate, 'builder'
7495914 Konstantin Haase rewrite Nokogiri and Builder templates to support method caching
rkh authored
467
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
468 require 'tilt/markaby'
469 register MarkabyTemplate, 'mab'
57dba70 Joshua Peek Cleanup whitespace
josh authored
470
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
471 require 'tilt/liquid'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
472 register LiquidTemplate, 'liquid'
8752db2 Ryan Tomayko Add RDiscountTemplate
authored
473
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
474 require 'tilt/radius'
475 register RadiusTemplate, 'radius'
476
477 require 'tilt/markdown'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
478 register BlueClothTemplate, 'markdown', 'mkd', 'md'
ddff065 Magnus Holm Add Maruku support. Thanks Tim Felgentreff!
judofyr authored
479 register MarukuTemplate, 'markdown', 'mkd', 'md'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
480 register RDiscountTemplate, 'markdown', 'mkd', 'md'
57dba70 Joshua Peek Cleanup whitespace
josh authored
481
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
482 require 'tilt/textile'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
483 register RedClothTemplate, 'textile'
6518ccd added RedCloth
bry4n authored
484
f71bfa5 Magnus Holm Split tilt.rb into several parts
judofyr authored
485 require 'tilt/rdoc'
239057d Magnus Holm tilt.rb: Switch to new register-API
judofyr authored
486 register RDocTemplate, 'rdoc'
137cd54 Ryan Tomayko Tilt!
authored
487 end
Something went wrong with that request. Please try again.