porthole 0.99.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +415 -0
  3. data/Rakefile +89 -0
  4. data/bin/porthole +94 -0
  5. data/lib/porthole.rb +304 -0
  6. data/lib/porthole/context.rb +142 -0
  7. data/lib/porthole/generator.rb +195 -0
  8. data/lib/porthole/parser.rb +263 -0
  9. data/lib/porthole/settings.rb +226 -0
  10. data/lib/porthole/sinatra.rb +205 -0
  11. data/lib/porthole/template.rb +58 -0
  12. data/lib/porthole/version.rb +3 -0
  13. data/lib/rack/bug/panels/mustache_panel.rb +81 -0
  14. data/lib/rack/bug/panels/mustache_panel/mustache_extension.rb +27 -0
  15. data/lib/rack/bug/panels/mustache_panel/view.mustache +46 -0
  16. data/man/porthole.1 +165 -0
  17. data/man/porthole.1.html +213 -0
  18. data/man/porthole.1.ron +127 -0
  19. data/man/porthole.5 +539 -0
  20. data/man/porthole.5.html +422 -0
  21. data/man/porthole.5.ron +324 -0
  22. data/test/autoloading_test.rb +56 -0
  23. data/test/fixtures/comments.porthole +1 -0
  24. data/test/fixtures/comments.rb +14 -0
  25. data/test/fixtures/complex_view.porthole +17 -0
  26. data/test/fixtures/complex_view.rb +34 -0
  27. data/test/fixtures/crazy_recursive.porthole +9 -0
  28. data/test/fixtures/crazy_recursive.rb +31 -0
  29. data/test/fixtures/delimiters.porthole +8 -0
  30. data/test/fixtures/delimiters.rb +23 -0
  31. data/test/fixtures/dot_notation.porthole +10 -0
  32. data/test/fixtures/dot_notation.rb +25 -0
  33. data/test/fixtures/double_section.porthole +7 -0
  34. data/test/fixtures/double_section.rb +14 -0
  35. data/test/fixtures/escaped.porthole +1 -0
  36. data/test/fixtures/escaped.rb +14 -0
  37. data/test/fixtures/inner_partial.porthole +1 -0
  38. data/test/fixtures/inner_partial.txt +1 -0
  39. data/test/fixtures/inverted_section.porthole +7 -0
  40. data/test/fixtures/inverted_section.rb +14 -0
  41. data/test/fixtures/lambda.porthole +7 -0
  42. data/test/fixtures/lambda.rb +31 -0
  43. data/test/fixtures/method_missing.rb +19 -0
  44. data/test/fixtures/namespaced.porthole +1 -0
  45. data/test/fixtures/namespaced.rb +25 -0
  46. data/test/fixtures/nested_objects.porthole +17 -0
  47. data/test/fixtures/nested_objects.rb +35 -0
  48. data/test/fixtures/node.porthole +8 -0
  49. data/test/fixtures/partial_with_module.porthole +4 -0
  50. data/test/fixtures/partial_with_module.rb +37 -0
  51. data/test/fixtures/passenger.conf +5 -0
  52. data/test/fixtures/passenger.rb +27 -0
  53. data/test/fixtures/recursive.porthole +4 -0
  54. data/test/fixtures/recursive.rb +14 -0
  55. data/test/fixtures/simple.porthole +5 -0
  56. data/test/fixtures/simple.rb +26 -0
  57. data/test/fixtures/template_partial.porthole +2 -0
  58. data/test/fixtures/template_partial.rb +18 -0
  59. data/test/fixtures/template_partial.txt +4 -0
  60. data/test/fixtures/unescaped.porthole +1 -0
  61. data/test/fixtures/unescaped.rb +14 -0
  62. data/test/fixtures/utf8.porthole +3 -0
  63. data/test/fixtures/utf8_partial.porthole +1 -0
  64. data/test/helper.rb +7 -0
  65. data/test/parser_test.rb +78 -0
  66. data/test/partial_test.rb +168 -0
  67. data/test/porthole_test.rb +677 -0
  68. data/test/spec_test.rb +68 -0
  69. data/test/template_test.rb +20 -0
  70. metadata +127 -0
@@ -0,0 +1,8 @@
1
+ <li>
2
+ %%contents%%
3
+ <ul>
4
+ %%#children%%
5
+ %%> node%%
6
+ %%/children%%
7
+ </ul>
8
+ </li>
@@ -0,0 +1,4 @@
1
+ <h1>%%greeting%%</h1>
2
+ %%>simple%%
3
+
4
+ <h3>%%farewell%%</h3>
@@ -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,5 @@
1
+ <VirtualHost *>
2
+ ServerName %%server%%
3
+ DocumentRoot %%deploy_to%%
4
+ RailsEnv %%stage%%
5
+ </VirtualHost>
@@ -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,4 @@
1
+ It works!
2
+ %%#show%%
3
+ %%>recursive%%
4
+ %%/show%%
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class Recursive < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def show
8
+ false
9
+ end
10
+ end
11
+
12
+ if $0 == __FILE__
13
+ puts Recursive.to_html
14
+ end
@@ -0,0 +1,5 @@
1
+ Hello %%name%%
2
+ You have just won $%%value%%!
3
+ %%#in_ca%%
4
+ Well, $%% taxed_value %%, after taxes.
5
+ %%/in_ca%%
@@ -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,2 @@
1
+ <h1>%%title%%</h1>
2
+ %%>inner_partial%%
@@ -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,4 @@
1
+ %%title%%
2
+ %%title_bars%%
3
+
4
+ %%>inner_partial%%
@@ -0,0 +1 @@
1
+ <h1>%%{title}%%</h1>
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class Unescaped < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def title
8
+ "Bear > Shark"
9
+ end
10
+ end
11
+
12
+ if $0 == __FILE__
13
+ puts Unescaped.to_html
14
+ end
@@ -0,0 +1,3 @@
1
+ <h1>中文 %%test%%</h1>
2
+
3
+ %%> utf8_partial%%
@@ -0,0 +1 @@
1
+ <h2>中文又来啦</h2>
@@ -0,0 +1,7 @@
1
+ require 'test/unit'
2
+
3
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/fixtures'
4
+
5
+ Dir[File.dirname(__FILE__) + '/fixtures/*.rb'].each do |f|
6
+ require f
7
+ end
@@ -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