class Tilt::Mapping
the first error will be raised.
back to ‘require “bluecloth/template”`. If none of these are successful,
BlueCloth. Tilt will first try to `require “rdiscount/template”`, falling
In the previous example we say that RDiscount has a *higher priority* than
# => RDiscount::Template
mapping[’index.md’]
mapping.register_lazy(‘RDiscount::Template’, ‘rdiscount/template’, ‘md’)
mapping.register_lazy(‘Bluecloth::Template’, ‘bluecloth/template’, ‘md’)
mapping = Tilt::Mapping.new
the exception of the first, since that was the most preferred one.
If all of the registered template implementations fails, Tilt will raise
returning the first which doesn’t raise LoadError.
template implementations in order (registered last would be tried first),
registered lazily to the same file extension. Tilt will attempt to load the
Unlike {#register}, there can be multiple template implementations
constantize the class name.
file extension, Tilt will automatically try to require the filename and
extensions. When you try to lookup a template name that matches the
{#register_lazy} takes a class name, a filename, and a list of file
# => RDiscount::Template
mapping[‘index.md’]
mapping.register_lazy(‘RDiscount::Template’, ‘rdiscount/template’, ‘md’)
mapping = Tilt::Mapping.new
are multiple alternatives.
depend on a specific template implementation and {#register_lazy} if there
registered template implementations. You should use {#register} if you
registered template implementations always have preference over lazily
Mapping also supports lazy template implementations. Note that regularly
objects.
{#[]} to lookup template classes, and {#new} to instantiate template
extension, {#registered?} to see if a file extension is mapped,
You can use {#register} to register a template class by file<br><br>mapping.new(‘index.rdoc’).render<br>mapping # => Tilt::RDocTemplate
mapping.register(Tilt::RDocTemplate, ‘rdoc’)
mapping = Tilt::Mapping.new
Tilt::Mapping associates file extensions with template implementations.
def [](file)
-
(template class)
-
def [](file) _, ext = split(file) ext && lookup(ext) end
def constant_defined?(name)
def constant_defined?(name) name.split('::').inject(Object) do |scope, n| return false if scope.autoload?(n) # skip autload return false unless scope.const_defined?(n) scope.const_get(n) end end
def extensions_for(template_class)
-
template_class
(template class
) --
def extensions_for(template_class) res = [] template_map.each do |ext, klass| res << ext if template_class == klass end lazy_map.each do |ext, choices| res << ext if choices.any? { |klass, file| template_class.to_s == klass } end res end
def initialize
def initialize @template_map = Hash.new @lazy_map = Hash.new { |h, k| h[k] = [] } end
def initialize_copy(other)
- Private: -
def initialize_copy(other) @template_map = other.template_map.dup @lazy_map = other.lazy_map.dup end
def lazy?(ext)
def lazy?(ext) ext = ext.downcase @lazy_map.has_key?(ext) && !@lazy_map[ext].empty? end
def lazy_load(pattern)
def lazy_load(pattern) return unless @lazy_map.has_key?(pattern) choices = @lazy_map[pattern] # Check if a template class is already present choices.each do |class_name, file| template_class = constant_defined?(class_name) if template_class register(template_class, pattern) return template_class end end first_failure = nil # Load in order choices.each do |class_name, file| begin require file if Thread.list.size > 1 warn "WARN: tilt autoloading '#{file}' in a non thread-safe way; " + "explicit require '#{file}' suggested." end # It's safe to eval() here because constant_defined? will # raise NameError on invalid constant names template_class = eval(class_name) rescue LoadError => ex first_failure ||= ex else register(template_class, pattern) return template_class end end raise first_failure if first_failure end
def lookup(ext)
def lookup(ext) @template_map[ext] || lazy_load(ext) end
def new(file, line=nil, options={}, &block)
- See: Tilt::Template.new -
Raises:
-
(RuntimeError)
- if there is no template class registered for the
def new(file, line=nil, options={}, &block) if template_class = self[file] template_class.new(file, line, options, &block) else fail "No template engine registered for #{File.basename(file)}" end end
def register(template_class, *extensions)
-
(void)
-
Parameters:
-
extensions
(Array
) -- List of extensions. -
template_class
() --
def register(template_class, *extensions) if template_class.respond_to?(:to_str) # Support register(ext, template_class) too extensions, template_class = [template_class], extensions[0] end extensions.each do |ext| @template_map[ext.to_s] = template_class end end
def register_lazy(class_name, file, *extensions)
-
(void)
-
Parameters:
-
extensions
(Array
) -- List of extensions. -
file
(String
) -- Filename where the template class is defined. -
class_name
(String
) -- Class name of a template class.
def register_lazy(class_name, file, *extensions) # Internal API if class_name.is_a?(Symbol) Tilt.autoload class_name, file class_name = "Tilt::#{class_name}" end extensions.each do |ext| @lazy_map[ext].unshift([class_name, file]) end end
def registered?(ext)
-
ext
(String
) -- File extension.
def registered?(ext) @template_map.has_key?(ext.downcase) or lazy?(ext) end
def split(file)
def split(file) pattern = file.to_s.downcase full_pattern = pattern.dup until registered?(pattern) return if pattern.empty? pattern = File.basename(pattern) pattern.sub!(/^[^.]*\.?/, '') end prefix_size = full_pattern.size - pattern.size [full_pattern[0,prefix_size-1], pattern] end
def templates_for(file)
-
(Array)
-
def templates_for(file) templates = [] while true prefix, ext = split(file) break unless ext templates << lookup(ext) file = prefix end templates end