meta_erb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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