porthole 0.99.4
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.
- 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
|