diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1437a31 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2008-2009 Pluron, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README b/README new file mode 100644 index 0000000..3af22ae --- /dev/null +++ b/README @@ -0,0 +1,23 @@ +Template inliner avoids the problem when to render a large list of objects, +Rails creates a large number of View instances, requiring additional CPU and memory +for each of them. + +Example situation: + <% for object in objects %> #1000 times + <%= render :partial => 'object', :locals => { :object => object } %> + <% end %> + + +Template inliner will include the source of the partial into the +template where it's rendered from before Rails starts processing the template. + +To use, just add :inline => true to the 'render' call. +Note, the entire call to render inlined partial must be on the one line for +template inliner to work. + +Example: + <% for object in objects %> #1000 times + <%= render :partial => 'object', :locals => { :object => object }, :inline => true %> + <% end %> + +Copyright (c) 2008-2009 Pluron, Inc. Released under the MIT license. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..83627a8 --- /dev/null +++ b/Rakefile @@ -0,0 +1,22 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test template_inliner plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for template_inliner plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'template_inliner' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end diff --git a/init.rb b/init.rb new file mode 100644 index 0000000..754cc16 --- /dev/null +++ b/init.rb @@ -0,0 +1,3 @@ +# Copyright (c) 2008-2009 Pluron, Inc. + +require 'template_inliner.rb' diff --git a/lib/template_inliner.rb b/lib/template_inliner.rb new file mode 100644 index 0000000..90265af --- /dev/null +++ b/lib/template_inliner.rb @@ -0,0 +1,61 @@ +# Copyright (c) 2008-2009 Pluron, Inc. + +module ActionView + + class Base + # Specify whether templates should be inlined. + # Inlining is turned off by default. + @@inline_templates = false + cattr_accessor :inline_templates + end + + class Template + + alias_method :old_initialize, :initialize + def initialize(template_path, load_path) + @view_storage = {:view => nil} + old_initialize(template_path, load_path) + end + + attr_accessor :view_storage + + def source + if ActionView::Base.inline_templates + read_template_source(filename) + else + File.read(filename) + end + end + + private + def read_template_source(template_path) + contents = "" + File.read(template_path).each_line do |line| + if line =~ /^(.*)<%=\s*render\s+:partial\s*=>\s*['"](.*)['"].*:inline\s*=>\strue\s*-?%>(.*)$/ and view_storage[:view] + template = view_storage[:view].send(:_pick_partial_template, $2) + contents << $1 + contents << template.source + contents << $3 + else + contents << line + end + end + contents + end + end +end + + +module ActionView + module Partials + private + + def _pick_partial_template_with_view_setting(partial_path) + template = _pick_partial_template_without_view_setting(partial_path) + template.view_storage[:view] = self + template + end + alias_method_chain :_pick_partial_template, :view_setting + + end +end