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