diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2005-07-23 06:14:10 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2005-07-23 06:14:10 +0000 |
commit | 7fe3fd23b31b0d4209d4b042f24f26bb0632e08c (patch) | |
tree | 4fec2c20b9312d8ac6a0b4efe40547005739d0bd | |
parent | 98fb9e5093decbaff5aea5fd25de53f2624ecff3 (diff) | |
download | rails-7fe3fd23b31b0d4209d4b042f24f26bb0632e08c.tar.gz rails-7fe3fd23b31b0d4209d4b042f24f26bb0632e08c.tar.bz2 rails-7fe3fd23b31b0d4209d4b042f24f26bb0632e08c.zip |
Extended template caching to rxml and attempted to fix periodical caching issue [Stephan Kaes]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1902 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | actionpack/CHANGELOG | 2 | ||||
-rw-r--r-- | actionpack/lib/action_view/base.rb | 89 |
2 files changed, 50 insertions, 41 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 860c35b768..a9ff040070 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -4,7 +4,7 @@ * Added support for per-action session management #1763 -* Improved rendering speed on complicated templates by up to 25% #1234 [Stephan Kaes]. This did necessasitate a change to the internals of ActionView#render_template that now has four parameters. Developers of custom view handlers (like Amrita) need to update for that. +* Improved rendering speed on complicated templates by up to 100% (the more complex the templates, the higher the speedup) #1234 [Stephan Kaes]. This did necessasitate a change to the internals of ActionView#render_template that now has four parameters. Developers of custom view handlers (like Amrita) need to update for that. * Added options hash as third argument to FormHelper#input, so you can do input('person', 'zip', :size=>10) #1719 [jeremye@bsa.ca.gov] diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index f20620d4f0..9f21f3fe3b 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -118,15 +118,17 @@ module ActionView #:nodoc: # More builder documentation can be found at http://builder.rubyforge.org. class Base include ERB::Util - + attr_reader :first_render attr_accessor :base_path, :assigns, :template_extension attr_accessor :controller - + attr_reader :logger, :params, :response, :session, :headers, :flash - # Turn on to cache the reading of templates from the file system. Doing so means that you have to restart the server - # when changing templates, but that rendering will be faster. + # Turn on to cache the reading of templates from the file system. + # Doing so means that you have to restart the server when changing + # templates, but it will save checking whether the file has changed + # on disk. @@cache_template_loading = false cattr_accessor :cache_template_loading @@ -135,8 +137,8 @@ module ActionView #:nodoc: @@erb_trim_mode = '-' cattr_accessor :erb_trim_mode - @@compiled_erb_templates = {} - @@erb_count = 0 + @@compiled_templates = {} + @@template_count = 0 @@loaded_templates = {} @@template_handlers = {} @@ -165,7 +167,7 @@ module ActionView #:nodoc: # is made available as local variables. def render_file(template_path, use_full_path = true, local_assigns = {}) @first_render = template_path if @first_render.nil? - + if use_full_path template_extension = pick_template_extension(template_path) template_file_name = full_template_path(template_path, template_extension) @@ -173,7 +175,7 @@ module ActionView #:nodoc: template_file_name = template_path template_extension = template_path.split('.').last end - + template_source = read_template_file(template_file_name, template_extension) begin @@ -187,7 +189,7 @@ module ActionView #:nodoc: end end end - + # Renders the template present at <tt>template_path</tt> (relative to the template_root). # The hash in <tt>local_assigns</tt> is made available as local variables. def render(options = {}, old_local_assigns = {}) @@ -196,7 +198,7 @@ module ActionView #:nodoc: elsif options.is_a?(Hash) options[:locals] ||= {} options[:use_full_path] = options[:use_full_path].nil? ? true : options[:use_full_path] - + if options[:file] render_file(options[:file], options[:use_full_path], options[:locals]) elsif options[:partial] && options[:collection] @@ -208,7 +210,7 @@ module ActionView #:nodoc: end end end - + # Renders the +template+ which is given as a string as either rhtml or rxml depending on <tt>template_extension</tt>. # The hash in <tt>local_assigns</tt> is made available as local variables. def render_template(template_extension, template, file_name = nil, local_assigns = {}) @@ -232,7 +234,7 @@ module ActionView #:nodoc: raise ActionViewError, "No rhtml, rxml, or delegate template found for #{template_path}" end end - + def delegate_template_exists?(template_path)#:nodoc: @@template_handlers.find { |k,| template_exists?(template_path, k) } end @@ -271,70 +273,77 @@ module ActionView #:nodoc: !@@cache_template_loading ) if read_file @@loaded_templates[template_path] = info = File.read(template_path) - @@compiled_erb_templates[template_path] = nil if 'rhtml' == extension + @@compiled_templates[template_path] = nil end info end def evaluate_assigns(local_assigns = {}) - @assigns.each { |key, value| instance_variable_set "@#{key}", value } + @assigns.each { |key, value| instance_variable_set("@#{key}", value) } saved_locals = {} local_assigns.each do |key, value| varstr = "@_#{key}_" - saved_locals[varstr] = instance_variable_get varstr - instance_variable_set varstr, value - unless self.respond_to? key - self.class.class_eval "def #{key}; #{varstr}; end" - self.class.class_eval "def #{key}=(v); #{varstr} = v; end" + saved_locals[varstr] = instance_variable_get(varstr) + instance_variable_set(varstr, value) + unless self.respond_to?(key) + self.class.class_eval("def #{key}; #{varstr}; end") + self.class.class_eval("def #{key}=(v); #{varstr} = v; end") end end saved_locals end - def compile_erb_template(template, file_name) + def compile_template(extension, template, file_name) cache_name = file_name || template - - unless @@compiled_erb_templates[cache_name] - erb = ERB.new(template, nil, @@erb_trim_mode) - erb_name = 'run_erb_' + unless @@compiled_templates[cache_name] + t_name, t_arg, t_code = nil + case extension + when :rhtml + t_name = 'run_html_' + t_arg = '' + t_code = ERB.new(template, nil, @@erb_trim_mode).src + when :rxml + t_name = 'run_xml_' + t_arg = '(xml)' + t_code = template + end if file_name i = file_name.index(@base_path) l = @base_path.length s_file_name = i ? file_name[i+l+1,file_name.length-l-1] : file_name - s_file_name.sub!(/.rhtml$/,'') + s_file_name.sub!(/(.rhtml|.rxml)$/,'') s_file_name.tr!('/:-', '_') s_file_name.gsub!(/[^a-zA-Z0-9_]/){|s| s[0].to_s} - erb_name += s_file_name + t_name += s_file_name else - @@erb_count += 1 - erb_name += @@erb_count.to_s + @@template_count += 1 + t_name += @@template_count.to_s end - erb_def = "def #{erb_name}; #{erb.src}; end" - eval erb_def rescue raise ActionViewError, "ERROR defining #{erb_name}: #{erb_def}" + t_def = "def #{t_name}#{t_arg}; #{t_code}; end" + self.class.class_eval(t_def) rescue raise ActionViewError, "ERROR defining #{t_name}: #{t_def}" - @@compiled_erb_templates[cache_name] = erb_name.intern + @@compiled_templates[cache_name] = t_name.intern @@loaded_templates[cache_name] = Time.now if file_name - logger.debug "Compiled erb template #{cache_name}\n ==> #{erb_name}" if logger + logger.info "Compiled template #{cache_name}\n ==> #{t_name}" if logger end - - @@compiled_erb_templates[cache_name] + @@compiled_templates[cache_name] end def rhtml_render(extension, template, file_name, local_assigns) - render_sym = compile_erb_template(template, file_name) + render_sym = compile_template(:rhtml, template, file_name) saved_locals = evaluate_assigns(local_assigns) result = self.send(render_sym) - saved_locals.each { |k,v| instance_variable_set(k, v) } + saved_locals.each{ |k,v| instance_variable_set(k, v) } result end def rxml_render(extension, template, file_name, local_assigns) @controller.headers["Content-Type"] ||= 'text/xml' + render_sym = compile_template(:rxml, template, file_name) saved_locals = evaluate_assigns(local_assigns) - xml = Builder::XmlMarkup.new(:indent => 2) - result = eval(template, binding, '(template)(eval)', 1) - saved_locals.each { |k,v| instance_variable_set(k,v) } + result = self.send(render_sym, Builder::XmlMarkup.new(:indent => 2)) + saved_locals.each{ |k,v| instance_variable_set(k, v) } result end @@ -344,4 +353,4 @@ module ActionView #:nodoc: end end -require 'action_view/template_error' +require 'action_view/template_error'
\ No newline at end of file |