meta_erb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ module MetaERB
2
+
3
+ class MissingTemplate < Exception
4
+ def initialize(path)
5
+ super("Missing template file at path: #{path}")
6
+ end
7
+ end
8
+
9
+ class TemplateNotSpecified < Exception
10
+ def initialize
11
+ super("No template option given")
12
+ end
13
+ end
14
+
15
+ class TemplateNotFound < Exception
16
+ def initialize(name)
17
+ super("No template found with name: #{name}")
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,27 @@
1
+ module MetaERB
2
+ class MetaTemplate
3
+
4
+ def initialize(content, *args)
5
+ @content = content
6
+ @proc_store = {}
7
+ @args = args
8
+ end
9
+
10
+ # Evaluates the DSL in @content and renders an ERB template.
11
+ #
12
+ # @return [String] The ERB template source.
13
+ def evaluate
14
+ MetaERB::ScopeEvaluator.new(self, ::GlobalScope, ::TopScope).evaluate(@content, *@args)
15
+ end
16
+
17
+ def yield_proc(proc=nil, &block)
18
+ proc ||= block
19
+ if Numeric === proc
20
+ @proc_store[proc]
21
+ else
22
+ @proc_store[proc.object_id] = proc
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+
2
+ module MetaERB
3
+ module Rails
4
+ class Handler < ActionView::TemplateHandler
5
+
6
+ include ::ActionView::TemplateHandlers::Compilable
7
+
8
+ ##
9
+ # :singleton-method:
10
+ # Specify trim mode for the ERB compiler. Defaults to '-'.
11
+ # See ERb documentation for suitable values.
12
+ cattr_accessor :erb_trim_mode
13
+ self.erb_trim_mode = '-'
14
+
15
+ cattr_accessor :meta_templates
16
+ self.meta_templates = {}
17
+
18
+ def compile(template)
19
+ meta_template = MetaERB::MetaTemplate.new(template.source, template.path)
20
+ meta_templates[template.path] = meta_template
21
+ src = ::ERB.new("<% __in_erb_template=true ; @meta_template = MetaERB::Rails::Handler.meta_templates[#{template.path.inspect}] %>#{meta_template.evaluate}", nil, erb_trim_mode, '@output_buffer').src
22
+
23
+ # Ruby 1.9 prepends an encoding to the source. However this is
24
+ # useless because you can only set an encoding on the first line
25
+ RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,86 @@
1
+ module MetaERB
2
+
3
+ # evaluate a scope
4
+ class ScopeEvaluator
5
+
6
+ def initialize(meta_template, *scopes)
7
+ @meta_template = meta_template
8
+
9
+ scopes.flatten.compact.uniq.each do |scope|
10
+ metaclass.send :include, scope
11
+ end
12
+ end
13
+
14
+ def evaluate(code=nil, *args, &block)
15
+ code ||= block
16
+
17
+ @__output = ""
18
+ case code
19
+ when Proc
20
+ if code.respond_to? :bind
21
+ code.bind(self).call
22
+ else
23
+ instance_eval(&code)
24
+ end
25
+ when String
26
+ instance_eval(code, *args)
27
+ end
28
+ output = @__output
29
+ @__output = nil
30
+ return output
31
+ end
32
+
33
+ def concat(string)
34
+ @__output.concat(string)
35
+ end
36
+
37
+ # @param [Hash] options the options of the render operation.
38
+ # @option options [String,Symbol] :template The name of the template to render.
39
+ # @raise [MetaERB::TemplateNotSpecified] if not template name is given.
40
+ # @raise [MetaERB::TemplateNotFound] if no template was found with the given name.
41
+ def render(options={})
42
+ template_name = options.delete(:template)
43
+ raise MetaERB::TemplateNotSpecified.new unless template_name
44
+
45
+ template = MetaERB::TemplateStore.shared.template(template_name)
46
+ raise MetaERB::TemplateNotFound.new(template_name) unless template
47
+
48
+ concat template.evaluate(__template_binding)
49
+ end
50
+
51
+ def render_scoped(*scopes, &block)
52
+ ivars = scopes.pop if Hash === scopes.last
53
+ scope = scoped(*scopes)
54
+ scope.set(ivars) if ivars
55
+ scope.evaluate(&block)
56
+ end
57
+
58
+ def set(options={})
59
+ options.each do |k,v|
60
+ instance_variable_set("@#{k}", v)
61
+ end
62
+ self
63
+ end
64
+
65
+ def scoped(*scopes)
66
+ MetaERB::ScopeEvaluator.new(@meta_template, *scopes)
67
+ end
68
+
69
+ def yield_proc(proc=nil, &block)
70
+ proc ||= block
71
+ @meta_template.yield_proc(proc)
72
+ "@meta_template.yield_proc(#{proc.object_id}).bind(self)"
73
+ end
74
+
75
+ private
76
+
77
+ def __template_binding
78
+ binding
79
+ end
80
+
81
+ def metaclass
82
+ (class << self ; self ; end)
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,28 @@
1
+ module MetaERB
2
+ class Template
3
+
4
+ attr_reader :name, :path
5
+
6
+ def initialize(name, path)
7
+ path = File.expand_path(path)
8
+
9
+ raise MetaERB::MissingTemplate.new(path) unless File.file?(path)
10
+
11
+ @name = name.to_sym
12
+ @path = path
13
+
14
+ template = File.read(path)
15
+
16
+ @erb = ERB.new(template)
17
+ @erb.filename = path
18
+ end
19
+
20
+ def evaluate(binding)
21
+ result = @erb.result(binding)
22
+ result.gsub!('(%', '<%')
23
+ result.gsub!('%)', '%>')
24
+ result
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,62 @@
1
+ module MetaERB
2
+ class TemplateStore
3
+
4
+ def self.shared
5
+ @template_store ||= MetaERB::TemplateStore.new
6
+ end
7
+
8
+ def self.search_in(pattern)
9
+ shared.search_in(pattern)
10
+ end
11
+
12
+ def initialize
13
+ @search_paths = []
14
+ @templates = {}
15
+ @mutex = Mutex.new
16
+ end
17
+
18
+ def search_in(pattern, in_front=true)
19
+ @mutex.synchronize do
20
+ pattern = File.expand_path(pattern)
21
+ unless @search_paths.include?(pattern)
22
+ if in_front
23
+ @search_paths.unshift(pattern)
24
+ else
25
+ @search_paths.push(pattern)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def template(name)
32
+ @mutex.synchronize do
33
+ @templates[name.to_sym] || load_template(name)
34
+ end
35
+ end
36
+
37
+ def reset!
38
+ @mutex.synchronize do
39
+ @templates = {}
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def find_template_path(name)
46
+ @search_paths.each do |pattern|
47
+ paths = Dir.glob(File.join(pattern, "#{name}{.html.erb,.erb,}"))
48
+ next if paths.empty?
49
+ return paths.first
50
+ end
51
+ nil
52
+ end
53
+
54
+ def load_template(name)
55
+ if path = find_template_path(name)
56
+ template = MetaERB::Template.new(name, path)
57
+ @templates[template.name] = template
58
+ end
59
+ end
60
+
61
+ end
62
+ end
data/lib/meta_erb.rb ADDED
@@ -0,0 +1,35 @@
1
+
2
+ $:.unshift(File.expand_path(File.dirname(__FILE__))) unless $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ autoload :ERB, 'erb'
5
+ autoload :Mutex, 'thread'
6
+
7
+ # @author Simon Menke
8
+ module MetaERB
9
+
10
+ autoload :Template, 'meta_erb/template'
11
+ autoload :MetaTemplate, 'meta_erb/meta_template'
12
+ autoload :TemplateStore, 'meta_erb/template_store'
13
+ autoload :ScopeEvaluator, 'meta_erb/scope_evaluator'
14
+
15
+ autoload :MissingTemplate, 'meta_erb/exceptions'
16
+ autoload :TemplateNotFound, 'meta_erb/exceptions'
17
+ autoload :TemplateNotSpecified, 'meta_erb/exceptions'
18
+
19
+ module Rails
20
+ autoload :Handler, 'meta_erb/rails/handler'
21
+ end
22
+
23
+ def self.search_in(pattern)
24
+ MetaERB::TemplateStore.shared.search_in(pattern)
25
+ end
26
+
27
+ def self.load_scopes_in(path)
28
+ path = File.expand_path(path)
29
+ MetaERB.search_in path
30
+ Dir.glob(File.join(path, '*.rb')).each do |scope_path|
31
+ require scope_path
32
+ end
33
+ end
34
+
35
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ ::ActionView::Template.register_default_template_handler :meta, ::MetaERB::Rails::Handler
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ class MetaERBTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+
9
+ test ""
10
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: meta_erb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Simon Menke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-03 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Construct ERB templates from easy DSLs
17
+ email: simon.menke@gmail.com
18
+ engine_dependencies: {}
19
+
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - lib/meta_erb/exceptions.rb
28
+ - lib/meta_erb/meta_template.rb
29
+ - lib/meta_erb/rails/handler.rb
30
+ - lib/meta_erb/scope_evaluator.rb
31
+ - lib/meta_erb/template.rb
32
+ - lib/meta_erb/template_store.rb
33
+ - lib/meta_erb.rb
34
+ - rails/init.rb
35
+ - test/meta_erb_test.rb
36
+ - test/test_helper.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/simonmenke/meta_erb
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.3
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Construct ERB templates from easy DSLs
65
+ test_files:
66
+ - test/meta_erb_test.rb
67
+ - test/test_helper.rb