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,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 < 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,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,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,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 @@
|
|
1
|
+
<h1>%%title%%</h1>
|
@@ -0,0 +1 @@
|
|
1
|
+
Again, %%title%%!
|
@@ -0,0 +1 @@
|
|
1
|
+
## Again, %%title%%! ##
|
@@ -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
|