porthole 0.99.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +415 -0
- data/Rakefile +89 -0
- data/bin/porthole +94 -0
- data/lib/porthole.rb +304 -0
- data/lib/porthole/context.rb +142 -0
- data/lib/porthole/generator.rb +195 -0
- data/lib/porthole/parser.rb +263 -0
- data/lib/porthole/settings.rb +226 -0
- data/lib/porthole/sinatra.rb +205 -0
- data/lib/porthole/template.rb +58 -0
- data/lib/porthole/version.rb +3 -0
- data/lib/rack/bug/panels/mustache_panel.rb +81 -0
- data/lib/rack/bug/panels/mustache_panel/mustache_extension.rb +27 -0
- data/lib/rack/bug/panels/mustache_panel/view.mustache +46 -0
- data/man/porthole.1 +165 -0
- data/man/porthole.1.html +213 -0
- data/man/porthole.1.ron +127 -0
- data/man/porthole.5 +539 -0
- data/man/porthole.5.html +422 -0
- data/man/porthole.5.ron +324 -0
- data/test/autoloading_test.rb +56 -0
- data/test/fixtures/comments.porthole +1 -0
- data/test/fixtures/comments.rb +14 -0
- data/test/fixtures/complex_view.porthole +17 -0
- data/test/fixtures/complex_view.rb +34 -0
- data/test/fixtures/crazy_recursive.porthole +9 -0
- data/test/fixtures/crazy_recursive.rb +31 -0
- data/test/fixtures/delimiters.porthole +8 -0
- data/test/fixtures/delimiters.rb +23 -0
- data/test/fixtures/dot_notation.porthole +10 -0
- data/test/fixtures/dot_notation.rb +25 -0
- data/test/fixtures/double_section.porthole +7 -0
- data/test/fixtures/double_section.rb +14 -0
- data/test/fixtures/escaped.porthole +1 -0
- data/test/fixtures/escaped.rb +14 -0
- data/test/fixtures/inner_partial.porthole +1 -0
- data/test/fixtures/inner_partial.txt +1 -0
- data/test/fixtures/inverted_section.porthole +7 -0
- data/test/fixtures/inverted_section.rb +14 -0
- data/test/fixtures/lambda.porthole +7 -0
- data/test/fixtures/lambda.rb +31 -0
- data/test/fixtures/method_missing.rb +19 -0
- data/test/fixtures/namespaced.porthole +1 -0
- data/test/fixtures/namespaced.rb +25 -0
- data/test/fixtures/nested_objects.porthole +17 -0
- data/test/fixtures/nested_objects.rb +35 -0
- data/test/fixtures/node.porthole +8 -0
- data/test/fixtures/partial_with_module.porthole +4 -0
- data/test/fixtures/partial_with_module.rb +37 -0
- data/test/fixtures/passenger.conf +5 -0
- data/test/fixtures/passenger.rb +27 -0
- data/test/fixtures/recursive.porthole +4 -0
- data/test/fixtures/recursive.rb +14 -0
- data/test/fixtures/simple.porthole +5 -0
- data/test/fixtures/simple.rb +26 -0
- data/test/fixtures/template_partial.porthole +2 -0
- data/test/fixtures/template_partial.rb +18 -0
- data/test/fixtures/template_partial.txt +4 -0
- data/test/fixtures/unescaped.porthole +1 -0
- data/test/fixtures/unescaped.rb +14 -0
- data/test/fixtures/utf8.porthole +3 -0
- data/test/fixtures/utf8_partial.porthole +1 -0
- data/test/helper.rb +7 -0
- data/test/parser_test.rb +78 -0
- data/test/partial_test.rb +168 -0
- data/test/porthole_test.rb +677 -0
- data/test/spec_test.rb +68 -0
- data/test/template_test.rb +20 -0
- metadata +127 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'porthole'
|
3
|
+
|
4
|
+
module SimpleView
|
5
|
+
def name
|
6
|
+
"Bob"
|
7
|
+
end
|
8
|
+
|
9
|
+
def value
|
10
|
+
100_000
|
11
|
+
end
|
12
|
+
|
13
|
+
def taxed_value
|
14
|
+
value - (value * 0.4)
|
15
|
+
end
|
16
|
+
|
17
|
+
def in_ca
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class PartialWithModule < Porthole
|
23
|
+
include SimpleView
|
24
|
+
self.path = File.dirname(__FILE__)
|
25
|
+
|
26
|
+
def greeting
|
27
|
+
"Welcome"
|
28
|
+
end
|
29
|
+
|
30
|
+
def farewell
|
31
|
+
"Fair enough, right?"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if $0 == __FILE__
|
36
|
+
puts PartialWithModule.to_html
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'porthole'
|
3
|
+
|
4
|
+
class Passenger < Porthole
|
5
|
+
self.path = File.dirname(__FILE__)
|
6
|
+
self.template_extension = 'conf'
|
7
|
+
|
8
|
+
def server
|
9
|
+
"example.com"
|
10
|
+
end
|
11
|
+
|
12
|
+
def deploy_to
|
13
|
+
"/var/www/example.com"
|
14
|
+
end
|
15
|
+
|
16
|
+
def stage
|
17
|
+
"production"
|
18
|
+
end
|
19
|
+
|
20
|
+
def timestamp
|
21
|
+
Time.now.strftime('%Y%m%d%H%M%S')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if $0 == __FILE__
|
26
|
+
puts Passenger.to_text
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'porthole'
|
3
|
+
|
4
|
+
class Simple < Porthole
|
5
|
+
self.path = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Chris"
|
9
|
+
end
|
10
|
+
|
11
|
+
def value
|
12
|
+
10_000
|
13
|
+
end
|
14
|
+
|
15
|
+
def taxed_value
|
16
|
+
value - (value * 0.4)
|
17
|
+
end
|
18
|
+
|
19
|
+
def in_ca
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if $0 == __FILE__
|
25
|
+
puts Simple.to_html
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'porthole'
|
3
|
+
|
4
|
+
class TemplatePartial < Porthole
|
5
|
+
self.path = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
def title
|
8
|
+
"Welcome"
|
9
|
+
end
|
10
|
+
|
11
|
+
def title_bars
|
12
|
+
'-' * title.size
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if $0 == __FILE__
|
17
|
+
puts TemplatePartial.to_html
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>%%{title}%%</h1>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h2>中文又来啦</h2>
|
data/test/helper.rb
ADDED
data/test/parser_test.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
class ParserTest < Test::Unit::TestCase
|
5
|
+
def test_parser
|
6
|
+
lexer = Porthole::Parser.new
|
7
|
+
tokens = lexer.compile(<<-EOF)
|
8
|
+
<h1>%%header%%</h1>
|
9
|
+
%%#items%%
|
10
|
+
%%#first%%
|
11
|
+
<li><strong>%%name%%</strong></li>
|
12
|
+
%%/first%%
|
13
|
+
%%#link%%
|
14
|
+
<li><a href="%%url%%">%%name%%</a></li>
|
15
|
+
%%/link%%
|
16
|
+
%%/items%%
|
17
|
+
|
18
|
+
%%#empty%%
|
19
|
+
<p>The list is empty.</p>
|
20
|
+
%%/empty%%
|
21
|
+
EOF
|
22
|
+
|
23
|
+
expected = [:multi,
|
24
|
+
[:static, "<h1>"],
|
25
|
+
[:porthole, :etag, [:porthole, :fetch, ["header"]]],
|
26
|
+
[:static, "</h1>\n"],
|
27
|
+
[:porthole,
|
28
|
+
:section,
|
29
|
+
[:porthole, :fetch, ["items"]],
|
30
|
+
[:multi,
|
31
|
+
[:porthole,
|
32
|
+
:section,
|
33
|
+
[:porthole, :fetch, ["first"]],
|
34
|
+
[:multi,
|
35
|
+
[:static, " <li><strong>"],
|
36
|
+
[:porthole, :etag, [:porthole, :fetch, ["name"]]],
|
37
|
+
[:static, "</strong></li>\n"]],
|
38
|
+
%Q' <li><strong>%%name%%</strong></li>\n',
|
39
|
+
%w[%% %%]],
|
40
|
+
[:porthole,
|
41
|
+
:section,
|
42
|
+
[:porthole, :fetch, ["link"]],
|
43
|
+
[:multi,
|
44
|
+
[:static, " <li><a href=\""],
|
45
|
+
[:porthole, :etag, [:porthole, :fetch, ["url"]]],
|
46
|
+
[:static, "\">"],
|
47
|
+
[:porthole, :etag, [:porthole, :fetch, ["name"]]],
|
48
|
+
[:static, "</a></li>\n"]],
|
49
|
+
%Q' <li><a href="%%url%%">%%name%%</a></li>\n',
|
50
|
+
%w[%% %%]]],
|
51
|
+
%Q'%%#first%%\n <li><strong>%%name%%</strong></li>\n%%/first%%\n%%#link%%\n <li><a href="%%url%%">%%name%%</a></li>\n%%/link%%\n',
|
52
|
+
%w[%% %%]],
|
53
|
+
[:static, "\n"],
|
54
|
+
[:porthole,
|
55
|
+
:section,
|
56
|
+
[:porthole, :fetch, ["empty"]],
|
57
|
+
[:multi, [:static, "<p>The list is empty.</p>\n"]],
|
58
|
+
%Q'<p>The list is empty.</p>\n',
|
59
|
+
%w[%% %%]]]
|
60
|
+
|
61
|
+
assert_equal expected, tokens
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_raw_content_and_whitespace
|
65
|
+
lexer = Porthole::Parser.new
|
66
|
+
tokens = lexer.compile("%%#list%%\t%%/list%%")
|
67
|
+
|
68
|
+
expected = [:multi,
|
69
|
+
[:porthole,
|
70
|
+
:section,
|
71
|
+
[:porthole, :fetch, ["list"]],
|
72
|
+
[:multi, [:static, "\t"]],
|
73
|
+
"\t",
|
74
|
+
%w[%% %%]]]
|
75
|
+
|
76
|
+
assert_equal expected, tokens
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
class PartialTest < Test::Unit::TestCase
|
5
|
+
def test_view_partial
|
6
|
+
assert_equal <<-end_partial.strip, PartialWithModule.render
|
7
|
+
<h1>Welcome</h1>
|
8
|
+
Hello Bob
|
9
|
+
You have just won $100000!
|
10
|
+
|
11
|
+
<h3>Fair enough, right?</h3>
|
12
|
+
end_partial
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_partial_with_slashes
|
16
|
+
klass = Class.new(Porthole)
|
17
|
+
klass.template = '%%> test/fixtures/inner_partial%%'
|
18
|
+
view = klass.new
|
19
|
+
view[:title] = 'success'
|
20
|
+
|
21
|
+
assert_equal "Again, success!", view.render
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_view_partial_inherits_context
|
25
|
+
klass = Class.new(TemplatePartial)
|
26
|
+
view = klass.new
|
27
|
+
view.template_path = File.dirname(__FILE__) + '/fixtures'
|
28
|
+
view[:titles] = [{:title => :One}, {:title => :Two}]
|
29
|
+
view.template = <<-end_template
|
30
|
+
<h1>Context Test</h1>
|
31
|
+
<ul>
|
32
|
+
%%#titles%%
|
33
|
+
<li>%%>inner_partial%%</li>
|
34
|
+
%%/titles%%
|
35
|
+
</ul>
|
36
|
+
end_template
|
37
|
+
assert_equal <<-end_partial, view.render
|
38
|
+
<h1>Context Test</h1>
|
39
|
+
<ul>
|
40
|
+
<li>Again, One!</li>
|
41
|
+
<li>Again, Two!</li>
|
42
|
+
</ul>
|
43
|
+
end_partial
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_view_partial_inherits_context_of_class_methods
|
47
|
+
klass = Class.new(TemplatePartial)
|
48
|
+
klass.template_path = File.dirname(__FILE__) + '/fixtures'
|
49
|
+
klass.send(:define_method, :titles) do
|
50
|
+
[{:title => :One}, {:title => :Two}]
|
51
|
+
end
|
52
|
+
view = klass.new
|
53
|
+
view.template = <<-end_template
|
54
|
+
<h1>Context Test</h1>
|
55
|
+
<ul>
|
56
|
+
%%#titles%%
|
57
|
+
<li>%%>inner_partial%%</li>
|
58
|
+
%%/titles%%
|
59
|
+
</ul>
|
60
|
+
end_template
|
61
|
+
assert_equal <<-end_partial, view.render
|
62
|
+
<h1>Context Test</h1>
|
63
|
+
<ul>
|
64
|
+
<li>Again, One!</li>
|
65
|
+
<li>Again, Two!</li>
|
66
|
+
</ul>
|
67
|
+
end_partial
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_template_partial
|
71
|
+
assert_equal <<-end_partial.strip, TemplatePartial.render
|
72
|
+
<h1>Welcome</h1>
|
73
|
+
Again, Welcome!
|
74
|
+
end_partial
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_template_partial_with_custom_extension
|
78
|
+
partial = Class.new(TemplatePartial)
|
79
|
+
partial.template_extension = 'txt'
|
80
|
+
partial.template_path = File.dirname(__FILE__) + '/fixtures'
|
81
|
+
|
82
|
+
assert_equal <<-end_partial.strip, partial.render.strip
|
83
|
+
Welcome
|
84
|
+
-------
|
85
|
+
|
86
|
+
## Again, Welcome! ##
|
87
|
+
end_partial
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_recursive_paritals
|
91
|
+
assert_equal <<-end_partial, Recursive.render
|
92
|
+
It works!
|
93
|
+
end_partial
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_crazy_recursive_partials
|
97
|
+
assert_equal <<-end_partial.strip, CrazyRecursive.render
|
98
|
+
<html>
|
99
|
+
<body>
|
100
|
+
<ul>
|
101
|
+
<li>
|
102
|
+
1
|
103
|
+
<ul>
|
104
|
+
<li>
|
105
|
+
2
|
106
|
+
<ul>
|
107
|
+
<li>
|
108
|
+
3
|
109
|
+
<ul>
|
110
|
+
</ul>
|
111
|
+
</li>
|
112
|
+
</ul>
|
113
|
+
</li>
|
114
|
+
<li>
|
115
|
+
4
|
116
|
+
<ul>
|
117
|
+
<li>
|
118
|
+
5
|
119
|
+
<ul>
|
120
|
+
<li>
|
121
|
+
6
|
122
|
+
<ul>
|
123
|
+
</ul>
|
124
|
+
</li>
|
125
|
+
</ul>
|
126
|
+
</li>
|
127
|
+
</ul>
|
128
|
+
</li>
|
129
|
+
</ul>
|
130
|
+
</li>
|
131
|
+
</ul>
|
132
|
+
</body>
|
133
|
+
</html>
|
134
|
+
end_partial
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_partials_use_proper_context
|
138
|
+
assert_equal "OuterThing OuterThing", OuterThing.render('%%name%% %%> p%%')
|
139
|
+
|
140
|
+
assert_equal "InnerThing InnerThing", InnerThing.render('%%name%% %%> p%%')
|
141
|
+
|
142
|
+
assert_equal "OuterThing InnerThing InnerThing",
|
143
|
+
OuterThing.render('%%name%% %%#inner%%%%name%% %%> p%%%%/inner%%')
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_partials_render_returned_strings
|
147
|
+
assert_equal "ok", MiddleThing.render('%%> some_partial %%')
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class InnerThing < Porthole
|
152
|
+
def partial(p) self.class end
|
153
|
+
def name; self.class end
|
154
|
+
end
|
155
|
+
|
156
|
+
class OuterThing < Porthole
|
157
|
+
def inner
|
158
|
+
InnerThing.new
|
159
|
+
end
|
160
|
+
|
161
|
+
def partial(p) self.class end
|
162
|
+
def name; self.class end
|
163
|
+
end
|
164
|
+
|
165
|
+
class MiddleThing < Porthole
|
166
|
+
def partial(name) "%%#{name}%%" end
|
167
|
+
def some_partial; "ok" end
|
168
|
+
end
|