Super speed boost! Like, I'm talking ZOOM! The patch was written by Tom Bagby and modified by myself to make it a bit leaner. The basic idea is that instead of caching the compiled template as a string of Ruby code, we cache it as a compiled method. This means that caching doesn't have to be done Template-side, which also means the :precompiled option now doesn't do anything. I don't think anyone used it anyway, though, so we're all good.
git-svn-id: svn://hamptoncatlin.com/haml/trunk@504 7063305b-7217-0410-af8c-cdc13e5119b9
This commit is contained in:
parent
568051434c
commit
3736c8b7e9
|
@ -635,10 +635,6 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|||
# evaluated. If this is true, said scripts are
|
||||
# rendered as empty strings. Defaults to false.
|
||||
#
|
||||
# [<tt>:precompiled</tt>] A string containing a precompiled Haml template.
|
||||
# If this is passed, <tt>template</tt> is ignored
|
||||
# and no precompilation is done.
|
||||
#
|
||||
# [<tt>:attr_wrapper</tt>] The character that should wrap element attributes.
|
||||
# This defaults to <tt>'</tt> (an apostrophe). Characters
|
||||
# of this type within the attributes will be escaped
|
||||
|
|
|
@ -151,8 +151,6 @@ END
|
|||
end
|
||||
@options[:filters].rec_merge! options[:filters] if options[:filters]
|
||||
|
||||
@precompiled = @options[:precompiled]
|
||||
|
||||
@template = template.strip #String
|
||||
@to_close_stack = []
|
||||
@output_tabs = 0
|
||||
|
@ -166,7 +164,7 @@ END
|
|||
begin
|
||||
# Only do the first round of pre-compiling if we really need to.
|
||||
# They might be passing in the precompiled string.
|
||||
do_precompile if @precompiled.nil? && (@precompiled = String.new)
|
||||
do_precompile unless @@method_names[@template]
|
||||
rescue Haml::Error => e
|
||||
e.add_backtrace_entry(@index, @options[:filename])
|
||||
raise e
|
||||
|
@ -185,6 +183,12 @@ END
|
|||
# Compile the @precompiled buffer
|
||||
compile &block
|
||||
|
||||
if @buffer.buffer.empty?
|
||||
if @options[:filename]
|
||||
raise @template.inspect
|
||||
end
|
||||
end
|
||||
|
||||
# Return the result string
|
||||
@buffer.buffer
|
||||
end
|
||||
|
@ -195,8 +199,10 @@ END
|
|||
|
||||
#Precompile each line
|
||||
def do_precompile
|
||||
@precompiled = ''
|
||||
method_name = assign_method_name(@template, options[:filename])
|
||||
push_silent <<-END
|
||||
def _haml_render
|
||||
def #{method_name}
|
||||
@haml_is_haml = true
|
||||
_hamlout = @haml_stack[-1]
|
||||
_erbout = _hamlout.buffer
|
||||
|
@ -369,6 +375,22 @@ END
|
|||
line && line.length > 1 && line[-1] == MULTILINE_CHAR_VALUE && line[-2] == 32
|
||||
end
|
||||
|
||||
# Method for generating compiled method names basically ripped out of ActiveView::Base
|
||||
# If Haml is to be used as a standalone module without rails and still use the precompiled
|
||||
# methods technique, it will end up duplicating this stuff. I can't decide whether
|
||||
# checking compile times to decide whether to recompile a template belongs in here or
|
||||
# out in template.rb
|
||||
@@method_names = {}
|
||||
@@render_method_count = 0
|
||||
def assign_method_name(template, file_name)
|
||||
@@render_method_count += 1
|
||||
@@method_names[template] = "_render_haml_#{@@render_method_count}".intern
|
||||
end
|
||||
|
||||
module CompiledTemplates
|
||||
# holds compiled template code
|
||||
end
|
||||
|
||||
# Takes <tt>@precompiled</tt>, a string buffer of Ruby code, and
|
||||
# evaluates it in the context of <tt>@scope_object</tt>, after preparing
|
||||
# <tt>@scope_object</tt>. The code in <tt>@precompiled</tt> populates
|
||||
|
@ -385,11 +407,21 @@ END
|
|||
attr :haml_lineno # :nodoc:
|
||||
end
|
||||
end
|
||||
@scope_object.class.instance_eval do
|
||||
include CompiledTemplates
|
||||
end
|
||||
|
||||
begin
|
||||
# Evaluate the buffer in the context of the scope object
|
||||
@scope_object.instance_eval @precompiled
|
||||
@scope_object._haml_render &block
|
||||
if false#options[:filename]
|
||||
method_name = @@method_names[options[:filename]]
|
||||
else
|
||||
method_name = @@method_names[@template]
|
||||
end
|
||||
|
||||
unless @scope_object.respond_to?(method_name)
|
||||
CompiledTemplates.module_eval @precompiled
|
||||
end
|
||||
@scope_object.send(method_name, &block)
|
||||
rescue Exception => e
|
||||
class << e
|
||||
include Haml::Error
|
||||
|
|
|
@ -40,7 +40,6 @@ module Haml
|
|||
# to render its templates.
|
||||
def initialize(view)
|
||||
@view = view
|
||||
@@precompiled_templates ||= {}
|
||||
end
|
||||
|
||||
# Renders the file at the location <tt>template</tt>,
|
||||
|
@ -60,13 +59,7 @@ module Haml
|
|||
engine = Haml::Engine.new(template, options)
|
||||
else
|
||||
options[:filename] ||= template
|
||||
if @precompiled = get_precompiled(template)
|
||||
options[:precompiled] ||= @precompiled
|
||||
engine = Haml::Engine.new("", options)
|
||||
else
|
||||
engine = Haml::Engine.new(File.read(template), options)
|
||||
set_precompiled(template, engine.precompiled)
|
||||
end
|
||||
end
|
||||
|
||||
yield_proc = @view.instance_eval do
|
||||
|
@ -76,24 +69,6 @@ module Haml
|
|||
engine.to_html(@view) { |*args| yield_proc.call(*args) }
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Gets the cached, precompiled version of the template at location <tt>filename</tt>
|
||||
# as a string.
|
||||
def get_precompiled(filename)
|
||||
# Do we have it on file? Is it new enough?
|
||||
if (precompiled, precompiled_on = @@precompiled_templates[filename]) &&
|
||||
(precompiled_on == File.mtime(filename).to_i)
|
||||
precompiled
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the cached, precompiled version of the template at location <tt>filename</tt>
|
||||
# to <tt>precompiled</tt>.
|
||||
def set_precompiled(filename, precompiled)
|
||||
@@precompiled_templates[filename] = [precompiled, File.mtime(filename).to_i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -81,23 +81,6 @@ class EngineTest < Test::Unit::TestCase
|
|||
assert_equal("<p>Paragraph!</p>\n", render("%p= text", :locals => { :text => "Paragraph!" }))
|
||||
end
|
||||
|
||||
def test_precompiled
|
||||
precompiled = <<-END
|
||||
def _haml_render
|
||||
_hamlout = @haml_stack[-1]
|
||||
_erbout = _hamlout.buffer
|
||||
|
||||
_hamlout.open_tag("p", 0, nil, true, "", nil, nil, false)
|
||||
@haml_lineno = 1
|
||||
haml_temp = "Haml Rocks Socks"
|
||||
haml_temp = _hamlout.push_script(haml_temp, 1, false)
|
||||
_hamlout.close_tag("p", 0)
|
||||
end
|
||||
END
|
||||
|
||||
assert_equal("<p>Haml Rocks Socks</p>\n", render("%h1 I shall not be rendered", :precompiled => precompiled))
|
||||
end
|
||||
|
||||
def test_comps
|
||||
assert_equal(-1, "foo" <=> nil)
|
||||
assert_equal(1, nil <=> "foo")
|
||||
|
|
Loading…
Reference in New Issue