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