-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
139 lines (133 loc) · 12 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<h1 id="pup-tent">pup-tent</h1>
<p>File caching and template rendering femto-framework using mustache and some assumptions.</p>
<p><a href="https://github.com/berkeleybop/pup-tent">On GitHub</a></p>
<p><a href="https://www.npmjs.com/package/pup-tent">NPM</a></p>
<p><a href="http://kltm.github.io/pup-tent/doc/index.html">API docs</a></p>
<p>pup-tent is maintained by <a href="https://github.com/berkeleybop">Berkeley BOP</a> & <a href="https://github.com/kltm">kltm</a></p>
<h2 id="overview">Overview</h2>
<p>Pup Tent is a femto-framework for template (Mustache) and static content delivery for Node.js and RingoJS (beta) web apps.</p>
<p>The idea is to quickly turn a pile of related JS, template, CSS, and static files into a whole coherent enough to deliver with a proper web app/routing framework, such as express.</p>
<p>There are two main aspects to Pup Tent. The first is searching for and synchronously caching static content on the filesystem, (including caching templates for later use), and then producing those when given the filename key (all filenames must be unique in Pup Tent). The second is aiding in using a couple of common template patterns using Mustache, examples below.</p>
<h2 id="usage">Usage</h2>
<h3 id="the-basics-kicking-the-tires-lightly">The Basics (kicking the tires, lightly)</h3>
<p>There are other examples in the tests/ directory, but a full example (without using the cache) might look like this.</p>
<p>Lets say you have the following files:</p>
<ul>
<li>static/frame.tmpl</li>
<li>static/content.tmpl</li>
<li>static/bar.css</li>
<li>static/foo.js</li>
<li>static/App.js</li>
</ul>
<p>The file content.tmpl looks like:</p>
<pre><code>{{ content }}</code></pre>
<p>And the file frame.tmpl looks like:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><html></span>
<span class="kw"><head></span>
<span class="kw"><title></span>{{title}}<span class="kw"></title></span>
{{#pup_tent_css_libraries}}
<span class="kw"><link</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="ot"> type=</span><span class="st">"text/css"</span><span class="ot"> href=</span><span class="st">"{{{.}}}"</span><span class="kw">></span>
{{/pup_tent_css_libraries}}
{{#pup_tent_js_variables}}
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="kw">>var</span> {{name}} = {{{value}}};<span class="kw"></script></span>
{{/pup_tent_js_variables}}
{{#pup_tent_js_libraries}}
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="ot"> src=</span><span class="st">"{{{.}}}"</span><span class="kw">></script></span>
{{/pup_tent_js_libraries}}
<span class="kw"></head></span>
<span class="kw"><body></span>
{{ <span class="er">&</span>pup_tent_content }}
<span class="kw"></body></span>
<span class="kw"></html></span></code></pre>
<p>The easiest way to deploy my App.js using this template and file structure could be something like:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> pup_tent = <span class="fu">require</span>(<span class="st">'pup-tent'</span>)([<span class="st">'static'</span>]);</code></pre>
<p>Set the common variables:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="ot">pup_tent</span>.<span class="fu">set_common</span>(<span class="st">'js_vars'</span>, {<span class="st">'name'</span>: <span class="st">'foo'</span>, <span class="st">'value'</span>: <span class="st">'bar'</span>});
<span class="ot">pup_tent</span>.<span class="fu">set_common</span>(<span class="st">'js_libs'</span>, <span class="st">'foo.js'</span>);
<span class="ot">pup_tent</span>.<span class="fu">set_common</span>(<span class="st">'css_libs'</span>, <span class="st">'bar.css'</span>);</code></pre>
<p>Set the variables for just this page:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> targs = {<span class="dt">content</span>: <span class="st">'bar'</span>, <span class="dt">title</span>: <span class="st">'foo'</span>, <span class="st">'pup_tent_js_libraries'</span>: [<span class="st">'App.js'</span>]};</code></pre>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> output = <span class="ot">pup_tent</span>.<span class="fu">render</span>(<span class="st">'content.tmpl'</span>, targs, <span class="st">'frame.tmpl'</span>);</code></pre>
<p>This would give output like:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><html></span>
<span class="kw"><head></span>
<span class="kw"><title></span>foo<span class="kw"></title></span>
<span class="kw"><link</span><span class="ot"> rel=</span><span class="st">"stylesheet"</span><span class="ot"> type=</span><span class="st">"text/css"</span><span class="ot"> href=</span><span class="st">"bar.css"</span><span class="kw">></span>
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="kw">>var</span> foo = <span class="st">"bar"</span>;<span class="kw"></script></span>
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="ot"> src=</span><span class="st">"foo.js"</span><span class="kw">></script></span>
<span class="kw"><script</span><span class="ot"> type=</span><span class="st">"text/javascript"</span><span class="ot"> src=</span><span class="st">"App.js"</span><span class="kw">></script></span>
<span class="kw"></head></span>
<span class="kw"><body></span>
bar
<span class="kw"></body></span>
<span class="kw"></html></span></code></pre>
<p>You might notice that some of the files are not correctly "linking" if you view your page in a web browser. On to the next section!</p>
<h3 id="more-advanced-test-drive">More Advanced (test drive)</h3>
<p>So far, we've just used it for some simple templating, but what if we want to use the integrated caching mechanism and use it in conjunction with something like express?</p>
<p>A more full-bodied example, using express as an example, might be:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> us = <span class="fu">require</span>(<span class="st">'underscore'</span>);
<span class="kw">var</span> express = <span class="fu">require</span>(<span class="st">'express'</span>);
<span class="kw">var</span> fs = <span class="fu">require</span>(<span class="st">'fs'</span>);
<span class="kw">var</span> mustache = <span class="fu">require</span>(<span class="st">'mustache'</span>)
<span class="kw">var</span> pup_tent = <span class="fu">require</span>(<span class="st">'pup-tent'</span>)
<span class="kw">var</span> app = <span class="fu">express</span>();
<span class="co">//////</span>
<span class="co">/// FOLLOW THE EXAMPLE ABOVE FOR REDACTED STUFF HERE ///</span>
<span class="co">//////</span>
<span class="co">// Pretty much the same as before.</span>
<span class="ot">app</span>.<span class="fu">get</span>(<span class="st">'/'</span>, <span class="kw">function</span>(req, res){
<span class="kw">var</span> targs = {
<span class="st">'title'</span>: <span class="st">'Testing'</span>
};
<span class="kw">var</span> output = <span class="ot">pup_tent</span>.<span class="fu">render</span>(<span class="st">'content.tmpl'</span>, targs, <span class="st">'frame.tmpl'</span>);
<span class="ot">res</span>.<span class="fu">send</span>(output);
});
<span class="co">// Cached static routes, using Pup Tent to easily deliver static docs.</span>
<span class="kw">var</span> js_re = <span class="ot">/</span><span class="fl">\.</span><span class="ot">js</span><span class="fl">$</span><span class="ot">/</span>;
<span class="kw">var</span> css_re = <span class="ot">/</span><span class="fl">\.</span><span class="ot">css</span><span class="fl">$</span><span class="ot">/</span>;
<span class="kw">var</span> html_re = <span class="ot">/</span><span class="fl">\.</span><span class="ot">html</span><span class="fl">$</span><span class="ot">/</span>;
<span class="co">// Routes for all static cache items at top-level.</span>
<span class="ot">us</span>.<span class="fu">each</span>(<span class="ot">pup_tent</span>.<span class="fu">cached_list</span>(<span class="st">'flat'</span>), <span class="kw">function</span>(thing){
<span class="kw">var</span> ctype = <span class="kw">null</span>;
<span class="kw">if</span>( <span class="ot">js_re</span>.<span class="fu">test</span>(thing) ){
ctype = <span class="st">'text/javascript'</span>;
}<span class="kw">else</span> <span class="kw">if</span>( <span class="ot">css_re</span>.<span class="fu">test</span>(thing) ){
ctype = <span class="st">'text/css'</span>;
}<span class="kw">else</span> <span class="kw">if</span>( <span class="ot">html_re</span>.<span class="fu">test</span>(thing) ){
ctype = <span class="st">'text/html'</span>;
}
<span class="co">// This will skip cached templates.</span>
<span class="kw">if</span>( ctype !== <span class="kw">null</span> ){
<span class="ot">app</span>.<span class="fu">get</span>(<span class="st">'/'</span> + thing, <span class="kw">function</span>(req, res) {
<span class="ot">res</span>.<span class="fu">setHeader</span>(<span class="st">'Content-Type'</span>, ctype);
<span class="ot">res</span>.<span class="fu">send</span>(<span class="ot">pup_tent</span>.<span class="fu">get</span>(thing) );
});
}
});
<span class="kw">var</span> server = <span class="ot">app</span>.<span class="fu">listen</span>(<span class="dv">3333</span>, <span class="kw">function</span>() {
<span class="ot">console</span>.<span class="fu">log</span>(<span class="st">'Starting at http://localhost:'</span> +
<span class="ot">server</span>.<span class="fu">address</span>().<span class="fu">port</span>);
});</code></pre>
<p>Since always caching can be a bit annoying when developing JavaScript/CSS heavy websites, there is also a use_cache_p() function that can be used to toggle whether Pup Tent returns to the filesystem every time or uses the internal cache. For more information about everything, see the API docs (linked at the end).</p>
<h3 id="special-variables">Special variables</h3>
<p>The special stack variables are:</p>
<ul>
<li>css_libs: will map to pup_tent_css_libraries</li>
<li>js_vars: will map to pup_tent_js_variables</li>
<li>js_libs: will map to pup_tent_js_libraries</li>
</ul>
<p>The special template variables are:</p>
<ul>
<li>pup_tent_css_libraries: list of CSS files to use</li>
<li>pup_tent_js_libraries: list of JS files to use</li>
<li>pup_tent_js_variables: list of name/value objects to convert to vaiables</li>
<li>pup_tent_content: meant for use in <em>base</em>tmpl_name_ to embed one template in another</li>
</ul>
<h2 id="tests">Tests</h2>
<h3 id="node.js">Node.js</h3>
<pre><code>Given the right environment, the tests can be easily run from the
command line using the gulpfile.js.</code></pre>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">gulp</span> test</code></pre>
<h3 id="ringojs">RingoJS</h3>
<p>The RingoJS tests are not integrated with the Makefile (yet), but can be run from the command line interface like:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">ringo</span> -m ./lib -m ./node_modules/underscore/ -m node_modules/mustache tests/full-tmpl.js.tests</code></pre>