module BabyErubis::Renderer

Module to define template rendering methods.

ex:

class MyController
  include BabyErubis::HtmlEscaper
  include BabyErubis::Renderer

  ERUBY_PATH      = ['.', 'templates']
  ERUBY_LAYOUT    = :_layout
  ERUBY_HTML      = BabyErubis::Html
  ERUBY_HTML_EXT  = '.html.eruby'
  ERUBY_TEXT      = BabyErubis::Text
  ERUBY_TEXT_EXT  = '.eruby'
  ERUBY_CACHE     = {}

  def index
    @items = ['A', 'B', 'C']
    ## renders 'templates/welcome.html.eruby'
    html = eruby_render_html(:welcome)
    return html
  end

end

Notice:

eruby_render_html(:welcome)              # render 'welcome.html.eruby'
eruby_render_html('welcome')             # render 'welcome'
eruby_render_html('welcome.html.eruby')  # render 'welcome.html.eruby'

Constants

ERUBY_CACHE
ERUBY_HTML
ERUBY_HTML_EXT
ERUBY_LAYOUT
ERUBY_PATH
ERUBY_TEXT
ERUBY_TEXT_EXT

Public Instance Methods

eruby_render_html(template_name, layout: true, encoding: 'utf-8') click to toggle source
# File lib/baby_erubis/renderer.rb, line 53
def eruby_render_html(template_name, layout: true, encoding: 'utf-8')
  ext        = self.class.const_get :ERUBY_HTML_EXT
  tmpl_class = self.class.const_get :ERUBY_HTML
  return _eruby_render_template(template_name, layout) {|tmpl_name|
    filename = tmpl_name.is_a?(Symbol) ? "#{tmpl_name}#{ext}" : tmpl_name
    _eruby_find_template(filename) {|fpath|
      tmpl_class.new.from_file(fpath, encoding)
    }
  }
end
eruby_render_text(template_name, layout: false, encoding: 'utf-8') click to toggle source
# File lib/baby_erubis/renderer.rb, line 64
def eruby_render_text(template_name, layout: false, encoding: 'utf-8')
  ext        = self.class.const_get :ERUBY_TEXT_EXT
  tmpl_class = self.class.const_get :ERUBY_TEXT
  return _eruby_render_template(template_name, layout) {|tmpl_name|
    filename = tmpl_name.is_a?(Symbol) ? "#{tmpl_name}#{ext}" : tmpl_name
    _eruby_find_template(filename) {|fpath|
      tmpl_class.new.from_file(fpath, encoding)
    }
  }
end

Private Instance Methods

_eruby_find_template(filename) { |fpath| ... } click to toggle source
# File lib/baby_erubis/renderer.rb, line 77
def _eruby_find_template(filename)
  cache = self.class.const_get :ERUBY_CACHE
  paths = self.class.const_get :ERUBY_PATH
  dir =  paths.find {|path| cache.key?("#{path}/#{filename}") } \
      || paths.find {|path| File.file?("#{path}/#{filename}") }  or
    raise BabyErubis::TemplateError.new("#{filename}: template not found in #{paths.inspect}.")
  fpath = "#{dir}/#{filename}"
  #
  now = Time.now
  template = _eruby_load_template(cache, fpath, now)
  unless template
    mtime = File.mtime(fpath)
    template = yield fpath
    ## retry when file timestamp changed during template loading
    unless mtime == (mtime2 = File.mtime(fpath))
      mtime = mtime2
      template = yield fpath
      mtime == File.mtime(fpath)  or
        raise "#{fpath}: timestamp changes too frequently. something wrong."
    end
    _eruby_store_template(cache, fpath, template, mtime, now)
  end
  return template
end
_eruby_load_template(cache, fpath, now) click to toggle source
# File lib/baby_erubis/renderer.rb, line 102
def _eruby_load_template(cache, fpath, now)
  tuple = cache[fpath]
  template, timestamp, last_checked = tuple
  return nil unless template
  ## skip timestamp check in order to reduce syscall (= File.mtime())
  interval = now - last_checked
  return template if interval < 0.5
  ## check timestamp only for 5% request in order to avoid thundering herd
  return template if interval < 1.0 && rand() > 0.05
  ## update last_checked in cache when file timestamp is not changed
  if timestamp == File.mtime(fpath)
    tuple[2] = now
    return template
  ## remove cache entry when file timestamp is changed
  else
    cache[fpath] = nil
    return nil
  end
end
_eruby_render_template(template_name, layout) { |template_name| ... } click to toggle source
# File lib/baby_erubis/renderer.rb, line 126
def _eruby_render_template(template_name, layout)
  template = yield template_name
  s = template.render(self)
  unless @_layout.nil?
    layout = @_layout; @_layout = nil
  end
  while layout
    layout = self.class.const_get :ERUBY_LAYOUT if layout == true
    template = yield layout
    @_content = s
    s = template.render(self)
    @_content = nil
    layout = @_layout; @_layout = nil
  end
  return s
end
_eruby_store_template(cache, fpath, template, timestamp, last_checked) click to toggle source
# File lib/baby_erubis/renderer.rb, line 122
def _eruby_store_template(cache, fpath, template, timestamp, last_checked)
  cache[fpath] = [template, timestamp, last_checked]
end