Class: Clamsy::Tenjin::Engine
- Inherits:
-
Object
- Object
- Clamsy::Tenjin::Engine
- Defined in:
- lib/clamsy/tenjin.rb
Overview
engine class for templates
Engine class supports the followings.
-
template caching
-
partial template
-
layout template
-
capturing (experimental)
ex. file ‘ex_list.rbhtml’
<ul>
{? for item in @items ?}
<li>#{item}</li>
{? end ?}
</ul>
ex. file ‘ex_layout.rbhtml’
<html>
<body>
<h1>${@title}</li>
#{@_content}
{? import 'footer.rbhtml' ?}
</body>
</html>
ex. file ‘main.rb’
require 'tenjin'
= {:prefix=>'ex_', :postfix=>'.rbhtml', :layout=>'ex_layout.rbhtml'}
engine = Tenjin::Engine.new()
context = {:title=>'Tenjin Example', :items=>['foo', 'bar', 'baz']}
output = engine.render(:list, context) # or 'ex_list.rbhtml'
print output
Instance Method Summary collapse
- #cachename(filename) ⇒ Object
-
#create_template(filename, _context = nil) ⇒ Object
create template object from file.
-
#find_template_file(template_name) ⇒ Object
find template filename.
-
#get_template(template_name, _context = nil) ⇒ Object
get template object.
- #hook_context(context) ⇒ Object
-
#initialize(options = {}) ⇒ Engine
constructor
initializer of Engine class.
-
#load_cachefile(cache_filename, template) ⇒ Object
load template from cache file.
-
#read_template_file(filename, _context) ⇒ Object
read template file and preprocess it.
-
#register_template(template_name, template) ⇒ Object
register template object.
-
#render(template_name, context = Context.new, layout = true) ⇒ Object
get template object and evaluate it with context object.
-
#store_cachefile(cache_filename, template) ⇒ Object
store template into cache file.
-
#to_filename(template_name) ⇒ Object
convert short name into filename (ex. ‘:list’ => ‘template/list.rb.html’).
Constructor Details
#initialize(options = {}) ⇒ Engine
initializer of Engine class.
options:
- :prefix
-
prefix string for template name (ex. ‘template/’)
- :postfix
-
postfix string for template name (ex. ‘.rbhtml’)
- :layout
-
layout template name (default nil)
- :path
-
array of directory name (default nil)
- :cache
-
save converted ruby code into file or not (default true)
- :path
-
list of directory (default nil)
- :preprocess
-
flag to activate preprocessing (default nil)
- :templateclass
-
template class object (default Tenjin::Template)
829 830 831 832 833 834 835 836 837 838 839 |
# File 'lib/clamsy/tenjin.rb', line 829 def initialize(={}) @prefix = [:prefix] || '' @postfix = [:postfix] || '' @layout = [:layout] @cache = .fetch(:cache, true) @path = [:path] @preprocess = .fetch(:preprocess, nil) @templateclass = .fetch(:templateclass, Template) @init_opts_for_template = @templates = {} # filename->template end |
Instance Method Details
#cachename(filename) ⇒ Object
881 882 883 |
# File 'lib/clamsy/tenjin.rb', line 881 def cachename(filename) return (filename + '.cache').untaint end |
#create_template(filename, _context = nil) ⇒ Object
create template object from file
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 |
# File 'lib/clamsy/tenjin.rb', line 886 def create_template(filename, _context=nil) template = @templateclass.new(nil, @init_opts_for_template) template. = Time.now() cache_filename = cachename(filename) _context = hook_context(Context.new) if _context.nil? if !@cache input = read_template_file(filename, _context) template.convert(input, filename) elsif !test(?f, cache_filename) || File.mtime(cache_filename) < File.mtime(filename) #$stderr.puts "*** debug: load original" input = read_template_file(filename, _context) template.convert(input, filename) store_cachefile(cache_filename, template) else #$stderr.puts "*** debug: load cache" template.filename = filename load_cachefile(cache_filename, template) end return template end |
#find_template_file(template_name) ⇒ Object
find template filename
848 849 850 851 852 853 854 855 856 857 858 859 |
# File 'lib/clamsy/tenjin.rb', line 848 def find_template_file(template_name) filename = to_filename(template_name) if @path for dir in @path filepath = "#{dir}#{File::SEPARATOR}#{filename}" return filepath if test(?f, filepath.untaint) end else return filename if test(?f, filename.dup.untaint) # dup is required for frozen string end raise Errno::ENOENT.new("#{filename} (path=#{@path.inspect})") end |
#get_template(template_name, _context = nil) ⇒ Object
get template object
926 927 928 929 930 931 932 933 934 935 |
# File 'lib/clamsy/tenjin.rb', line 926 def get_template(template_name, _context=nil) template = @templates[template_name] t = template unless t && t. && t.filename && t. >= File.mtime(t.filename) filename = find_template_file(template_name) template = create_template(filename, _context) # _context is passed only for preprocessor register_template(template_name, template) end return template end |
#hook_context(context) ⇒ Object
963 964 965 966 967 968 969 970 971 972 |
# File 'lib/clamsy/tenjin.rb', line 963 def hook_context(context) if !context context = Context.new elsif context.is_a?(Hash) context = Context.new(context) end context._engine = self context._layout = nil return context end |
#load_cachefile(cache_filename, template) ⇒ Object
load template from cache file
917 918 919 920 921 922 923 |
# File 'lib/clamsy/tenjin.rb', line 917 def load_cachefile(cache_filename, template) s = File.read(cache_filename) if s.sub!(/\A\#\@ARGS (.*?)\r?\n/, '') template.args = $1.split(',') end template.script = s end |
#read_template_file(filename, _context) ⇒ Object
read template file and preprocess it
862 863 864 865 866 867 868 869 870 871 872 873 |
# File 'lib/clamsy/tenjin.rb', line 862 def read_template_file(filename, _context) return File.read(filename) if !@preprocess _context ||= {} _context = hook_context(_context) if _context.is_a?(Hash) || _context._engine.nil? _buf = _context._buf _context._buf = "" begin return Preprocessor.new(filename).render(_context) ensure _context._buf = _buf end end |
#register_template(template_name, template) ⇒ Object
register template object
876 877 878 879 |
# File 'lib/clamsy/tenjin.rb', line 876 def register_template(template_name, template) #template.timestamp = Time.new unless template.timestamp @templates[template_name] = template end |
#render(template_name, context = Context.new, layout = true) ⇒ Object
get template object and evaluate it with context object. if argument ‘layout’ is true then default layout file (specified at initializer) is used as layout template, else if false then no layout template is used. if argument ‘layout’ is string, it is regarded as layout template name.
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 |
# File 'lib/clamsy/tenjin.rb', line 942 def render(template_name, context=Context.new, layout=true) #context = Context.new(context) if context.is_a?(Hash) context = hook_context(context) while true template = get_template(template_name, context) # context is passed only for preprocessor _buf = context._buf output = template.render(context) context._buf = _buf unless context._layout.nil? layout = context._layout context._layout = nil end layout = @layout if layout == true or layout.nil? break unless layout template_name = layout layout = false context.instance_variable_set('@_content', output) end return output end |
#store_cachefile(cache_filename, template) ⇒ Object
store template into cache file
908 909 910 911 912 913 914 |
# File 'lib/clamsy/tenjin.rb', line 908 def store_cachefile(cache_filename, template) s = template.script s = "\#@ARGS #{template.args.join(',')}\n#{s}" if template.args tmp_filename = "#{cache_filename}.#{rand()}" File.open(tmp_filename, 'w') {|f| f.write(s) } File.rename(tmp_filename, cache_filename) end |
#to_filename(template_name) ⇒ Object
convert short name into filename (ex. ‘:list’ => ‘template/list.rb.html’)
842 843 844 845 |
# File 'lib/clamsy/tenjin.rb', line 842 def to_filename(template_name) name = template_name return name.is_a?(Symbol) ? "#{@prefix}#{name}#{@postfix}" : name end |