forked from ingydotnet/jemplate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DESIGN
320 lines (249 loc) · 12.3 KB
/
DESIGN
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
= DESIGN GOALS
* Be Useful
* Support as much of Perl's Template Toolkit (TT2) as feasible
* Avoid cruft and scope explosion.
* Make runtime fast as possible.
* Actually complete the project and become stable.
= OVERVIEW
Jemplate leverages TT2 by using Template::Parser, but replacing the
backend (Template::Directive) with Jemplate::Directive to produce
JavaScript code instead of Perl code.
The typical usage envisioned is that you compile your templates into one
big JavaScript file. Then you import this document and the Jemplate.js
runtime support module in your html.
= Perl API
- Jemplate::Parser->new->parse($template_text);
Parse a single template and return a JavaScript function (as a
string scalar).
- Jemplate->compile_template_files(@template_file_paths);
Take a list of template file paths and compile them into a module of
functions. Returns the text of the module.
- Jemplate->compile_template_content($template_content, $template_name);
Take a template string and its name and return the compiled code.
- Jemplate->compile_module($module_path, \@template_file_paths);
Similar to `compile_templates`, but prints the result to the
$module_path. Returns 1 if successful, undef if error.
- Jemplate->compile_module_cached($module_path, \@template_file_paths);
Similar to `compile_module`, but only compiles if one of the templates
is newer than the module. Returns 1 if sucessful compile, 0 if no
compile due to cache, undef if error.
= JavaScript API
- Jemplate.process(templateFileName[, dataObject][, outputTarget]);
Returns a string containing the rendering of the template.
templateFileName is something like `my-widget.tt` and dataObject is just
a JavaScript "hash" of data values.
The optional outputTarget can be a string or a function. If it is a
function, the function is called with the result, and `true` is returned.
If it is a string beginning with '#' followed by a word, then the word
is used to locate the DOM element with that id, and the innerHTML of the
element is replaced with the result. (`true` is returned)
If outputTarget is anything else, an exception will be thrown.
= TESTING
Currently we have automated tests in the `t/` directory that prove that
compilation is correct. These tests use Perl's Test::Base data driven
test framework.
There is also a JavaScript runtime testing suite in the `tests/`
directory that you can run by simply loading the index.html file into
any supported browser. These tests use a JavaScript port of the
Test.Base framework.
We also have a more adhoc `examples/` directory with stuff that you need to
run by hand.
= FEATURE CHECKLIST
This is basically a copy of the Template Toolkit Quick Reference Card by
Andrew Ford. This provides a really nice roadmap for Jemplate.
The original is here: http://refcards.com/refcards/tt2/index.html
Index:
(-) Not done yet but planned.
(+) Completed feature.
(=) Partially completed feature.
(x) Not appropriate for Jemplate.
Each bullet consists of a pair of symbols. The first is for the feature
completion, the second is for the testing of the feature.
== Syntax
=== Directives
++ [% [GET] var %]
++ [% CALL var %]
++ [% [SET] var = value ... %]
++ [% DEFAULT var = value ... %]
-- [% META attr = value ... %]
-- [% INSERT filename %]
++ [% INCLUDE template [var = value ...] %]
++ [% PROCESS template [var = value ...] %]
++ [% WRAPPER template [var = value ...] %] text... [% END %]
++ [% BLOCK [name] %] content... [% END %]
++ [% FILTER filter %] text... [% END %]
+- [% MACRO name[(varlist)] directive %]
-- [% USE plugin[(param, ...)] %]
xx [% PERL %] code... [% END %]
xx [% RAWPERL %] code... [% END %]
++ [% JAVASCRIPT %] code... [% END %]
++ [% FOREACH var = list %] ... [% END %]
++ [% WHILE cond %] ... [% END %]
++ [% IF cond %] ... [% ELSIF cond %] ... [% ELSE %] [% END %]
++ [% SWITCH var %] ... [% CASE [{value|DEFAULT}] %] ... [% END %]
-- [% TRY %] ... [% CATCH [type] %] ... [% FINAL %] ... [% END %]
++ [% THROW type info ... %]
++ [% NEXT %]
++ [% LAST %]
++ [% RETURN %]
++ [% STOP %]
=== Special variables
-- template outermost template being processed - methods: name, modtime
-- component innermost template being processed - methods: name, modtime
++ loop loop iterator - methods: count, first, last, max, prev, next
-- error exception object
-- content captured output for WRAPPER
-- global top level namespace
=== Virtual methods
==== Scalar variables
++ chunk(size) negative size chunks from end
++ defined is value defined?
++ hash treat as single-element hash with key value
++ length length of string representation
++ list treat as single-item list
++ match(re) true if value matches re
++ repeat(n) repeated n times
++ replace(re, sub) replace instances of re with sub
++ search(re) returns list of matching subpatterns
++ size returns 1, as if a single-item list
++ split(re) split string on re
==== Hash variables
++ each list of alternating keys/values
++ exists(key) does key exist?
+- import(hash2) import contents of hash2
+- import import into current namespace hash
+- item retrieve value using string
++ keys list of keys
++ list returns alternating key, value
++ nsort keys sorted numerically
++ size number of pairs
++ sort keys sorted alphabetically
++ values list of values
==== List variables
++ first first item in list
++ grep(re) items matching re
++ join(str) items joined with str
++ last last item in list
++ max maximum index number (i.e. size - 1)
++ merge(list [, list...]) combine lists
++ nsort items sorted numerically
++ pop remove first item from list
++ push(item) add item to end of list
++ reverse items in reverse order
++ shift remove last item from list
++ size number of elements
++ slice(from, to) subset of list
++ sort items sorted lexically
++ sort(key) list of hashes sorted lexically by key "key"
++ splice(off, len [,list]) modifies list
++ unique unique items (retains order)
++ unshift(item) add item to start of list
=== Standard filters
++ collapse collapses whitespace to a single space
-- eval(text) evaluate as template text
-- evaltt(text) evaluate as template text
-- evalperl(text) evaluate text as Perl code
-- format(str) format as per printf()
++ html performs HTML escaping on ‘<’, ‘>’, ‘&’
++ html_break convert empty lines to HTML linebreaks
++ html_entity performs HTML escaping
++ html_line_break convert newlines to ‘<br>’
++ html_para convert blank lines to HTML paras
++ indent(pad) indent by pad string or width
-- latex(outfmt) process through LATEX
++ lcfirst lower case first character
++ lower convert to lower case
++ null output to the bit bucket
xx perl(text) evaluate text as Perl code
xx redirect(file) redirect output to file
-- remove(re) removes occurrences of re
++ repeat(n) repeat n times
++ replace(re, sub) replace re with sub
xx stderr redirect output to STDERR
xx stdout(binmode) redirect output to STDERR in mode binmode
++ trim removes leading and trailing whitespace
++ truncate(len) truncate to length len
++ ucfirst capitalize first character
++ upper convert to upper case
++ uri performs URI-escaping
=== Standard plugins
Refer to documentation for details of individual plugins.
-- Autoformat autoformatting with Text::Autoformat
-- CGI interface to CGI.pm
-- Datafile data stored in plain text files
-- Date generates formatted time and date strings
-- Directory interface to directory contents
-- DBI interface to DBI
-- Dumper interface to Data::Dumper
-- File provides general file abstraction
-- Format provides printf-like formatting
-- GD::* provide access to GD graphics library
-- HTML generic HTML generation
-- Iterator iterator creation
-- Pod interface to Pod::POM (POD Object Model)
-- String OO string manipulation interface
-- Table table formatting
-- Url URL construction
-- Wrap simple paragraph wrapping
-- XML.DOM interface to XML Document Object Model
-- XML.RSS interface to XML::RSS
-- XML.Simple interface to XML::Simple
-- XML.Style simple stylesheet transforms of XML
-- XML.XPath interface to XML::XPath
== Configuration Options
++ START_TAG start of directive token ([%)
++ END_TAG end of directive token (%])
xx TAG_STYLE set pre-defined START_TAG/END_TAG style
++ PRE_CHOMP remove whitespace before directives (0)
++ POST_CHOMP remove whitespace after directives (0)
++ TRIM remove leading and trailing whitespace (0)
-- INTERPOLATE interpolate embedded variables (0)
++ ANYCASE allow lower case directive keywords (0)
=== Template files and blocks
-- INCLUDE_PATH search path for templates
xx DELIMITER delimiter for separating paths (:)
xx ABSOLUTE allow absolute file names (0)
xx RELATIVE allow relative filenames (0)
-- DEFAULT default template
-- BLOCKS hash array pre-defining template blocks
-- AUTO_RESET reset BLOCK definitions each time (1)
-- RECURSION permit recursion in templates (0)
=== Template variables
-- PRE_DEFINE hash array of variables and values to pre-define
-- VARIABLES synonym for PRE_DEFINE
=== Runtime processing options
-- EVAL_PERL process PERL/RAWPERL blocks (0)
++ PRE_PROCESS template(s) to process before main template
+- POST_PROCESS template(s) to process after main template
-- PROCESS template(s) to process instead of main template
-- ERROR name of error template or reference to hash
array mapping error types to templates
-- OUTPUT default output location or handler
-- OUTPUT_PATH directory into which output files can be written
== DEBUG raise 'undef' error on access to undefined variables
=== Caching and Compiling Options
xx CACHE_SIZE max compiled templates to cache (undef, i.e. cache all)
xx COMPILE_EXT extension for compiled template files (undef)
xx COMPILE_DIR directory for compiled template files (undef)
=== Plugins and Filters
-- PLUGINS reference to a hash array mapping plugin
names to Perl packages.
-- PLUGIN_BASE base class(es) under which plugins may be found
-- LOAD_PERL load Perl modules if plugin not found (0)
-- FILTERS hash array mapping filter names to filter
subroutines or factories.
=== Compatibility, Customisation and Extension
xx V1DOLLAR backwards compatibility flag
-- LOAD_TEMPLATES list of template providers
-- LOAD_PLUGINS list of plugin providers
-- LOAD_FILTERS list of filter providers
-- TOLERANT set providers to tolerate errors as declinations (0)
-- SERVICE custom service obj (Template::Service)
++ CONTEXT custom context obj (Template::Context)
++ STASH custom stash object (Template::Stash)
-- PARSER custom parser object (Template::Parser)
-- GRAMMAR custom grammar obj(Template::Grammar)
== Command line tools
-- tpage tpage processes supplied templates and sends output
to STDOUT
-- ttree processes directory hierarchies of templates