pivotal-erector 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +81 -0
- data/VERSION.yml +4 -0
- data/bin/erect +7 -0
- data/lib/erector/erect.rb +148 -0
- data/lib/erector/erected.rb +63 -0
- data/lib/erector/extensions/object.rb +18 -0
- data/lib/erector/indenting.rb +36 -0
- data/lib/erector/rails/extensions/action_controller/1.2.5/action_controller.rb +17 -0
- data/lib/erector/rails/extensions/action_controller/2.2.0/action_controller.rb +26 -0
- data/lib/erector/rails/extensions/action_controller.rb +8 -0
- data/lib/erector/rails/extensions/action_view.rb +21 -0
- data/lib/erector/rails/extensions/widget/1.2.5/widget.rb +18 -0
- data/lib/erector/rails/extensions/widget/2.2.0/widget.rb +36 -0
- data/lib/erector/rails/extensions/widget.rb +117 -0
- data/lib/erector/rails/supported_rails_versions.rb +14 -0
- data/lib/erector/rails/template_handlers/1.2.5/action_view_template_handler.rb +32 -0
- data/lib/erector/rails/template_handlers/2.0.0/action_view_template_handler.rb +36 -0
- data/lib/erector/rails/template_handlers/2.1.0/action_view_template_handler.rb +31 -0
- data/lib/erector/rails/template_handlers/2.2.0/action_view_template_handler.rb +46 -0
- data/lib/erector/rails/template_handlers/action_view_template_handler.rb +14 -0
- data/lib/erector/rails.rb +6 -0
- data/lib/erector/raw_string.rb +8 -0
- data/lib/erector/rhtml.treetop +156 -0
- data/lib/erector/unicode.rb +18185 -0
- data/lib/erector/unicode_builder.rb +67 -0
- data/lib/erector/version.rb +10 -0
- data/lib/erector/widget.rb +510 -0
- data/lib/erector/widgets/table.rb +96 -0
- data/lib/erector/widgets.rb +2 -0
- data/lib/erector.rb +16 -0
- data/spec/core_spec_suite.rb +3 -0
- data/spec/erect/erect_spec.rb +145 -0
- data/spec/erect/erected_spec.rb +80 -0
- data/spec/erect/rhtml_parser_spec.rb +318 -0
- data/spec/erector/indentation_spec.rb +136 -0
- data/spec/erector/unicode_builder_spec.rb +75 -0
- data/spec/erector/widget_spec.rb +657 -0
- data/spec/erector/widgets/table_spec.rb +99 -0
- data/spec/rails_spec_suite.rb +3 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/spec_suite.rb +45 -0
- metadata +118 -0
data/README.txt
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= Erector
|
2
|
+
|
3
|
+
* http://erector.rubyforge.org
|
4
|
+
* mailto:erector-devel@rubyforge.org
|
5
|
+
* http://www.pivotaltracker.com/projects/482
|
6
|
+
|
7
|
+
== DESCRIPTION
|
8
|
+
|
9
|
+
Erector is a Builder-like view framework, inspired by Markaby but overcoming
|
10
|
+
some of its flaws. In Erector all views are objects, not template files,
|
11
|
+
which allows the full power of object-oriented programming (inheritance,
|
12
|
+
modular decomposition, encapsulation) in views. See the rdoc for the
|
13
|
+
Erector::Widget class to learn how to make your own widgets, and visit the
|
14
|
+
project site at http://erector.rubyforge.org for more documentation.
|
15
|
+
|
16
|
+
== SYNOPSIS
|
17
|
+
|
18
|
+
require 'erector'
|
19
|
+
|
20
|
+
class Hello < Erector::Widget
|
21
|
+
def render
|
22
|
+
html do
|
23
|
+
head do
|
24
|
+
title "Hello"
|
25
|
+
end
|
26
|
+
body do
|
27
|
+
text "Hello, "
|
28
|
+
b "world!", :class => 'big'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Hello.new.to_s
|
35
|
+
=> "<html><head><title>Hello</title></head><body>Hello, <b class=\"big\">world!</b></body></html>"
|
36
|
+
|
37
|
+
== REQUIREMENTS
|
38
|
+
|
39
|
+
The gem depends on rake and treetop, although this is just for using the "erect" tool,
|
40
|
+
so deployed applications won't need these. Currently it also requires rails, although
|
41
|
+
we plan to separate the rails-dependent code so you can use Erector cleanly in a non-Rails app.
|
42
|
+
|
43
|
+
== INSTALL
|
44
|
+
|
45
|
+
To install as a gem:
|
46
|
+
|
47
|
+
* sudo gem install erector
|
48
|
+
|
49
|
+
Then add "require 'erector'" to any files which need erector.
|
50
|
+
|
51
|
+
To install as a Rails plugin:
|
52
|
+
|
53
|
+
* Copy the erector source to vendor/plugins/erector in your Rails directory.
|
54
|
+
|
55
|
+
When installing this way, erector is automatically available to your Rails code
|
56
|
+
(no require directive is needed).
|
57
|
+
|
58
|
+
== LICENSE:
|
59
|
+
|
60
|
+
(The MIT License)
|
61
|
+
|
62
|
+
Copyright (c) 2007-8 Pivotal Labs
|
63
|
+
|
64
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
65
|
+
a copy of this software and associated documentation files (the
|
66
|
+
"Software"), to deal in the Software without restriction, including
|
67
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
68
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
69
|
+
permit persons to whom the Software is furnished to do so, subject to
|
70
|
+
the following conditions:
|
71
|
+
|
72
|
+
The above copyright notice and this permission notice shall be
|
73
|
+
included in all copies or substantial portions of the Software.
|
74
|
+
|
75
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
76
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
77
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
78
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
79
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
80
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
81
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/VERSION.yml
ADDED
data/bin/erect
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "rake"
|
3
|
+
require "erector/erected" # pull this out so we don't recreate the grammar every time
|
4
|
+
|
5
|
+
module Erector
|
6
|
+
class Erect
|
7
|
+
attr_reader :files, :verbose, :mode, :output_dir
|
8
|
+
def initialize(args)
|
9
|
+
@verbose = true
|
10
|
+
@mode = :to_erector
|
11
|
+
@output_dir = nil
|
12
|
+
|
13
|
+
opts = OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: erect [options] [file|dir]*"
|
15
|
+
|
16
|
+
opts.separator "Converts from html/rhtml files to erector widgets, or from erector widgets to html files"
|
17
|
+
opts.separator ""
|
18
|
+
opts.separator "Options:"
|
19
|
+
|
20
|
+
opts.on("-q", "--quiet",
|
21
|
+
"Operate silently except in case of error") do |quiet|
|
22
|
+
@verbose = !quiet
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("--to-erector", "(default) Convert from html/rhtml to erector classes") do
|
26
|
+
@mode = :to_erector
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("--to-html", "Convert from erector to html") do
|
30
|
+
@mode = :to_html
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-o", "--output-dir DIRECTORY", "Output files to DIRECTORY (default: output files go next to input files)") do |dir|
|
34
|
+
@output_dir = dir
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
38
|
+
@mode = :help
|
39
|
+
puts opts
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on_tail("-v", "--version", "Show version") do
|
44
|
+
puts Erector::VERSION
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
opts.parse!(args)
|
50
|
+
@files = args
|
51
|
+
explode_dirs
|
52
|
+
end
|
53
|
+
|
54
|
+
def say(msg)
|
55
|
+
print msg if verbose
|
56
|
+
end
|
57
|
+
|
58
|
+
#todo: unit test
|
59
|
+
def explode_dirs
|
60
|
+
exploded_files = FileList.new
|
61
|
+
files.each do |file|
|
62
|
+
if File.directory?(file)
|
63
|
+
exploded_files.add(explode(file))
|
64
|
+
else
|
65
|
+
exploded_files.add(file)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@files = exploded_files
|
69
|
+
end
|
70
|
+
|
71
|
+
def explode(dir)
|
72
|
+
case mode
|
73
|
+
when :to_erector
|
74
|
+
FileList["#{dir}/**/*.rhtml", "#{dir}/**/*.html", "#{dir}/**/*.html.erb"]
|
75
|
+
when :to_html
|
76
|
+
FileList["#{dir}/**/*.rb"]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def run
|
81
|
+
self.send(mode)
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_erector
|
85
|
+
files.each do |file|
|
86
|
+
say "Erecting #{file}... "
|
87
|
+
begin
|
88
|
+
e = Erector::Erected.new(file)
|
89
|
+
e.convert
|
90
|
+
say " --> #{e.filename}\n"
|
91
|
+
rescue => e
|
92
|
+
puts e
|
93
|
+
puts e.backtrace.join("\n\t")
|
94
|
+
puts
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def to_html
|
100
|
+
files.each do |file|
|
101
|
+
say "Erecting #{file}... "
|
102
|
+
#todo: move this into Erected with better tests for the naming methods
|
103
|
+
begin
|
104
|
+
#todo: fail if file isn't a .rb file
|
105
|
+
require file
|
106
|
+
#todo: understand modulized widgets (e.g. class Foo::Bar::Baz < Erector::Widget in baz.rb)
|
107
|
+
filename = file.split('/').last.gsub(/\.rb$/, '')
|
108
|
+
widget_name = camelize(filename)
|
109
|
+
widget_class = constantize(widget_name)
|
110
|
+
|
111
|
+
if widget_class < Erector::Widget
|
112
|
+
widget = widget_class.new
|
113
|
+
#todo: skip if it's missing a no-arg constructor
|
114
|
+
dir = output_dir || File.dirname(file)
|
115
|
+
FileUtils.mkdir_p(dir)
|
116
|
+
output_file = "#{dir}/#{filename}.html"
|
117
|
+
File.open(output_file, "w") do |f|
|
118
|
+
f.puts widget.to_s
|
119
|
+
end
|
120
|
+
say " --> #{output_file}\n"
|
121
|
+
else
|
122
|
+
say " -- not a widget, skipping\n"
|
123
|
+
end
|
124
|
+
rescue => e
|
125
|
+
puts e
|
126
|
+
puts e.backtrace.join("\n\t")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# stolen from activesuppport/lib/inflector.rb
|
132
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
133
|
+
if first_letter_in_uppercase
|
134
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
135
|
+
else
|
136
|
+
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
def constantize(camel_cased_word)
|
140
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
|
141
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
|
142
|
+
end
|
143
|
+
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'treetop'
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
require "#{dir}/indenting"
|
5
|
+
Treetop.load("#{dir}/rhtml.treetop")
|
6
|
+
|
7
|
+
module Erector
|
8
|
+
class Erected
|
9
|
+
def initialize(in_file)
|
10
|
+
@in_file = in_file
|
11
|
+
end
|
12
|
+
|
13
|
+
def filename
|
14
|
+
dir + basename + ".rb"
|
15
|
+
end
|
16
|
+
|
17
|
+
def classname
|
18
|
+
base = classize(basename)
|
19
|
+
parent = File.dirname(@in_file)
|
20
|
+
grandparent = File.dirname(parent)
|
21
|
+
if File.basename(grandparent) == "views"
|
22
|
+
base = "Views::" + classize(File.basename(parent)) + "::" + base
|
23
|
+
end
|
24
|
+
base
|
25
|
+
end
|
26
|
+
|
27
|
+
def text
|
28
|
+
File.read(@in_file)
|
29
|
+
end
|
30
|
+
|
31
|
+
def convert
|
32
|
+
parser = RhtmlParser.new
|
33
|
+
parsed = parser.parse(File.read(@in_file))
|
34
|
+
if parsed.nil?
|
35
|
+
raise "Could not parse #{@in_file}\n" +
|
36
|
+
parser.failure_reason
|
37
|
+
else
|
38
|
+
File.open(filename, "w") do |f|
|
39
|
+
f.puts("class #{classname} < Erector::Widget")
|
40
|
+
f.puts(" def render")
|
41
|
+
f.puts(parsed.set_indent(2).convert)
|
42
|
+
f.puts(" end")
|
43
|
+
f.puts("end")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def basename
|
51
|
+
@in_file.split("/").last.gsub(/\..*$/, '')
|
52
|
+
end
|
53
|
+
|
54
|
+
def dir
|
55
|
+
x = File.dirname(@in_file)
|
56
|
+
return (x == ".") ? "" : "#{x}/"
|
57
|
+
end
|
58
|
+
|
59
|
+
def classize(filename)
|
60
|
+
filename.split("_").map{|part| part.capitalize}.join
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Object
|
2
|
+
def metaclass
|
3
|
+
class << self; self; end
|
4
|
+
end
|
5
|
+
|
6
|
+
def html_escape
|
7
|
+
return CGI.escapeHTML(to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def html_unescape
|
11
|
+
CGI.unescapeHTML(to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
def escape_single_quotes
|
15
|
+
self.gsub(/[']/, '\\\\\'')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'treetop'
|
3
|
+
|
4
|
+
module Erector
|
5
|
+
class Indenting < Treetop::Runtime::SyntaxNode #:nodoc:
|
6
|
+
@@indent = 0
|
7
|
+
|
8
|
+
def set_indent(x)
|
9
|
+
@@indent = x
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def indent
|
14
|
+
[0, @@indent].max
|
15
|
+
end
|
16
|
+
|
17
|
+
def indented(s)
|
18
|
+
" " * indent + s + "\n"
|
19
|
+
end
|
20
|
+
|
21
|
+
def line(s)
|
22
|
+
indented(s)
|
23
|
+
end
|
24
|
+
|
25
|
+
def line_in(s)
|
26
|
+
s = indented(s)
|
27
|
+
@@indent += 1
|
28
|
+
s
|
29
|
+
end
|
30
|
+
|
31
|
+
def line_out(s)
|
32
|
+
@@indent -= 1
|
33
|
+
indented(s)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
ActionController::Base.class_eval do
|
2
|
+
def render_widget(widget_class, assigns=@assigns)
|
3
|
+
@__widget_class = widget_class
|
4
|
+
@__widget_assigns = assigns
|
5
|
+
add_variables_to_assigns
|
6
|
+
render :inline => "<% @__widget_class.new(self, @__widget_assigns, _erbout).render %>"
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_with_erector_widget(*options, &block)
|
10
|
+
if options.first.is_a?(Hash) && widget = options.first.delete(:widget)
|
11
|
+
render_widget widget, @assigns, &block
|
12
|
+
else
|
13
|
+
render_without_erector_widget *options, &block
|
14
|
+
end
|
15
|
+
end
|
16
|
+
alias_method_chain :render, :erector_widget
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
ActionController::Base.class_eval do
|
2
|
+
def render_widget(widget_class, assigns=nil)
|
3
|
+
@__widget_class = widget_class
|
4
|
+
if assigns
|
5
|
+
@__widget_assigns = assigns
|
6
|
+
else
|
7
|
+
@__widget_assigns = {}
|
8
|
+
variables = instance_variable_names
|
9
|
+
variables -= protected_instance_variables
|
10
|
+
variables.each do |name|
|
11
|
+
@__widget_assigns[name.sub('@', "")] = instance_variable_get(name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
response.template.send(:_evaluate_assigns_and_ivars)
|
15
|
+
render :inline => "<% @__widget_class.new(self, @__widget_assigns, output_buffer).render %>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_with_erector_widget(*options, &block)
|
19
|
+
if options.first.is_a?(Hash) && widget = options.first.delete(:widget)
|
20
|
+
render_widget widget, @assigns, &block
|
21
|
+
else
|
22
|
+
render_without_erector_widget *options, &block
|
23
|
+
end
|
24
|
+
end
|
25
|
+
alias_method_chain :render, :erector_widget
|
26
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
if (
|
3
|
+
ActionController::Base.instance_methods + ActionController::Base.private_instance_methods).
|
4
|
+
include?("add_variables_to_assigns")
|
5
|
+
require File.expand_path("#{dir}/action_controller/1.2.5/action_controller")
|
6
|
+
else
|
7
|
+
require File.expand_path("#{dir}/action_controller/2.2.0/action_controller")
|
8
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
unless ActionView.const_defined?(:Template)
|
2
|
+
ActionView::Base.class_eval do
|
3
|
+
attr_reader :template_file_path
|
4
|
+
def render_template_with_saving_file_path(template_extension, template, file_path = nil, local_assigns = {})
|
5
|
+
@template_file_path = file_path
|
6
|
+
render_template_without_saving_file_path(template_extension, template, file_path, local_assigns)
|
7
|
+
end
|
8
|
+
alias_method_chain :render_template, :saving_file_path
|
9
|
+
|
10
|
+
def render_partial_with_notification(*args, &blk)
|
11
|
+
@is_partial_template = true
|
12
|
+
render_partial_without_notification(*args, &blk)
|
13
|
+
end
|
14
|
+
alias_method_chain :render_partial, :notification
|
15
|
+
|
16
|
+
def is_partial_template?
|
17
|
+
@is_partial_template || false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Erector
|
2
|
+
Widget.class_eval do
|
3
|
+
attr_reader :_erbout
|
4
|
+
|
5
|
+
after_initialize do
|
6
|
+
@_erbout = output
|
7
|
+
end
|
8
|
+
|
9
|
+
def define_javascript_functions(*args)
|
10
|
+
begin
|
11
|
+
text raw(helpers.define_javascript_functions(*args))
|
12
|
+
rescue => e
|
13
|
+
puts e.backtrace.join("\n\t")
|
14
|
+
raise e
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Erector
|
2
|
+
Widget.class_eval do
|
3
|
+
def output
|
4
|
+
process_output_buffer || @output
|
5
|
+
end
|
6
|
+
|
7
|
+
def capture_with_helpers(&block)
|
8
|
+
helpers ? helpers.capture(&block) : capture_without_helpers(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
alias_method_chain :capture, :helpers
|
12
|
+
|
13
|
+
# This is here to force #helpers.capture to return the output
|
14
|
+
def __in_erb_template; end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def process_output_buffer
|
19
|
+
if helpers.respond_to?(:output_buffer)
|
20
|
+
buffer = helpers.output_buffer
|
21
|
+
buffer.is_a?(String) ? buffer : handle_rjs_buffer
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def handle_rjs_buffer
|
28
|
+
returning buffer = helpers.output_buffer.dup.to_s do
|
29
|
+
helpers.output_buffer.clear
|
30
|
+
helpers.with_output_buffer(buffer) do
|
31
|
+
buffer << helpers.output_buffer.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Erector
|
2
|
+
Widget.class_eval do
|
3
|
+
include ActionController::UrlWriter
|
4
|
+
|
5
|
+
# helpers returning raw text
|
6
|
+
[
|
7
|
+
:image_tag,
|
8
|
+
:javascript_include_tag,
|
9
|
+
:stylesheet_link_tag,
|
10
|
+
:sortable_element,
|
11
|
+
:sortable_element_js,
|
12
|
+
:text_field_with_auto_complete,
|
13
|
+
].each do |helper_name|
|
14
|
+
define_method helper_name do |*args|
|
15
|
+
begin
|
16
|
+
text raw(helpers.send(helper_name, *args))
|
17
|
+
rescue => e
|
18
|
+
puts e.backtrace.join("\n\t")
|
19
|
+
raise e
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# helpers returning raw text whose first parameter is HTML escaped
|
25
|
+
[
|
26
|
+
:link_to,
|
27
|
+
:link_to_remote,
|
28
|
+
:mail_to,
|
29
|
+
:button_to,
|
30
|
+
:submit_tag,
|
31
|
+
].each do |helper_name|
|
32
|
+
|
33
|
+
method_def =<<-METHOD_DEF
|
34
|
+
def #{helper_name}(link_text, *args, &block)
|
35
|
+
text raw(helpers.#{helper_name}(h(link_text), *args, &block))
|
36
|
+
end
|
37
|
+
METHOD_DEF
|
38
|
+
eval(method_def)
|
39
|
+
end
|
40
|
+
|
41
|
+
def error_messages_for(*args)
|
42
|
+
text raw(helpers.error_messages_for(*args))
|
43
|
+
end
|
44
|
+
|
45
|
+
# return text, take block
|
46
|
+
[
|
47
|
+
:link_to_function,
|
48
|
+
:text_field_tag,
|
49
|
+
:password_field_tag,
|
50
|
+
:check_box_tag
|
51
|
+
].each do |method_to_proxy_with_block|
|
52
|
+
method_def =<<-METHOD_DEF
|
53
|
+
def #{method_to_proxy_with_block}(*args, &block)
|
54
|
+
text raw(helpers.#{method_to_proxy_with_block}(*args, &block))
|
55
|
+
end
|
56
|
+
METHOD_DEF
|
57
|
+
eval(method_def)
|
58
|
+
end
|
59
|
+
|
60
|
+
# render text, take block
|
61
|
+
[
|
62
|
+
:error_messages_for,
|
63
|
+
:form_tag,
|
64
|
+
:form_for,
|
65
|
+
].each do |method_to_proxy_with_block|
|
66
|
+
method_def =<<-METHOD_DEF
|
67
|
+
def #{method_to_proxy_with_block}(*args, &block)
|
68
|
+
helpers.#{method_to_proxy_with_block}(*args, &block)
|
69
|
+
end
|
70
|
+
METHOD_DEF
|
71
|
+
eval(method_def)
|
72
|
+
end
|
73
|
+
|
74
|
+
def javascript_include_merged(key)
|
75
|
+
helpers.javascript_include_merged(key)
|
76
|
+
end
|
77
|
+
|
78
|
+
def stylesheet_link_merged(key)
|
79
|
+
helpers.stylesheet_link_merged(key)
|
80
|
+
end
|
81
|
+
|
82
|
+
def flash
|
83
|
+
helpers.controller.send(:flash)
|
84
|
+
end
|
85
|
+
|
86
|
+
def session
|
87
|
+
helpers.controller.session
|
88
|
+
end
|
89
|
+
|
90
|
+
def controller
|
91
|
+
helpers.controller
|
92
|
+
end
|
93
|
+
|
94
|
+
def cycle(*args)
|
95
|
+
helpers.cycle(*args)
|
96
|
+
end
|
97
|
+
|
98
|
+
def simple_format(string)
|
99
|
+
p raw(string.to_s.html_escape.gsub(/\r\n?/, "\n").gsub(/\n/, "<br/>\n"))
|
100
|
+
end
|
101
|
+
|
102
|
+
def time_ago_in_words(*args)
|
103
|
+
helpers.time_ago_in_words(*args)
|
104
|
+
end
|
105
|
+
|
106
|
+
def pluralize(*args)
|
107
|
+
helpers.pluralize(*args)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
dir = File.dirname(__FILE__)
|
113
|
+
if ActionView::Base.instance_methods.include?("output_buffer")
|
114
|
+
require "#{dir}/widget/2.2.0/widget"
|
115
|
+
else
|
116
|
+
require "#{dir}/widget/1.2.5/widget"
|
117
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Erector
|
2
|
+
module Rails
|
3
|
+
SUPPORTED_RAILS_VERSIONS = {
|
4
|
+
# "1.2.5" => {'version' => '1.2.5', 'git_tag' => 'v1.2.5'},
|
5
|
+
"1.99.0" => {'version' => '1.99.0', 'git_tag' => 'v2.0.0_RC1'},
|
6
|
+
"2.0.2" => {'version' => '2.0.2', 'git_tag' => 'v2.0.2'},
|
7
|
+
"2.1.0" => {'version' => '2.1.0', 'git_tag' => 'v2.1.0'},
|
8
|
+
"2.2.0" => {'version' => '2.2.0', 'git_tag' => 'v2.2.0'},
|
9
|
+
"2.2.2" => {'version' => '2.2.2', 'git_tag' => 'v2.2.2'},
|
10
|
+
"2.3.2" => {'version' => '2.3.2', 'git_tag' => 'v2.3.2'},
|
11
|
+
# "edge" => {'version' => 'edge', 'git_tag' => 'master'}, #TODO: Readd edge support
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActionView #:nodoc:
|
2
|
+
module TemplateHandlers #:nodoc:
|
3
|
+
class Erector
|
4
|
+
def self.line_offset
|
5
|
+
2
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :view
|
9
|
+
def initialize(view)
|
10
|
+
@view = view
|
11
|
+
end
|
12
|
+
|
13
|
+
def compilable?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
ActionView::Base.register_template_handler :rb, ActionView::TemplateHandlers::Erector
|
18
|
+
|
19
|
+
def render(template, local_assigns)
|
20
|
+
relative_path_parts = view.first_render.split('/')
|
21
|
+
require_dependency view.template_file_path
|
22
|
+
|
23
|
+
dot_rb = /\.rb$/
|
24
|
+
widget_class = relative_path_parts.inject(Views) do |mod, node|
|
25
|
+
mod.const_get(node.gsub(dot_rb, '').gsub(".html", "").camelize)
|
26
|
+
end
|
27
|
+
render_method = view.is_partial_template? ? 'render_partial' : 'render'
|
28
|
+
widget_class.new(view, view.assigns).to_s(render_method)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|