Module: Frank::Render

Included in:
Base, Output
Defined in:
lib/frank/base.rb,
lib/frank/base.rb

Constant Summary collapse

TMPL_EXTS =
{ 
  :html => %w[haml erb rhtml builder liquid mustache textile md mkd markdown],
  :css  => %w[sass less scss]
}
LAYOUT_EXTS =
%w[.haml .erb .rhtml .liquid .mustache]

Instance Method Summary collapse

Instance Method Details

#ext_from_handler(extension) ⇒ Object

lookup the original ext for given template path TODO: make non-ugly



158
159
160
161
162
163
164
# File 'lib/frank/base.rb', line 158

def ext_from_handler(extension)
  orig_ext = nil
  TMPL_EXTS.each do |ext, engines|
    orig_ext = ext.to_s if engines.include? extension[1..-1]
  end
  orig_ext
end

#layout_ext_or_first(layout_exts, ext) ⇒ Object

if the given ext is a layout ext, pop it off and return it otherwise return the first layout ext



197
198
199
# File 'lib/frank/base.rb', line 197

def layout_ext_or_first(layout_exts, ext)
  layout_exts.include?(ext) ? layout_exts.delete(ext) : layout_exts.first
end

#layout_for(path) ⇒ Object

reverse walks the layouts folder until we find a layout returns nil if layout is not found



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/frank/base.rb', line 169

def layout_for(path)
  layout_exts = LAYOUT_EXTS.dup
  ext         = File.extname(path)
  default     = 'default' << layout_ext_or_first(layout_exts, ext)
  file_path   = path.sub(/\/[\w-]+\.[\w-]+$/, '')
  folders     = file_path.split('/')
        
  until File.exist? File.join(@proj_dir, @layouts_folder, folders, default)
    break if layout_exts.empty? && folders.empty?
    
    if layout_exts.empty?
      layout_exts = LAYOUT_EXTS.dup
      default = 'default' << layout_ext_or_first(layout_exts, ext)
      folders.pop
    else
      default = 'default' << layout_exts.shift
    end
  end
  
  if File.exists? File.join(@proj_dir, @layouts_folder, folders, default)
    File.join(folders, default)
  else
    nil
  end
end

#render(path, partial = false, local_vars = nil) ⇒ Object

render request path or template path



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/frank/base.rb', line 92

def render(path, partial = false, local_vars = nil)
  @current_path = path unless partial
  
  # normalize the path
  path.sub!(/^\/?(.*)$/, '/\1')
  path.sub!(/\/$/, '/index.html')
  path.sub!(/(\/[\w-]+)$/, '\1.html')
  path = to_file_path(path) if defined? @request or path.match(/\/_[^\/]+$/)
  
  # regex for kinds that don't support meta
  # and define the meta delimiter
  nometa, delimiter  = /\/_|\.(sass|less)$/, /^META-{3,}\s*$|^-{3,}META\s*$/
  
  # set the layout
  layout = path.match(nometa) ? nil : layout_for(path)
  
  template_path = File.join(@proj_dir, @dynamic_folder, path)
  raise Frank::TemplateError, "Template not found #{template_path}" unless File.exist? template_path
  
  # read in the template
  # check for meta and parse it if it exists
  template        = File.read(template_path) << "\n"
  ext             = File.extname(path)
  template, meta  = template.split(delimiter).reverse
  locals          = parse_meta_and_set_locals(meta, local_vars)

  # use given layout if defined as a meta field
  layout = locals[:layout] == 'nil' ? nil : locals[:layout] if locals.has_key?(:layout)
  
  # let tilt determine the template handler
  # and return some template markup
  if layout.nil?
    tilt(ext, template, locals)
  else
    layout_path = File.join(@proj_dir, @layouts_folder, layout)
    # add layout_path to locals
    raise Frank::TemplateError, "Layout not found #{layout_path}" unless File.exist? layout_path
    
    tilt(File.extname(layout), layout_path, locals) do
      tilt(ext, template, locals)
    end          
  end
end

#tilt(ext, source, locals = {}, &block) ⇒ Object

setup an object and extend it with TemplateHelpers and Render then send everything to tilt and get some template markup back



203
204
205
206
207
208
209
210
211
# File 'lib/frank/base.rb', line 203

def tilt(ext, source, locals={}, &block)
  obj = Object.new.extend(TemplateHelpers).extend(Render)
  instance_variables.each do |var|
    unless ['@response', '@env'].include? var
      obj.instance_variable_set(var.intern, instance_variable_get(var))
    end
  end
  Tilt[ext].new(source).render(obj, locals=locals, &block)
end

#to_file_path(path) ⇒ Object

converts a request path to a template path



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/frank/base.rb', line 137

def to_file_path(path)
  file_name = File.basename(path, File.extname(path))
  file_ext  = File.extname(path).sub(/^\./, '')
  folder    = File.join(@proj_dir, @dynamic_folder)
  engine    = nil
  
  TMPL_EXTS.each do |ext, engines|
    if ext.to_s == file_ext
      engine = engines.reject do |eng|
        !File.exist? File.join(folder, path.sub(/\.[\w-]+$/, ".#{eng}"))
      end.first          
    end
  end
  
  raise Frank::TemplateError, "Template not found #{path}" if engine.nil?
  
  path.sub(/\.[\w-]+$/, ".#{engine}")
end