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,56 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+ require 'helper'
3
+
4
+ module TestViews; end
5
+
6
+ class AutoloadingTest < Test::Unit::TestCase
7
+ def setup
8
+ Porthole.view_path = File.dirname(__FILE__) + '/fixtures'
9
+ end
10
+
11
+ def test_autoload
12
+ klass = Porthole.view_class(:Comments)
13
+ assert_equal Comments, klass
14
+ end
15
+
16
+ def test_autoload_lowercase
17
+ klass = Porthole.view_class(:comments)
18
+ assert_equal Comments, klass
19
+ end
20
+
21
+ def test_autoload_nil
22
+ klass = Porthole.view_class(nil)
23
+ assert_equal Porthole, klass
24
+ end
25
+
26
+ def test_autoload_empty_string
27
+ klass = Porthole.view_class('')
28
+ assert_equal Porthole, klass
29
+ end
30
+
31
+ def test_namespaced_autoload
32
+ Porthole.view_namespace = TestViews
33
+ klass = Porthole.view_class('Namespaced')
34
+ assert_equal TestViews::Namespaced, klass
35
+ assert_equal <<-end_render.strip, klass.render
36
+ <h1>Dragon &lt; Tiger</h1>
37
+ end_render
38
+ end
39
+
40
+ def test_folder_autoload
41
+ assert_equal TestViews::Namespaced, Porthole.view_class('test_views/namespaced')
42
+ end
43
+
44
+ def test_namespaced_partial_autoload
45
+ Porthole.view_namespace = TestViews
46
+ klass = Porthole.view_class(:namespaced_with_partial)
47
+ assert_equal TestViews::NamespacedWithPartial, klass
48
+ assert_equal <<-end_render.strip, klass.render
49
+ My opinion: Again, Victory!
50
+ end_render
51
+ end
52
+
53
+ def test_bad_constant_name
54
+ assert_equal Porthole, Porthole.view_class(404)
55
+ end
56
+ end
@@ -0,0 +1 @@
1
+ <h1>%%title%%%%! just something interesting... #or not... %%</h1>
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class Comments < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def title
8
+ "A Comedy of Errors"
9
+ end
10
+ end
11
+
12
+ if $0 == __FILE__
13
+ puts Comments.to_html
14
+ end
@@ -0,0 +1,17 @@
1
+ <h1>%%header%%</h1>
2
+ %%#list%%
3
+ <ul>
4
+ %%#item%%
5
+ %%#current%%
6
+ <li><strong>%%name%%</strong></li>
7
+ %%/current%%
8
+ %%#link%%
9
+ <li><a href="%%url%%">%%name%%</a></li>
10
+ %%/link%%
11
+ %%/item%%
12
+ </ul>
13
+ %%/list%%
14
+
15
+ %%^list%%
16
+ <p>The list is empty.</p>
17
+ %%/list%%
@@ -0,0 +1,34 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class ComplexView < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def header
8
+ "Colors"
9
+ end
10
+
11
+ def item
12
+ items = []
13
+ items << { :name => 'red', :current => true, :url => '#Red' }
14
+ items << { :name => 'green', :current => false, :url => '#Green' }
15
+ items << { :name => 'blue', :current => false, :url => '#Blue' }
16
+ items
17
+ end
18
+
19
+ def link
20
+ not self[:current]
21
+ end
22
+
23
+ def list
24
+ not item.empty?
25
+ end
26
+
27
+ def empty
28
+ item.empty?
29
+ end
30
+ end
31
+
32
+ if $0 == __FILE__
33
+ puts ComplexView.to_html
34
+ end
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <body>
3
+ <ul>
4
+ %%#top_nodes%%
5
+ %%> node%%
6
+ %%/top_nodes%%
7
+ </ul>
8
+ </body>
9
+ </html>
@@ -0,0 +1,31 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class CrazyRecursive < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def top_nodes
8
+ [{ :contents => "1",
9
+ :children =>
10
+ [{ :contents => "2",
11
+ :children =>
12
+ [{ :contents => "3",
13
+ :children => []
14
+ }]
15
+ },
16
+ { :contents => "4",
17
+ :children =>
18
+ [{ :contents => "5",
19
+ :children =>
20
+ [{ :contents => "6",
21
+ :children => []
22
+ }]
23
+ }]
24
+ }]
25
+ }]
26
+ end
27
+ end
28
+
29
+ if $0 == __FILE__
30
+ puts CrazyRecursive.to_html
31
+ end
@@ -0,0 +1,8 @@
1
+ %%=<% %>=%%
2
+ * <% start %>
3
+ <%=| |=%>
4
+ |# middle |
5
+ * | item |
6
+ |/ middle |
7
+ |=%% %%=|
8
+ * %% final %%
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class Delimiters < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def start
8
+ "It worked the first time."
9
+ end
10
+
11
+ def middle
12
+ [ { :item => "And it worked the second time." },
13
+ { :item => "As well as the third." } ]
14
+ end
15
+
16
+ def final
17
+ "Then, surprisingly, it worked the final time."
18
+ end
19
+ end
20
+
21
+ if $0 == __FILE__
22
+ puts Delimiters.to_html
23
+ end
@@ -0,0 +1,10 @@
1
+ * %%person.name.first%% %%person.name.last%%
2
+ * %%person.age%%
3
+ * %%person.hometown.city%%, %%person.hometown.state%%
4
+ * %%#person%%%%hometown.city%%, %%hometown.state%%%%/person%%
5
+ * %%#person%%%%#hometown%%%%city%%, %%state%%%%/hometown%%%%/person%%
6
+ * %%#person.hometown%%%%city%%, %%state%%%%/person.hometown%%
7
+ * %%normal%%
8
+
9
+ * %%{person.name.first}%% %%&person.name.last%%
10
+ * %%^person.alien?%%%%person.hometown.city%%, %%person.hometown.state%%%%/person.alien?%%
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class DotNotation < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def person
8
+ return {
9
+ :name => OpenStruct.new(:first => 'Chris', :last => 'Firescythe'),
10
+ :age => 24,
11
+ :hometown => {
12
+ :city => "Cincinnati",
13
+ :state => "OH"
14
+ }
15
+ }
16
+ end
17
+
18
+ def normal
19
+ "Normal"
20
+ end
21
+ end
22
+
23
+ if $0 == __FILE__
24
+ puts DotNotation.to_html
25
+ end
@@ -0,0 +1,7 @@
1
+ %%#t%%
2
+ * first
3
+ %%/t%%
4
+ * %%two%%
5
+ %%#t%%
6
+ * third
7
+ %%/t%%
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class DoubleSection < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def t
8
+ true
9
+ end
10
+
11
+ def two
12
+ "second"
13
+ end
14
+ end
@@ -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 Escaped < 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 Escaped.to_html
14
+ end
@@ -0,0 +1 @@
1
+ Again, %%title%%!
@@ -0,0 +1 @@
1
+ ## Again, %%title%%! ##
@@ -0,0 +1,7 @@
1
+ %%^t%%
2
+ * first
3
+ %%/t%%
4
+ * %%two%%
5
+ %%^t%%
6
+ * third
7
+ %%/t%%
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class InvertedSection < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ def t
8
+ false
9
+ end
10
+
11
+ def two
12
+ "second"
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ %%#rendered%%
2
+ Hi %%name%%.
3
+ %%/rendered%%
4
+
5
+ %%#not_rendered%%
6
+ Hi %%name%%.
7
+ %%/not_rendered%%
@@ -0,0 +1,31 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class Lambda < Porthole
5
+ self.path = File.dirname(__FILE__)
6
+
7
+ attr_reader :calls
8
+
9
+ def initialize(*args)
10
+ super
11
+ @calls = 0
12
+ @cached = nil
13
+ end
14
+
15
+ def rendered
16
+ lambda do |text|
17
+ return @cached if @cached
18
+
19
+ @calls += 1
20
+ @cached = render(text)
21
+ end
22
+ end
23
+
24
+ def not_rendered
25
+ lambda { |text| "%%= | =%%#{text}" }
26
+ end
27
+ end
28
+
29
+ if $0 == __FILE__
30
+ puts Lambda.to_html(Lambda.template, :name => "Jonny")
31
+ end
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ class MethodMissing < Porthole
5
+ self.template = '[ %%#list%%%%.%% %%/list%%]'
6
+
7
+ def method_missing(name, *args, &block)
8
+ return (0..10).to_a if name == :list
9
+ return super
10
+ end
11
+
12
+ def respond_to?(method)
13
+ method == :list
14
+ end
15
+ end
16
+
17
+ if $0 == __FILE__
18
+ puts MethodMissing.to_html
19
+ end
@@ -0,0 +1 @@
1
+ <h1>%%title%%</h1>
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+
4
+ module TestViews
5
+ class Namespaced < Porthole
6
+ self.path = File.dirname(__FILE__)
7
+
8
+ def title
9
+ "Dragon < Tiger"
10
+ end
11
+ end
12
+
13
+ class NamespacedWithPartial < Porthole
14
+ self.path = File.dirname(__FILE__)
15
+ self.template = "My opinion: %%>inner_partial%%"
16
+
17
+ def title
18
+ "Victory"
19
+ end
20
+ end
21
+ end
22
+
23
+ if $0 == __FILE__
24
+ puts TestViews::Namespaced.to_html
25
+ end
@@ -0,0 +1,17 @@
1
+ <h1>%%header%%</h1>
2
+ %%#list%%
3
+ <ul>
4
+ %%#item%%
5
+ %%#current%%
6
+ <li><strong>%%name%%</strong></li>
7
+ %%/current%%
8
+ %%#link%%
9
+ <li><a href="%%url%%">%%name%%</a></li>
10
+ %%/link%%
11
+ %%/item%%
12
+ </ul>
13
+ %%/list%%
14
+
15
+ %%^list%%
16
+ <p>The list is empty.</p>
17
+ %%/list%%
@@ -0,0 +1,35 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'porthole'
3
+ require 'ostruct'
4
+
5
+ class NestedObjects < Porthole
6
+ self.path = File.dirname(__FILE__)
7
+
8
+ def header
9
+ "Colors"
10
+ end
11
+
12
+ def item
13
+ items = []
14
+ items << OpenStruct.new(:name => 'red', :current => true, :url => '#Red')
15
+ items << OpenStruct.new(:name => 'green', :current => false, :url => '#Green')
16
+ items << OpenStruct.new(:name => 'blue', :current => false, :url => '#Blue')
17
+ items
18
+ end
19
+
20
+ def link
21
+ not self[:current]
22
+ end
23
+
24
+ def list
25
+ not item.empty?
26
+ end
27
+
28
+ def empty
29
+ item.empty?
30
+ end
31
+ end
32
+
33
+ if $0 == __FILE__
34
+ puts NestedObjects.to_html
35
+ end