Module: Merb::Template

Defined in:
lib/merb-core/controller/template.rb

Defined Under Namespace

Classes: Erubis

Constant Summary collapse

EXTENSIONS =
{}
METHOD_LIST =
{}
SUPPORTED_LOCALS_LIST =
Hash.new([].freeze)
MTIMES =
{}

Class Method Summary collapse

Class Method Details

.engine_for(path) ⇒ Object

Finds the engine for a particular path.

Parameters

path<String>

The path of the file to find an engine for.

Returns

Class

The engine.

:api: private



153
154
155
156
# File 'lib/merb-core/controller/template.rb', line 153

def engine_for(path)
  path = File.expand_path(path)      
  EXTENSIONS[path.match(/\.([^\.]*)$/)[1]]
end

.inline_template(io, locals = [], mod = Merb::InlineTemplates) ⇒ Object

Takes a template at a particular path and inlines it into a module and adds it to the METHOD_LIST table to speed lookup later.

Parameters

io<#path>

An IO that responds to #path (File or VirtualFile)

locals<Array>

A list of local names that should be assigned in the template method from the arguments hash. Defaults to [].

mod<Module>

The module to put the compiled method into. Defaults to Merb::InlineTemplates

Returns

Symbol

The name of the method that the template was compiled into.

Notes

Even though this method supports inlining into any module, the method must be available to instances of AbstractController that will use it.

:api: private



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/merb-core/controller/template.rb', line 131

def inline_template(io, locals=[], mod = Merb::InlineTemplates)
  full_file_path = File.expand_path(io.path)
  engine_neutral_path = full_file_path.gsub(/\.[^\.]*$/, "")
  
  local_list = (SUPPORTED_LOCALS_LIST[engine_neutral_path] |= locals)
  ret = METHOD_LIST[engine_neutral_path] =
    engine_for(full_file_path).compile_template(io, 
    template_name(full_file_path), local_list, mod)
    
  io.close
  ret
end

.needs_compilation?(path, locals) ⇒ Boolean

Decide if a template needs to be re/compiled.

Parameters

path<String>

The full path of the template to check support for.

locals<Array>

The list of locals that need to be supported

Returns

Boolean

Whether or not the template for the provided path needs to be recompiled

:api: private

Returns:

  • (Boolean)


92
93
94
95
96
97
98
# File 'lib/merb-core/controller/template.rb', line 92

def needs_compilation?(path, locals)
  return true if Merb::Config[:reload_templates] || !METHOD_LIST[path]
  
  current_locals = SUPPORTED_LOCALS_LIST[path]
  current_locals != locals &&
    !(locals - current_locals).empty?
end

.register_extensions(engine, extensions) ⇒ Object

Registers the extensions that will trigger a particular templating engine.

Parameters

engine<Class>

The class of the engine that is being registered

extensions<Array>

The list of extensions that will be registered with this templating language

Raises

ArgumentError

engine does not have a compile_template method.

Returns

nil

Example

Merb::Template.register_extensions(Merb::Template::Erubis, ["erb"])

:api: plugin

Raises:

  • (ArgumentError)


177
178
179
180
181
182
183
184
# File 'lib/merb-core/controller/template.rb', line 177

def register_extensions(engine, extensions) 
  raise ArgumentError, "The class you are registering does not have a compile_template method" unless
    engine.respond_to?(:compile_template)
  extensions.each{|ext| EXTENSIONS[ext] = engine }
  Merb::AbstractController.class_eval <<-HERE
    include #{engine}::Mixin
  HERE
end

.template_extensionsObject

Get all known template extensions

Returns

Array:: Extension strings.

:api: plugin



106
107
108
# File 'lib/merb-core/controller/template.rb', line 106

def template_extensions
  EXTENSIONS.keys
end

.template_for(path, template_stack = [], locals = []) ⇒ Object

Get the name of the template method for a particular path.

Parameters

path<String>

A full path to find a template method for.

template_stack<Array>

The template stack. Not used.

locals<Array>

The names of local variables

Returns

<String>

name of the method that inlines the template.

:api: private



71
72
73
74
75
76
77
78
79
80
# File 'lib/merb-core/controller/template.rb', line 71

def template_for(path, template_stack = [], locals=[])
  path = File.expand_path(path)
  
  if needs_compilation?(path, locals)
    template_io = load_template_io(path)
    METHOD_LIST[path] = inline_template(template_io, locals) if template_io
  end
  
  METHOD_LIST[path]
end

.template_name(path) ⇒ Object

Get the template’s method name from a full path. This replaces non-alphanumeric characters with __ and “.” with “_”

Collisions are potentially possible with something like: ~foo.bar and __foo.bar or !foo.bar.

Parameters

path<String>

A full path to convert to a valid Ruby method name

Returns

String

The template name.

We might want to replace this with something that varies the character replaced based on the non-alphanumeric character to avoid edge-case collisions.

:api: private



30
31
32
33
# File 'lib/merb-core/controller/template.rb', line 30

def template_name(path)
  path = File.expand_path(path)      
  path.gsub(/[^\.a-zA-Z0-9]/, "__").gsub(/\./, "_")
end