Class: Tilt::Mapping
- Inherits:
-
BaseMapping
- Object
- BaseMapping
- Tilt::Mapping
- Defined in:
- lib/tilt/mapping.rb
Overview
Tilt::Mapping associates file extensions with template implementations.
mapping = Tilt::Mapping.new
mapping.register(Tilt::RDocTemplate, 'rdoc')
mapping['index.rdoc'] # => Tilt::RDocTemplate
mapping.new('index.rdoc').render
You can use #register to register a template class by file extension, #registered? to see if a file extension is mapped, BaseMapping#[] to lookup template classes, and BaseMapping#new to instantiate template objects.
Mapping also supports lazy template implementations. Note that regularly registered template implementations always have preference over lazily registered template implementations. You should use #register if you depend on a specific template implementation and #register_lazy if there are multiple alternatives.
mapping = Tilt::Mapping.new
mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
mapping['index.md']
# => RDiscount::Template
#register_lazy takes a class name, a filename, and a list of file extensions. When you try to lookup a template name that matches the file extension, Tilt will automatically try to require the filename and constantize the class name.
Unlike #register, there can be multiple template implementations registered lazily to the same file extension. Tilt will attempt to load the template implementations in order (registered last would be tried first), returning the first which doesn’t raise LoadError.
If all of the registered template implementations fails, Tilt will raise the exception of the first, since that was the most preferred one.
mapping = Tilt::Mapping.new
mapping.register_lazy('Maruku::Template', 'maruku/template', 'md')
mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
mapping['index.md']
# => RDiscount::Template
In the previous example we say that RDiscount has a *higher priority* than Maruku. Tilt will first try to ‘require “rdiscount/template”`, falling back to `require “maruku/template”`. If none of these are successful, the first error will be raised.
Constant Summary collapse
- LOCK =
Mutex.new
Instance Attribute Summary collapse
- #lazy_map ⇒ Object readonly
- #template_map ⇒ Object readonly
Instance Method Summary collapse
-
#extensions_for(template_class) ⇒ Object
Finds the extensions the template class has been registered under.
-
#finalized ⇒ Object
Return a finalized mapping.
-
#initialize ⇒ Mapping
constructor
A new instance of Mapping.
- #initialize_copy(other) ⇒ Object
-
#register(template_class, *extensions) ⇒ void
Registers a template implementation by file extension.
-
#register_lazy(class_name, file, *extensions) ⇒ void
Registers a lazy template implementation by file extension.
-
#register_pipeline(ext, options = EMPTY_HASH) ⇒ void
Register a new template class using the given extension that represents a pipeline of multiple existing template, where the output from the previous template is used as input to the next template.
-
#registered?(ext) ⇒ Boolean
Checks if a file extension is registered (either eagerly or lazily) in this mapping.
-
#unregister(*extensions) ⇒ Object
Unregisters an extension.
Constructor Details
#initialize ⇒ Mapping
Returns a new instance of Mapping.
131 132 133 134 |
# File 'lib/tilt/mapping.rb', line 131 def initialize @template_map = Hash.new @lazy_map = Hash.new { |h, k| h[k] = [] } end |
Instance Attribute Details
#lazy_map ⇒ Object (readonly)
129 130 131 |
# File 'lib/tilt/mapping.rb', line 129 def lazy_map @lazy_map end |
#template_map ⇒ Object (readonly)
129 130 131 |
# File 'lib/tilt/mapping.rb', line 129 def template_map @template_map end |
Instance Method Details
#extensions_for(template_class) ⇒ Object
Finds the extensions the template class has been registered under.
287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/tilt/mapping.rb', line 287 def extensions_for(template_class) res = [] LOCK.synchronize{@template_map.to_a}.each do |ext, klass| res << ext if template_class == klass end LOCK.synchronize{@lazy_map.to_a}.each do |ext, choices| res << ext if LOCK.synchronize{choices.dup}.any? { |klass, file| template_class.to_s == klass } end res.uniq! res end |
#finalized ⇒ Object
Return a finalized mapping. A finalized mapping will only include support for template libraries already loaded, and will not allow registering new template libraries or lazy loading template libraries not yet loaded. Finalized mappings improve performance by not requiring synchronization and ensure that the mapping will not attempt to load additional files (useful when restricting file system access after template libraries in use are loaded).
151 152 153 154 155 156 157 158 |
# File 'lib/tilt/mapping.rb', line 151 def finalized LOCK.synchronize{@lazy_map.dup}.each do |pattern, classes| register_defined_classes(LOCK.synchronize{classes.map(&:first)}, pattern) end # Check if a template class is already present FinalizedMapping.new(LOCK.synchronize{@template_map.dup}.freeze) end |
#initialize_copy(other) ⇒ Object
137 138 139 140 141 142 |
# File 'lib/tilt/mapping.rb', line 137 def initialize_copy(other) LOCK.synchronize do @template_map = other.template_map.dup @lazy_map = other.lazy_map.dup end end |
#register(template_class, *extensions) ⇒ void
This method returns an undefined value.
Registers a template implementation by file extension. There can only be one template implementation per file extension, and this method will override any existing mapping.
200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/tilt/mapping.rb', line 200 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| ext = ext.to_s LOCK.synchronize do @template_map[ext] = template_class end end end |
#register_lazy(class_name, file, *extensions) ⇒ void
This method returns an undefined value.
Registers a lazy template implementation by file extension. You can have multiple lazy template implementations defined on the same file extension, in which case the template implementation defined last will be attempted loaded first.
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/tilt/mapping.rb', line 176 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 v = [class_name, file].freeze extensions.each do |ext| LOCK.synchronize{@lazy_map[ext].unshift(v)} end end |
#register_pipeline(ext, options = EMPTY_HASH) ⇒ void
This method returns an undefined value.
Register a new template class using the given extension that represents a pipeline of multiple existing template, where the output from the previous template is used as input to the next template.
This will register a template class that processes the input with the erb template processor, and takes the output of that and feeds it to the scss template processor, returning the output of the scss template processor as the result of the pipeline.
238 239 240 241 242 243 244 245 246 247 |
# File 'lib/tilt/mapping.rb', line 238 def register_pipeline(ext, =EMPTY_HASH) templates = [:templates] || ext.split('.').reverse templates = templates.map{|t| [self[t], [t] || EMPTY_HASH]} klass = Class.new(Pipeline) klass.send(:const_set, :TEMPLATES, templates) register(klass, ext, *Array([:extra_exts])) klass end |
#registered?(ext) ⇒ Boolean
Checks if a file extension is registered (either eagerly or lazily) in this mapping.
280 281 282 283 |
# File 'lib/tilt/mapping.rb', line 280 def registered?(ext) ext_downcase = ext.downcase LOCK.synchronize{@template_map.has_key?(ext_downcase)} or lazy?(ext) end |
#unregister(*extensions) ⇒ Object
Unregisters an extension. This removes the both normal registrations and lazy registrations.
260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/tilt/mapping.rb', line 260 def unregister(*extensions) extensions.each do |ext| ext = ext.to_s LOCK.synchronize do @template_map.delete(ext) @lazy_map.delete(ext) end end nil end |