Skip to content

Commit 538cb2e

Browse files
author
Egil Moeller
committed
Added documentation on the theme system
1 parent 5c26da0 commit 538cb2e

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

README.themes

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
Themes are templates
2+
---------------------
3+
4+
The theme infrastructure is really a templating library. It consists
5+
of an extended version of EJS (like ERB but for JavaScript).
6+
7+
Many templating libraries (Smarty, Django templates) adds a special
8+
template script language that provides things like inheritance and
9+
blocks, but also general programming constructs like loops and
10+
conditionals.
11+
12+
The EJS templating language uses JavaScript as templating scripting
13+
language, giving you the full power JavaScript in your templates. In
14+
addition, it provides a standard library for interacting with the
15+
template content.
16+
17+
EJS tags
18+
---------
19+
20+
An EJS template consist of verbatim HTML (or other text) and
21+
server-side JavaScripts mixed in one file. There are three syntaxes
22+
available to mix in JavaScript in the verbatim HTML:
23+
24+
<h1>some HTML</h1>
25+
<% myVar = someJavaScript(); xyzzy = goesHere(); %>
26+
<p>some more HTML</p>
27+
<% if (myVar != '') { %>
28+
myVar is not empty
29+
<% } %>
30+
31+
This will execute the javascript statements beteen <% and %>, but
32+
throw away any result values. To insert a value in the generated HTML,
33+
you use the <%= syntax:
34+
35+
<p>Result from previous code plus 47: <%= xyzzy + 47 %></p>
36+
37+
This will convert the value in the expression to string and then
38+
include it. If the value already is a string, you can gain a little
39+
more expressive freedom by using the <%: syntax instead:
40+
41+
<p>Result from previous code: <%: myVar %></p>
42+
43+
The advantage of the latter one is that it does not require the code
44+
between <%: and %> to be a full JavaScript expression, but can be a
45+
fragment of one. To understand how this is usefull, we have to examine
46+
another property of EJS: What happens to verbatim HTML.
47+
48+
49+
Verbatim text in EJS and the evaluation model
50+
----------------------------------------------
51+
52+
During evaluation of an EJS template, verbatim HTML is appended to a
53+
variable called ejs_data, one part at a time. Consider the following code:
54+
55+
Some text
56+
<% temp = ejs_data; ejs_data = ''; %>
57+
some text to be encoded
58+
<% data = base64encode(ejs_data); ejs_data = temp; %>
59+
Base64 dump: <%= data %>
60+
61+
This will encode the string "some text to be encoded" with the
62+
base64encode function and insert the result at the end of the output.
63+
The original, unencoded string is not inserted in the output.
64+
65+
Since ejs_data is just a normal variable that can be hidden by a local
66+
variable in a function, this allows for creating functions that
67+
returns mostly text using the normal EJS templating syntax:
68+
69+
<% function header(n) { var ejs_data = ''; %>
70+
Hello world <%= n %> times!
71+
<% return ejs_data; } %>
72+
73+
This is equivalent to
74+
75+
<%
76+
function (n) {
77+
return "Hello world " + n + " times!";
78+
}
79+
%>
80+
81+
Of course this only starts to be usefull when the function should
82+
return a larger body of verbatim text.
83+
84+
So, back to the usefullness of the <%: syntax:
85+
86+
Base64 dump:
87+
<%: base64encode(function () { var ejs_data = ''; %>
88+
some text to be encoded
89+
<% return ejs_data; }); %>
90+
91+
Here, the base64encode function call only ends inside the last <% %>
92+
block. This type of expression is extensively used for the template
93+
inheritance and block functions.
94+
95+
Standard functions
96+
-------------------
97+
98+
In addition to the ability to mix verbatim text and code, templates
99+
needs some additional functionality not found in a scripting language,
100+
or at least not in the same form. This include textual inheritance and
101+
blocks.
102+
103+
In EJS this is provided by a standrad function library.
104+
105+
template.inherit('page.ejs');
106+
Declares that the template inherits from another template, page.ejs.
107+
This should only be called once in a template, and at the top.
108+
109+
<%: template.use('blockName'); %>
110+
<%: template.use('blockName', function() { var ejs_data=''; %>Default content<% return ejs_data; }); %>
111+
Declares a block that can be overridden by an inheriting template.
112+
If the first form of the call is used the block is empty unless
113+
overridden.
114+
115+
<% template.define('blockName', function() { var ejs_data=''; %>New block content<% return ejs_data; }); %>
116+
Overrides the content of a block of an inherited template.
117+
118+
Note: All templates should define (or inherit from a template that
119+
defines) a top-level block named "body". The content of this block,
120+
will be the final output of the template.

0 commit comments

Comments
 (0)