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,3 @@
1
+ class Porthole
2
+ Version = VERSION = '0.99.4'
3
+ end
@@ -0,0 +1,81 @@
1
+ module Rack
2
+ module Bug
3
+ # PortholePanel is a Rack::Bug panel which tracks the time spent rendering
4
+ # Porthole views as well as all the variables accessed during view
5
+ # rendering.
6
+ #
7
+ # It can be used to track down slow partials and ensure you're only
8
+ # generating data you need.
9
+ #
10
+ # Also, it's fun.
11
+ class PortholePanel < Panel
12
+ require "rack/bug/panels/porthole_panel/porthole_extension"
13
+
14
+ # The view is responsible for rendering our panel. While Rack::Bug
15
+ # takes care of the nav, the content rendered by View is used for
16
+ # the panel itself.
17
+ class View < Porthole
18
+ self.path = ::File.dirname(__FILE__) + '/porthole_panel'
19
+
20
+ # We track the render times of all the Porthole views on this
21
+ # page load.
22
+ def times
23
+ PortholePanel.times.map do |key, value|
24
+ { :key => key, :value => value }
25
+ end
26
+ end
27
+
28
+ # Any variables used in this page load are collected and displayed.
29
+ def variables
30
+ vars = PortholePanel.variables.sort_by { |key, _| key.to_s }
31
+ vars.map do |key, value|
32
+ # Arrays can get too huge. Just show the first 10 to give you
33
+ # some idea.
34
+ if value.is_a?(Array) && value.size > 10
35
+ size = value.size
36
+ value = value.first(10)
37
+ value << "...and #{size - 10} more"
38
+ end
39
+
40
+ { :key => key, :value => value.inspect }
41
+ end
42
+ end
43
+ end
44
+
45
+ # Clear out our page load-specific variables.
46
+ def self.reset
47
+ Thread.current["rack.bug.porthole.times"] = {}
48
+ Thread.current["rack.bug.porthole.vars"] = {}
49
+ end
50
+
51
+ # The view render times for this page load
52
+ def self.times
53
+ Thread.current["rack.bug.porthole.times"] ||= {}
54
+ end
55
+
56
+ # The variables used on this page load
57
+ def self.variables
58
+ Thread.current["rack.bug.porthole.vars"] ||= {}
59
+ end
60
+
61
+ # The name of this Rack::Bug panel
62
+ def name
63
+ "porthole"
64
+ end
65
+
66
+ # The string used for our tab in Rack::Bug's navigation bar
67
+ def heading
68
+ "{{%.2fms}}" % self.class.times.values.inject(0.0) do |sum, obj|
69
+ sum + obj
70
+ end
71
+ end
72
+
73
+ # The content of our Rack::Bug panel
74
+ def content
75
+ View.render
76
+ ensure
77
+ self.class.reset
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,27 @@
1
+ if defined? Porthole
2
+ require 'benchmark'
3
+
4
+ Porthole.class_eval do
5
+ alias_method :real_render, :render
6
+
7
+ def render(*args, &block)
8
+ out = ''
9
+ Rack::Bug::PortholePanel.times[self.class.name] = Benchmark.realtime do
10
+ out = real_render(*args, &block)
11
+ end
12
+ out
13
+ end
14
+
15
+ alias_method :to_html, :render
16
+ alias_method :to_text, :render
17
+ end
18
+
19
+ Porthole::Context.class_eval do
20
+ alias_method :real_get, :[]
21
+
22
+ def [](name)
23
+ return real_get(name) if name == :yield || !@porthole.respond_to?(name)
24
+ Rack::Bug::PortholePanel.variables[name] = real_get(name)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,46 @@
1
+ <script type="text/javascript">
2
+ $(function() {
3
+ $('#porthole_variables .variable').each(function() {
4
+ var el = $(this)
5
+ if (el.text().length > 500) {
6
+ var txt = el.text()
7
+ el.click(function() {
8
+ $(this).text(txt)
9
+ }).text( el.text().slice(0, 500) + '...' )
10
+ }
11
+ })
12
+ });
13
+ </script>
14
+
15
+ <h3>Render Times</h3>
16
+
17
+ <table>
18
+ <tr>
19
+ <th>View</th>
20
+ <th>Render Time</th>
21
+ </tr>
22
+
23
+ {{# times }}
24
+ <tr>
25
+ <td>{{ key }}</td>
26
+ <td>{{ value }}</td>
27
+ </tr>
28
+ {{/ times }}
29
+ </table>
30
+
31
+ <h3>Variables</h3>
32
+
33
+ <table id="porthole_variables">
34
+ <tr>
35
+ <th>Name</th>
36
+ <th>Value</th>
37
+ </tr>
38
+
39
+ {{# variables }}
40
+ <tr>
41
+ <td>{{ key }}</td>
42
+ <td class="variable">{{ value }}</td>
43
+ </tr>
44
+ {{/ variables }}
45
+ </table>
46
+
@@ -0,0 +1,165 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "MUSTACHE" "1" "August 2011" "DEFUNKT" "Porthole Manual"
5
+ .
6
+ .SH "NAME"
7
+ \fBporthole\fR \- Porthole processor
8
+ .
9
+ .SH "SYNOPSIS"
10
+ .
11
+ .nf
12
+
13
+ porthole <YAML> <FILE>
14
+ porthole \-\-compile <FILE>
15
+ porthole \-\-tokens <FILE>
16
+ .
17
+ .fi
18
+ .
19
+ .SH "DESCRIPTION"
20
+ Porthole is a logic\-less templating system for HTML, config files, anything\.
21
+ .
22
+ .P
23
+ The \fBporthole\fR command processes a Porthole template preceded by YAML frontmatter from standard input and prints one or more documents to standard output\.
24
+ .
25
+ .P
26
+ YAML frontmatter beings with \fB\-\-\-\fR on a single line, followed by YAML, ending with another \fB\-\-\-\fR on a single line, e\.g\.
27
+ .
28
+ .IP "" 4
29
+ .
30
+ .nf
31
+
32
+ \-\-\-
33
+ names: [ {name: chris}, {name: mark}, {name: scott} ]
34
+ \-\-\-
35
+ .
36
+ .fi
37
+ .
38
+ .IP "" 0
39
+ .
40
+ .P
41
+ If you are unfamiliar with YAML, it is a superset of JSON\. Valid JSON should work fine\.
42
+ .
43
+ .P
44
+ After the frontmatter should come any valid Porthole template\. See porthole(5) for an overview of Porthole templates\.
45
+ .
46
+ .P
47
+ For example:
48
+ .
49
+ .IP "" 4
50
+ .
51
+ .nf
52
+
53
+ {{#names}}
54
+ Hi {{name}}!
55
+ {{/names}}
56
+ .
57
+ .fi
58
+ .
59
+ .IP "" 0
60
+ .
61
+ .P
62
+ Now let\'s combine them\.
63
+ .
64
+ .IP "" 4
65
+ .
66
+ .nf
67
+
68
+ $ cat data\.yml
69
+ \-\-\-
70
+ names: [ {name: chris}, {name: mark}, {name: scott} ]
71
+ \-\-\-
72
+
73
+ $ cat template\.porthole
74
+ {{#names}}
75
+ Hi {{name}}!
76
+ {{/names}}
77
+
78
+ $ cat data\.yml template\.porthole | porthole
79
+ Hi chris!
80
+ Hi mark!
81
+ Hi scott!
82
+ .
83
+ .fi
84
+ .
85
+ .IP "" 0
86
+ .
87
+ .P
88
+ If you provide multiple YAML documents (as delimited by \fB\-\-\-\fR), your template will be rendered multiple times\. Like a mail merge\.
89
+ .
90
+ .P
91
+ For example:
92
+ .
93
+ .IP "" 4
94
+ .
95
+ .nf
96
+
97
+ $ cat data\.yml
98
+ \-\-\-
99
+ name: chris
100
+ \-\-\-
101
+ name: mark
102
+ \-\-\-
103
+ name: scott
104
+ \-\-\-
105
+
106
+ $ cat template\.porthole
107
+ Hi {{name}}!
108
+
109
+ $ cat data\.yml template\.porthole | porthole
110
+ Hi chris!
111
+ Hi mark!
112
+ Hi scott!
113
+ .
114
+ .fi
115
+ .
116
+ .IP "" 0
117
+ .
118
+ .SH "OPTIONS"
119
+ By default \fBporthole\fR will try to render a Porthole template using the YAML frontmatter you provide\. It can do a few other things, however\.
120
+ .
121
+ .TP
122
+ \fB\-c\fR, \fB\-\-compile\fR
123
+ Print the compiled Ruby version of a given template\. This is the code that is actually used when rendering a template into a string\. Useful for debugging but only if you are familiar with Porthole\'s internals\.
124
+ .
125
+ .TP
126
+ \fB\-t\fR, \fB\-\-tokens\fR
127
+ Print the tokenized form of a given Porthole template\. This can be used to understand how Porthole parses a template\. The tokens are handed to a generator which compiles them into a Ruby string\. Syntax errors and confused tags, therefor, can probably be identified by examining the tokens produced\.
128
+ .
129
+ .SH "INSTALLATION"
130
+ If you have RubyGems installed:
131
+ .
132
+ .IP "" 4
133
+ .
134
+ .nf
135
+
136
+ gem install porthole
137
+ .
138
+ .fi
139
+ .
140
+ .IP "" 0
141
+ .
142
+ .SH "EXAMPLES"
143
+ .
144
+ .nf
145
+
146
+ $ porthole data\.yml template\.porthole
147
+ $ cat data\.yml | porthole \- template\.porthole
148
+ $ porthole \-c template\.porthole
149
+ $ cat <<data | ruby porthole \- template\.porthole
150
+ \-\-\-
151
+ name: Bob
152
+ age: 30
153
+ \-\-\-
154
+ data
155
+ .
156
+ .fi
157
+ .
158
+ .SH "COPYRIGHT"
159
+ Porthole is Copyright (C) 2009 Chris Wanstrath
160
+ .
161
+ .P
162
+ Original CTemplate by Google
163
+ .
164
+ .SH "SEE ALSO"
165
+ porthole(5), gem(1), \fIhttp://porthole\.github\.com/\fR
@@ -0,0 +1,213 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
6
+ <title>porthole(1) - Porthole processor</title>
7
+ <style type='text/css' media='all'>
8
+ /* style: man */
9
+ body#manpage {margin:0}
10
+ .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
11
+ .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
12
+ .mp h2 {margin:10px 0 0 0}
13
+ .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
14
+ .mp h3 {margin:0 0 0 4ex}
15
+ .mp dt {margin:0;clear:left}
16
+ .mp dt.flush {float:left;width:8ex}
17
+ .mp dd {margin:0 0 0 9ex}
18
+ .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
19
+ .mp pre {margin-bottom:20px}
20
+ .mp pre+h2,.mp pre+h3 {margin-top:22px}
21
+ .mp h2+pre,.mp h3+pre {margin-top:5px}
22
+ .mp img {display:block;margin:auto}
23
+ .mp h1.man-title {display:none}
24
+ .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
25
+ .mp h2 {font-size:16px;line-height:1.25}
26
+ .mp h1 {font-size:20px;line-height:2}
27
+ .mp {text-align:justify;background:#fff}
28
+ .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
29
+ .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
30
+ .mp u {text-decoration:underline}
31
+ .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
32
+ .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
33
+ .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
34
+ .mp b.man-ref {font-weight:normal;color:#434241}
35
+ .mp pre {padding:0 4ex}
36
+ .mp pre code {font-weight:normal;color:#434241}
37
+ .mp h2+pre,h3+pre {padding-left:0}
38
+ ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
39
+ ol.man-decor {width:100%}
40
+ ol.man-decor li.tl {text-align:left}
41
+ ol.man-decor li.tc {text-align:center;letter-spacing:4px}
42
+ ol.man-decor li.tr {text-align:right;float:right}
43
+ </style>
44
+ </head>
45
+ <!--
46
+ The following styles are deprecated and will be removed at some point:
47
+ div#man, div#man ol.man, div#man ol.head, div#man ol.man.
48
+
49
+ The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
50
+ .man-navigation should be used instead.
51
+ -->
52
+ <body id='manpage'>
53
+ <div class='mp' id='man'>
54
+
55
+ <div class='man-navigation' style='display:none'>
56
+ <a href="#NAME">NAME</a>
57
+ <a href="#SYNOPSIS">SYNOPSIS</a>
58
+ <a href="#DESCRIPTION">DESCRIPTION</a>
59
+ <a href="#OPTIONS">OPTIONS</a>
60
+ <a href="#INSTALLATION">INSTALLATION</a>
61
+ <a href="#EXAMPLES">EXAMPLES</a>
62
+ <a href="#COPYRIGHT">COPYRIGHT</a>
63
+ <a href="#SEE-ALSO">SEE ALSO</a>
64
+ </div>
65
+
66
+ <ol class='man-decor man-head man head'>
67
+ <li class='tl'>porthole(1)</li>
68
+ <li class='tc'>Porthole Manual</li>
69
+ <li class='tr'>porthole(1)</li>
70
+ </ol>
71
+
72
+ <h2 id="NAME">NAME</h2>
73
+ <p class="man-name">
74
+ <code>porthole</code> - <span class="man-whatis">Porthole processor</span>
75
+ </p>
76
+
77
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
78
+
79
+ <pre><code>porthole &lt;YAML> &lt;FILE>
80
+ porthole --compile &lt;FILE>
81
+ porthole --tokens &lt;FILE>
82
+ </code></pre>
83
+
84
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
85
+
86
+ <p>Porthole is a logic-less templating system for HTML, config files,
87
+ anything.</p>
88
+
89
+ <p>The <code>porthole</code> command processes a Porthole template preceded by YAML
90
+ frontmatter from standard input and prints one or more documents to
91
+ standard output.</p>
92
+
93
+ <p>YAML frontmatter beings with <code>---</code> on a single line, followed by YAML,
94
+ ending with another <code>---</code> on a single line, e.g.</p>
95
+
96
+ <pre><code>---
97
+ names: [ {name: chris}, {name: mark}, {name: scott} ]
98
+ ---
99
+ </code></pre>
100
+
101
+ <p>If you are unfamiliar with YAML, it is a superset of JSON. Valid JSON
102
+ should work fine.</p>
103
+
104
+ <p>After the frontmatter should come any valid Porthole template. See
105
+ <a href="porthole.5.ron.html" class="man-ref">porthole<span class="s">(5)</span></a> for an overview of Porthole templates.</p>
106
+
107
+ <p>For example:</p>
108
+
109
+ <pre><code>{{#names}}
110
+ Hi {{name}}!
111
+ {{/names}}
112
+ </code></pre>
113
+
114
+ <p>Now let's combine them.</p>
115
+
116
+ <pre><code>$ cat data.yml
117
+ ---
118
+ names: [ {name: chris}, {name: mark}, {name: scott} ]
119
+ ---
120
+
121
+ $ cat template.porthole
122
+ {{#names}}
123
+ Hi {{name}}!
124
+ {{/names}}
125
+
126
+ $ cat data.yml template.porthole | porthole
127
+ Hi chris!
128
+ Hi mark!
129
+ Hi scott!
130
+ </code></pre>
131
+
132
+ <p>If you provide multiple YAML documents (as delimited by <code>---</code>), your
133
+ template will be rendered multiple times. Like a mail merge.</p>
134
+
135
+ <p>For example:</p>
136
+
137
+ <pre><code>$ cat data.yml
138
+ ---
139
+ name: chris
140
+ ---
141
+ name: mark
142
+ ---
143
+ name: scott
144
+ ---
145
+
146
+ $ cat template.porthole
147
+ Hi {{name}}!
148
+
149
+ $ cat data.yml template.porthole | porthole
150
+ Hi chris!
151
+ Hi mark!
152
+ Hi scott!
153
+ </code></pre>
154
+
155
+ <h2 id="OPTIONS">OPTIONS</h2>
156
+
157
+ <p>By default <code>porthole</code> will try to render a Porthole template using the
158
+ YAML frontmatter you provide. It can do a few other things, however.</p>
159
+
160
+ <dl>
161
+ <dt><code>-c</code>, <code>--compile</code></dt><dd><p>Print the compiled Ruby version of a given template. This is the
162
+ code that is actually used when rendering a template into a
163
+ string. Useful for debugging but only if you are familiar with
164
+ Porthole's internals.</p></dd>
165
+ <dt><code>-t</code>, <code>--tokens</code></dt><dd><p>Print the tokenized form of a given Porthole template. This can be
166
+ used to understand how Porthole parses a template. The tokens are
167
+ handed to a generator which compiles them into a Ruby
168
+ string. Syntax errors and confused tags, therefor, can probably be
169
+ identified by examining the tokens produced.</p></dd>
170
+ </dl>
171
+
172
+
173
+ <h2 id="INSTALLATION">INSTALLATION</h2>
174
+
175
+ <p>If you have RubyGems installed:</p>
176
+
177
+ <pre><code>gem install porthole
178
+ </code></pre>
179
+
180
+ <h2 id="EXAMPLES">EXAMPLES</h2>
181
+
182
+ <pre><code>$ porthole data.yml template.porthole
183
+ $ cat data.yml | porthole - template.porthole
184
+ $ porthole -c template.porthole
185
+ $ cat &lt;&lt;data | ruby porthole - template.porthole
186
+ ---
187
+ name: Bob
188
+ age: 30
189
+ ---
190
+ data
191
+ </code></pre>
192
+
193
+ <h2 id="COPYRIGHT">COPYRIGHT</h2>
194
+
195
+ <p>Porthole is Copyright (C) 2009 Chris Wanstrath</p>
196
+
197
+ <p>Original CTemplate by Google</p>
198
+
199
+ <h2 id="SEE-ALSO">SEE ALSO</h2>
200
+
201
+ <p><a href="porthole.5.ron.html" class="man-ref">porthole<span class="s">(5)</span></a>, <span class="man-ref">gem<span class="s">(1)</span></span>,
202
+ <a href="http://porthole.github.com/" data-bare-link="true">http://porthole.github.com/</a></p>
203
+
204
+
205
+ <ol class='man-decor man-foot man foot'>
206
+ <li class='tl'>DEFUNKT</li>
207
+ <li class='tc'>August 2011</li>
208
+ <li class='tr'>porthole(1)</li>
209
+ </ol>
210
+
211
+ </div>
212
+ </body>
213
+ </html>