-
Notifications
You must be signed in to change notification settings - Fork 92
/
guide.html
1080 lines (901 loc) · 43.6 KB
/
guide.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
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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>How To Use the Ctemplate (formerly Google Template) System</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="designstyle.css" type="text/css" rel="stylesheet">
<style type="text/css">
ol.bluelist li {
color: #3366ff;
font-family: sans-serif;
}
ol.bluelist li p {
color: #000;
font-family: "Times Roman", times, serif;
}
ul.blacklist li {
color: #000;
font-family: "Times Roman", times, serif;
}
</style>
</head>
<body>
<h1>How To Use the Ctemplate (formerly Google Template) System</h1>
<small>(as of
<script type=text/javascript>
var lm = new Date(document.lastModified);
document.write(lm.toDateString());
</script>)
</small>
<br>
<h2> Motivation </h2>
<p>A template system can be used to separate output formatting
specifications, which govern the appearance and location of output
text and data elements, from the executable logic which prepares the
data and makes decisions about what appears in the output.</p>
<p>Template systems lie along a continuum of power versus separation.
"Powerful" constructs like variable assignment or conditional
statements make it easy to modify the look of an application within
the template system exclusively, without having to modify any of the
underlying "application logic". They do so, however, at the cost of
separation, turning the templates themselves into part of the
application logic.</p>
<p>This template system leans strongly towards preserving the
separation of logic and presentation. It is intentionally constrained
in the features it supports and, as a result, applications tend to
require quite a bit of code to instantiate a template. This may not
be to everybody's tastes. However, while this design limits the power
of the template <i>language</i>, it does not limit the power or
flexibility of the template <i>system</i>. This system supports
arbitrarily complex text formatting. Many Google applications,
including the "main" Google web search, use this system
for formatting output.</p>
<p>Finally, this system is designed with an eye towards efficiency.
Template instantiation is very quick, with an eye towards minimizing
both memory use and memory fragmentation.</p>
<h2> Overview </h2>
<p>There are two main parts to the Ctemplate System:</p>
<ul>
<li> Templates
<li> Data dictionaries
</ul>
<p>The templates are text files that contain the format specification
for the formatted output, i.e, the template language. The data
dictionaries contain the mappings from the template elements (markers)
embedded in the templates to the data that they will format. Here's
a simple template:</p>
<pre>
<html><head><title>{{TITLE}}</title>{{META_TAGS}}</head>
<body>{{BODY}}</body></html>
</pre>
<p>Here's a dictionary that one could use to instantiate the template:</p>
<pre>
{"TITLE": "Template example",
"BODY": "This is a simple template example.\nIt's boring",
"DATE": "11/20/2005"}
</pre>
<p>If we instantiated the template with this dictionary (a process we
call "expanding"), here's the output we would get:</p>
<pre>
<html><head><title>Template example</title></head>
<body>This is a simple template example.
It's boring</body></html>
</pre>
<p><code>{{TITLE}}</code> and <code>{{BODY}}</code> are <b>template
elements</b>, also called <b>markers</b>. In the dictionary,
<code>TITLE</code>, <code>BODY</code>, and <code>DATE</code> are
<b>dictionary names</b>, and the values associated with each one, such
as <code>11/20/2005</code>, are <b>dictionary values</b>.</p>
<p>A few points are clear even from this simple example:</p>
<ol>
<li> Dictionary keys and values are strings; the Ctemplate
system is not typed. </li>
<li> Dictionary values come already formatted. It was up to the
application code to decide how to format the value for
<code>DATE</code>, and to insert the date into the dictionary
already formatted. </li>
<li> Not all dictionary values must be used by a template.
<code>DATE</code> is entirely ignored. </li>
<li> Not all template elements may exist in the dictionary. In this
example, <code>{{META_TAGS}}</code> is not found in the
dictionary. This is perfectly legal; missing dictionary names
evaluate to the empty string. </li>
</ol>
<h3> Templates </h3>
<p> The template language has four major types of markers (the full
list of marker types is described in the <A
HREF="reference.html#template">reference guide</A>):</p>
<ol>
<li> <b>Variable</b> markers, which are replaced by text based on
dictionary values. All markers in the above example are
variable markers. Variable markers look like this:
<code>{{FOO}}</code></li>
<li> <b>Start section</b> and <b>end section</b> markers, which delimit
sections which may appear zero, one, or N times in
the output. The number of times a section appears is
determined by the data dictionaries, as explained below.
Each time a section is expanded, it uses a different
dictionary, so that the output values may be different from one
iteration of a section expansion to another. Note that the
specification of how sections expand is entirely dependent on
the dictionary, as set up by the application; there is no way
to specify a repeat count in the template language itself.
Section markers look like this:
<code>{{#FOO}}...{{/FOO}}</code></li>
<li> <b>Template-include</b> markers, which designate other templates to be
expanded and inserted at the location where the marker appears.
These are treated much like sections -- one may think of them
as sections whose content is specified in a
different file instead of inline -- and just like sections, can
be expanded zero, one or N times in the output, each with a
different dictionary and even a different include-file.
Template-include markers look like this:
<code>{{>FOO}}</code></li>
<li> <b>Comment</b> markers, which may annotate the template
structure but drop completely out of the expanded
output. Comment markers look like this:
<code>{{! comment lives here -- cool, no?}}</code></li>
</ol>
<p>These marker types each have their own namespace. For readability,
however, it is best to not overuse a single name.</p>
<p>Anything found in a template of the form <code>{{...}}</code> is
interpreted as a template marker. All other text is considered
formatting text and is output verbatim at template expansion time.
Formatting text may consist of HTML tags, XML tags, linefeeds and
other spacing characters, constant text, etc.</p>
<h3> Data Dictionaries </h3>
<p>A data dictionary is a map from keys to values. The keys are
always strings, each string representing either a variable, a section,
or a template-include file. (Comments are not stored in the data
dictionary!) These values correspond to the name of the associated
template marker: a section <code>{{#FOO}}</code> in the template text
is matched to the key <code>"FOO"</code> in the dictionary, if it
exists. Note the case must match as well.</p>
<p>The value associated with a key differs according to key type. The
value associated with a <i>variable</i> is simple: it's the value for
that variable. Both keys and values can be any 8-bit
character-string, and may include internal NULs (\0).</p>
<p>The value associated with a <i>section</i> is more complicated, and
somewhat recursive: it's a list of data dictionaries. Come
template-expansion time, the section is expanded once for each
dictionary in the list, so if there are two dictionaries in the list,
then the section text will occur in the output twice. The first time,
all variables/etc. in the section will be evaluated taking into
account the first dictionary. The second time, all
variables/etc. will be evaluated taking into account the second
dictionary. (See <A HREF="#inheritance">below</A> for a definition of
"taking into account.")</p>
<p>A <i>template-include</i> is a special type of section, so the
associated value is the same: a list of dictionaries.
Template-includes also have one other, mandatory associated piece of
information: the filename of the template to include.</p>
<p>The application program is responsible for building this data
dictionary, including all nesting. It then applies this dictionary to
a single template to produce formatted output.</p>
<h3>Expanding a Template</h3>
<p>A program using Ctemplate typically reads in templates at
load time. During the course of program execution, the program will
repeatedly perform the following two steps: first, instantiate a data
dictionary, and second, apply the dictionary to the template to
produce output.</p>
<p>The template system applies a dictionary to a template by finding
all template markers in the template, and replacing them with the
appropriate dictionary values. It matches template markers to
dictionary keys in the obvious way. For instance, a template marker
<code>{{FOO}}</code> matches the dictionary key <code>FOO</code>. The
marker <code>{{#BAR}}</code> matches the dictionary key
<code>BAR</code>, as does the marker <code>{{/BAR}}</code>. The
marker <code>{{>BAZ}}</code> matches the dictionary key
<code>BAZ</code>. (And of course, the marker <code>{{!
comment}}</code> doesn't match any dictionary key at all.)</p>
<p>If no dictionary key is found for a given template marker, then the
template marker is ignored: if a variable, it expands to the empty
string; if a section or include-template, the section or
include-template is expanded zero times.</p>
<p>All names are case sensitive. Names -- that is, variable keys and,
as a result, template markers -- must be made of (7-bit ascii)
alphanumeric characters and the underscore. The comment marker,
which does not map to dictionary keys, may contain any characters
whatsoever except <code>}</code>, the close-curly brace. It's a
syntax error for any template marker to violate this rule.</p>
<p>Outside of the template markers, templates may contain any text
whatsoever, including (single) curly braces and NUL characters.</p>
<h3> <A NAME="auto_escape">Auto Escape Mode</A> </h3>
<p>The Auto Escape mode helps protect against cross-site scripting
(XSS) attacks in web-applications by automatically escaping variables
in your template. The <a href="auto_escape.html">Guide to using Auto
Escape</a> has an overview of Auto Escape as well as discussion of its
limitations.</p>
<p>Auto Escape is enabled on a template-by-template basis. Simply add
the AUTOESCAPE pragma to the desired template. That template will then
be automatically escaped, independently of the templates it may
include or it may be included from. The AUTOESCAPE pragma must be
placed at the top of the template. It takes a 'context' argument
saying what context the template is used in: html, javascript, css,
xml, etc. (There's also a <code>state=IN_TAG</code> argument that is
used when the template is just a snippet of html intended for use in a
tag.) See the <A HREF="reference.html#auto_escaping">reference
guide</A> for a full description of autoescape arguments.</p>
<p>The table below shows four small sample templates along with their
corresponding AUTOESCAPE pragma. The two most common contexts are
<code>HTML</code> and <code>JAVASCRIPT</code>. We also show a sample
template for the <code>CSS</code> context as well as a sample template
for the <code>IN_TAG</code> state of <code>HTML</code>
(although it is expected to be rarely used).</p>
<p>
<table id="AutoescapePragmaEx" border=1 cellpadding=3>
<tr>
<th>HTML</th>
<th>JAVASCRIPT</th>
<th>CSS</th>
<th>HTML IN_TAG (uncommon)</th>
</tr>
<tr valign="top">
<td>
<pre>
{{%AUTOESCAPE context="HTML"}}
<body>
<p>Hello {{USER}}</p>
<p><a href="{{URL}}">Your Account</a></p>
</body>
</pre>
</td>
<td>
<pre>
{{%AUTOESCAPE context="JAVASCRIPT"}}
function showMessage(user, msg) {
alert("Hello: " + user + " Message: " + msg);
}
var user = '{{USER}}';
var msg = '{{MSG}}';
showMessage(user, msg);
</pre>
</td>
<td>
<pre>
{{%AUTOESCAPE context="CSS"}}
P.abstract {
text-align:{{EDGE}};
font-size:{{FONT_SIZE_PC}};
}
.italic {font-style:{{ITALIC}}}
</pre>
</td>
<td>
<pre>
{{%AUTOESCAPE context="HTML" state="IN_TAG"}}
class="{{CLASS}}" id="{{ID}}"
</pre>
</td>
</tr>
</table>
</p>
<p>Auto-escaping works by automatically applying <i>modifiers</i> to
every variable in the template. You can manually apply modifiers as
well, and even define your own. See the <A
HREF="reference.html#template_modifier">reference guide</A> for a full
discussion of modifiers and how to use them.</p>
<h3> <A NAME="inheritance">Details on Dictionary Lookup</A> </h3>
<p>The dictionary structure is a tree: there's a 'main' dictionary,
and then a list of sub-dictionaries for each section or
include-template. Even with all this complexity, the lookup rules are
mostly straightforward: when looking up a marker -- be it a variable,
section, or include-template marker -- the system looks in the
currently applicable dictionary. If it's found there, great. If not,
and the parent dictionary is not an include-template, it continues the
look in the parent dictionary, and possibly the grandparent, etc.
That is, lookup has <i>static scoping</i>: you look in your dictionary
and any parent dictionary that is associated with the same
template-file. As soon as continuing the lookup would require you to
jump to a new template-file (which is what include-template would do),
we stop the lookup.</p>
<p>For instance, for a template that says
<code>{{#RESULTS}}{{RESULTNUM}}. {{>ONE_RESULT}}{{/RESULTS}}</code>,
<code>"ONE_RESULT"</code> is looked for in the "RESULTS" dictionary,
and if not found there, is looked for in the main, top-level
dictionary. Likewise, the variable <code>"RESULTNUM"</code> is looked
for first in the "RESULTS" dictionary, then in the main dictionary if
necessary. However, "ONE_RESULT" will not do equivalent cascading
lookups. In fact, it will have no parent dictionaries at all, because
it's a different template file and thus in a different scope.</p>
<p>Because of these scoping rules, it's perfectly reasonable to set
all variables that are needed in a given template file, in the
top-level dictionary for that template. In fact, the <code><A
HREF="#sections">ShowSection()</A></code> function is provided to
support just this idiom. To avoid confusion in such a usage mode,
it's strongly encouraged that you give unique names to all sections
and include-templates in a single template file. (It's no problem,
given the template scoping rules, for a single section or
include-template name to be repeated across different template
files.)</p>
<p>There's a single special case: the <b>global variable
dictionary</b>. Every dictionary inherits its initial set of values
from the global dictionary. Clients can <A HREF="#variables">set
variables in the global dictionary</A> just like they can in normal
template dictionaries they create.</p>
<p>The system initializes the global dictionary with a few useful
values for your convenience. All system variables are prefixed with
<code>BI</code>, to emphasize they are "built in" variables.</p>
<ul>
<li> <code>BI_SPACE</code>, which has the value
<code><space></code>. It is used to force a space
at the beginning or end of a line in the template,
where it would normally be suppressed. (See below.) </li>
<li><code>BI_NEWLINE</code>, which has the value
<code><newline></code> It is used to force a
newline at the end of a line, where it would normally
be suppressed. (See below.) </li>
</ul>
<p>As is usual for inheritance, if a user explicitly assigns a value
to these variable-names in its own dictionary, this overrides the
inherited value. So, <code>dict->SetValue("BI_SPACE",
"&nbsp;")</code> causes <code>BI_SPACE</code> to have the value
<code>&nbsp;</code>, rather than <code><space></code>, when
expanding <code>dict</code>.</p>
<p>Note that only variables can be inherited from the global
dictionary, not section dictionaries or include-file dictionaries.</p>
<p>A couple of small implementation notes: global inheritance is "last
chance", so if a section's parent dictionary redefined
<code>BI_SPACE</code>, say, the section dictionary inherits the
parent-dict value, not the global-dict value. Second, variable
inheritance happens at expand time, not at dictionary-create time. So
if you create a section dictionary, and then afterwards set a variable
in its parent dictionary (or in the global dictionary), the section
<i>will</i> inherit that variable value, if it doesn't define the
value itself.</p>
<h2> Writing Application Code To Use Templates </h2>
<p>Most application code concerns filling a template dictionary, but
there is also code for expanding templates given a dictionary. A
final category of code lets you inspect and control the template
system.</p>
<h3> Creating A Template Dictionary </h3>
<p>The class <code>TemplateDictionary</code> is used for all template
dictionary operations. <code>new ctemplate::TemplateDictionary(name)</code> is
used to create a new top-level dictionary.
<code>dict->AddSectionDictionary(name)</code> and
<code>dict->AddIncludeDictionary(name)</code> are used to create
sub-dictionaries for sections or include-files. After
creating a dictionary, the application should call one or more
functions for each marker in the template. As an example, consider
the following template:
<pre>
<html><body> {{! This page has no head section.}}
{{#CHANGE_USER}}
<A HREF="/login">Click here</A> if you are not {{USERNAME}}<br>
{{/CHANGE_USER}}
Last five searches:<ol>
{{#PREV_SEARCHES}
<li> {{PREV_SEARCH}}
{{/PREV_SEARCHES}}
</ol>
{{>RESULT_TEMPLATE}}
{{FOOTER}}
</body></html>
</pre>
<p>To instantiate the template, the user should call a function to set
up <code>FOOTER</code>, and a function to say what to do for the
sections <code>CHANGE_USER</code> and <code>PREV_SEARCHES</code>, and
for the include-template <code>RESULT_TEMPLATE</code>. Quite likely,
the application will also want to create a sub-dictionary for
<code>CHANGE_USER</code>, and in that sub-dictionary call a function
to set up <code>USERNAME</code>. There will also be sub-dictionaries
for <code>PREV_SEARCHES</code>, each of which will need to set
<code>PREV_SEARCH</code>. Only when this is all set up will the
application be able to apply the dictionary to the template to get
output.</p>
<p>The appropriate function to call for a given template marker
depends on its type.</p>
<h4> <A NAME="variables">Variables</A> </h4>
<p>For variables, the only interesting action is to set the variable's
value. For most variables, the right method to call is
<code>dict->SetValue(name, value)</code>. (The name and value
can be specified as strings in a variety of ways: C++ strings, char
*'s, or char *'s plus length.)</p>
<p>There are two other ways to set a variable's value as well, each
with a different scoping rule. You can call
<code>ctemplate::TemplateDictionary::SetGlobalValue(name, value)</code>
-- no <code>TemplateDictionary</code> instance needed here -- to set a
variable that can be used by all templates in an application. This
is quite rare.</p>
<p>You can also call <code>dict->SetTemplateGlobalValue(name,
value)</code>. This sets a variable that is seen by all child
dictionaries of this dictionary: sub-sections you create via
<code>AddSectionDictionary</code>, and included templates you create
via <code>AddIncludeDictionary</code> (both described below). This
differs from <code>SetValue()</code>, because <code>SetValue()</code>
values are never inherited across template-includes. Almost always,
<code>SetValue</code> is what you want;
<code>SetTemplateGlobalValue</code> is intended for variables that are
"global" to a particular template tree not all template trees, such as
a color scheme to use, a language code, etc.</p>
<p>To make it easier to use <code>SetValue()</code>, there are a few
helper routines to help setting values of a few special forms.</p>
<ul>
<li> <code>SetIntValue(name, int)</code>: takes an int as the value. </li>
<li> <code>SetFormattedValue(name, fmt, ...)</code>: the
<code>fmt</code> and <code>...</code> work just like in
<code>printf</code>: <code>SetFormattedValue("HOMEPAGE",
"http://%s/", hostname)</code>. </li>
</ul>
<p>Example:</p>
<pre>
ctemplate::TemplateDictionary* dict = new ctemplate::TemplateDictionary("var example");
dict->SetValue("FOOTER", "Aren't these great results?");
</pre>
<h4> <A NAME="sections">Sections</A> </h4>
<p>Sections are used in two ways in templates. One is to expand some
text multiple times. This is how <code>PREV_SEARCHES</code> is used
in the example above. In this case we'll have one small
sub-dictionary for each of the five previous searches the user did.
To do this, call <code>AddSectionDictionary(section_name)</code>
to create the sub-dictionary. It returns a
<code>TemplateDictionary*</code> that you can use to fill the
sub-dictionary.
<p>The other use of sections is to conditionally show or hide a block
of text at template-expand time. This is how <code>CHANGE_USER</code>
is used in the example template: if the user is logged in, we show the
section with the user's username, otherwise we choose not to show the
section.</p>
<p>This second case is a special case of the first, and the "standard"
way to show a section is to expand it exactly one time, by calling
<code>AddSectionDictionary()</code> once, and then setting
<code>USERNAME</code> in the sub-dictionary.</p>
<p>However, the hide/show idiom is so common there are a few
convenience methods to make it simpler. The first takes advantage of
the fact sections inherit variables from their parent: you set
<code>USERNAME</code> in the parent dictionary, rather than a section
sub-dictionary, and then call <code>ShowSection()</code>, which adds a
single, empty dictionary for that section. This causes the section to
be shown once, and to inherit <i>all</i> its variable values from its
parent.</p>
<p>A second convenience method is written for the particular case we
have with <code>USERNAME</code>: if the user's username is non-empty,
we wish to
show the section with <code>USERNAME</code> set to the username,
otherwise we wish to hide the section and show neither
<code>USERNAME</code> nor the text around it. The method
<code>SetValueAndShowSection(name, value, section_name)</code> does
exactly that: if value is non-empty, add a single dictionary to
<code>section_name</code> and call <code>section_dict->AddValue(name,
value)</code>.</p>
<p>Example:</p>
<pre>
ctemplate::TemplateDictionary* dict = new ctemplate::TemplateDictionary("section example");
const char* username = GetUsername(); // returns "" for no user
if (username[0] != '\0') {
ctemplate::TemplateDictionary* sub_dict = dict->AddSectionDictionary("CHANGE_USER");
sub_dict->SetValue("USERNAME", username);
} else {
// don't need to do anything; we want a hidden section, which is the default
}
// Instead of the above 'if' statement, we could have done this:
if (username[0] != '\0') {
dict->ShowSection("CHANGE_USER"); // adds a single, empty dictionary
dict->SetValue("USERNAME", username); // take advantage of inheritance
} else {
// don't need to do anything; we want a hidden section, which is the default
}
// Or we could have done this:
dict->SetValueAndShowSection("USERNAME", username, "CHANGE_USER");
// Moving on...
GetPrevSearches(prev_searches, &num_prev_searches);
if (num_prev_searches > 0) {
for (int i = 0; i < num_prev_searches; ++i) {
TemplateDictionary* sub_dict = dict->AddSectionDictionary("PREV_SEARCHES");
sub_dict->SetValue("PREV_SEARCH", prev_searches[i]);
}
}
</pre>
<h4> Template-includes </h4>
<p>Template-include markers are much like section markers, so
<code>AddIncludeDictionary(name)</code> acts, not surprisingly,
exactly like <code>AddSectionDictionary(name)</code>. However, since
variable inheritance doesn't work across include boundaries, there is
no template-include equivalent to <code>ShowSection()</code> or
<code>SetValueAndShowSection()</code>.</p>
<p>One difference between template-includes and sections is that for a
sub-dictionary that you create via
<code>AddIncludeDictionary()</code>, you <i>must</i> call
<code>subdict->SetFilename()</code> to indicate the name of the
template to include. If you do not set this, the sub-dictionary will
be ignored. The filename may be absolute, or relative, in which case
it's relative to some entry in the <A
HREF="reference.html#template_cache">template search path</A>.</p>
<p>Example:</p>
<pre>
using ctemplate::TemplateDictionary;
TemplateDictionary* dict = new TemplateDictionary("include example");
GetResults(results, &num_results);
for (int i = 0; i < num_results; ++i) {
TemplateDictionary* sub_dict = dict->AddIncludeDictionary("RESULT_TEMPLATE");
sub_dict->SetFilename("results.tpl");
FillResultsTemplate(sub_dict, results[i]);
}
</pre>
<p>In practice, it's much more likely that
<code>FillResultsTemplate()</code> will be the one to call
<code>SetFilename()</code>. Note that it's not an error to call
<code>SetFilename()</code> on a dictionary even if the dictionary is
not being used for a template-include; in that case, the function is a
no-op, but is perhaps still useful as self-documenting code.</p>
<p>Another property of template-includes is that they set the indentation level
for the included template, that is, every line in the included template is
indented by the same amount as the template-includes line itself. For
instance, if you have a template <code>PRINT_STUFF</code> like this:</p>
<pre>
print "Hello!"
print "You are the 10th caller!"
print "Congratulations!"
</pre>
<p>and you include it in the template:</p>
<pre>
if ShouldPrintStuff():
{{>PRINT_STUFF}}
else:
pass
</pre>
<p>then when it is expanded, all three print lines will be indented,
not just the first one:</p>
<pre>
if ShouldPrintStuff():
print "Hello!"
print "You are the 10th caller!"
print "Congratulations!"
else:
pass
</pre>
<p>Note that this behavior is immaterial when using <A
HREF="#expand"><code>STRIP_WHITESPACE</code></A>, since in that case
all leading whitespace is stripped.</p>
<h3> <A name="expand">Expanding a Template</A> </h3>
<p>Once you have a template dictionary, it's simplicity itself to
expand the template with those dictionary values, putting the output
in a string:</p>
<pre>
ctemplate::TemplateDictionary dict("debug-name");
FillDictionary(&dict, ...);
string output;
bool error_free = <font color=red>ctemplate::ExpandTemplate(<filename>, ctemplate::STRIP_WHITESPACE, &dict, &output);</font>
// output now holds the expanded template.
// ExpandTemplate returns false if the system cannot load-and-parse
// <filename> or any of the template files referenced by the
// TemplateDictionary.
</pre>
<p>The first argument to <code>ExpandTemplate</code> is the filename
holding the template to expand (though there are ways to use <A
HREF="#string">non-file-based templates</A> as well). The second argument
is the "strip" mode, which specifies how to treat whitespace in the
template. It can take the following values:</p>
<ul>
<li> <code>ctemplate::DO_NOT_STRIP</code>: do nothing. This expands
the template file verbatim.
<li> <code>ctemplate::STRIP_BLANK_LINES</code>: remove all blank
lines. This ignores any blank lines found in the template file
when parsing it. When the template is html, this reduces the
size of the output text without requiring a sacrifice of
readability for the input file.
<li> <code>ctemplate::STRIP_WHITESPACE</code>: remove not only blank
lines when parsing, but also whitespace at the beginning and
end of each line. It also removes any linefeed (possibly
following whitespace) that follows a closing <code>}}</code> of
any kind of template marker <i>except</i> a template variable.
(This means a linefeed may be removed anywhere by simply
placing a comment marker as the last element on the line.)
When the template is html, this reduces the size of the output
html without changing the way it renders (except in a few
special cases.) When using this flag, the built-in template
variables <code>BI_NEWLINE</code> and <code>BI_SPACE</code> can
be useful to force a space or newline in a particular
situation.
</ul>
<p>The expanded template is written to the string <code>output</code>.
If <code>output</code> was not empty before calling
<code>Expand()</code>, the expanded template is appended to the end of
<code>output</code>.
<p>There is also a "power user" version of
<code>ExpandTemplate()</code>, called <code>ExpandWithData()</code>,
that allows you to pass in per-expand data. Another "power user"
version allows you to expand the template into a custom output
container, rather than a string. See the <A
HREF="reference.html#per_expand_data">reference guide</A> for more
information about these advanced methods.</p>
<h3> <A name="string">Getting a Template From a String Rather Than a File</A> </h3>
<p>The first argument to <code>ExpandTemplate</code> is named
"filename", suggesting that the template has to be read from an
on-disk file. But in reality, the "filename" argument is just a key
into an internal cache. (By default, the template system looks on
disk to satisfy a cache miss, hence the "filename" to describe this
variable.) If you have a template specified in a string rather than a
file, you can manually insert it into the cache via
<code>ctemplate::StringToTemplateCache()</code>.</p>
<p><code>StringToTemplateCache()</code> parses the string you pass in
as if it were a template file, and inserts it into the global cache
with the key and strip-mode that you provide. You can then use this
key and strip-mode as the first two arguments to
<code>ExpandTemplate</code>. You can also use the key as the argument
to <code>ctemplate::TemplateDictionary::SetFilename()</code>.</p>
<p>Prefer file-based to string-based templates where possible.
Updating a file-based template requires merely a data push, rather
than pushing the new executable, and it also makes it easier for
non-programmers to modify the template. One reason to use
string-based templates is if you are in an environment where having
data files could be dangerous—for instance, you work on a disk
that is usually full, or need the template to work even in the face of
disk I/O errors.</p>
<p>This package comes with a script, <A
HREF="reference.html#template_converter">template-converter</A>, that
takes a template file as input and emits a C++ code snippet (an .h
file) that defines a string with those template contents. This makes
it easy to start by using a normal, file-based template, and then
switch to <code>StringToTemplateCache()</code> later if you so
desire.</p>
<h3> Copying a Template Dictionary </h3>
<p>You can use the <code>MakeCopy()</code> method on a template
dictionary to make a "deep" copy of the template. This can be useful
for situations like the following: you want to fill a template several
times, each time with 90% of the values the same, but the last 10%
different. Computing the values is slow. Here's how you can use
<code>MakeCopy()</code> to do it:</p>
<ol>
<li> fill dict with 90%
<li> <code>newdict1 = dict->MakeCopy();</code>
<li> fill newdict1 with last 10%
<li> <code>newdict2 = dict->MakeCopy();</code>
<li> fill newdict2 with last 10%
<li> etc.
</ol>
<h3> The Template Cache </h3>
<p>When templates are loaded from disk, they are stored in an internal
template cache, which is used by <code>ExpandTemplate()</code> and
(most obviously) <code>StringToTemplateCache()</code>. You can define
your own template cache with the <code>TemplateCache</code> class.</p>
<p>This is an advanced technique used when you want to support having
several versions of a template file in memory at the same time (for
instance, a webserver might want to keep an old version of a template
file around until all old requests using that template are done being
serviced). It also supports advanced operations like removing a
template from the cache, and reloading templates from disk if they
have changed.</p>
<p>See the <A HREF="reference.html#template_cache">reference
manual</A> for more details about the template cache.</p>
<h3> Template and Threads </h3>
<p>All expansion functions and static <code>TemplateDictionary</code>
methods are threadsafe: you can safely call
<code>ctemplate::TemplateDictionary::SetGlobalValue()</code>
without needing to worry about locking.</p>
<p>Non-static <code>TemplateDictionary</code> methods are not
thread-safe. It is not safe for two threads to assign values to the
same template-dictionary without doing their own locking. Note that
this is expected to be quite rare: usually only one thread will care
about a given template-dictionary.</p>
<h2> <a name="testing_templates">Testing Templates</a> </h2>
<p>Templates have the advantage that they separate the presentation of
your data from the application logic that generates the data.
Naturally, you want to do the same for testing: you would like to test
the application's <i>logic</i> in a way that is robust to changes in
the <i>presentation</i>.</p>
<p>The easiest way to test this logic is with unit tests that exercise
the functions in your code that fill template dictionaries. The class
<code>ctemplate::TemplateDictionaryPeer</code> in
<code>template_test_util.h</code> is designed to help you do exactly
that.</p>
<p>Here's a sample test using <code>TemplateDictionaryPeer</code>:</p>
<pre>
void MyTestMethod() {
// Create and populate the dictionary as your app normally would.
// In this case, we create a dict with data like this:
// { color:blue,
// shape_section: [
// { size:big, num_sides:7 },
// { size:big, num_sides:7 },
// { size:big, num_sides:7 }
// ]
// }
MyObject obj;
ctemplate::TemplateDictionary dict;
obj.FillDictionary(&dict);
// Create a TemplateDictionaryPeer to gain access to the dict contents.
ctemplate::TemplateDictionaryPeer peer(&dict);
// Expect color:blue at the top level of this dictionary.
EXPECT_STREQ("blue", peer.GetSectionValue("color"));
// Fetch sub-dictionaries from the dict.
vector<const ctemplate::TemplateDictionary*> shape_dicts;
peer.GetSectionDictionaries("shape_section", &shape_dicts);
EXPECT_EQ(3, shape_dicts.size());
for (int i = 0; i < 3; ++i) {
// Create another peer for each sub-dict, and assert that each sub-dict
// contains the expected data.
ctemplate::TemplateDictionaryPeer shape_peer(dicts[i]);
EXPECT_STREQ("big", shape_peer.GetSectionValue("size"));
EXPECT_STREQ("7", shape_peer.GetSectionValue("num_sides"));
}
}
</pre>
<p>Note that by using <code>TemplateDictionaryPeer</code>, you can
unit test the code for filling a <code>TemplateDictionary</code>
independent of the consuming <code>Template</code>.</p>
<p>The above tests your dictionary filling functions, but doesn't
touch the template expansion. Naturally, you may also want to test
the template itself. In this case, you will want to avoid using your
program's dictionary filling functions, and will instead provide a
custom dictionary in your test. There are a variety of properties you
might want to test about the template, but here are a few sample
tests:</p>
<pre>
void TestTemplateHTMLEscapesColor() {
// Populate a dictionary that lets us exercise the condition we're testing.
// In this case, that the 'color' tag will be HTML escaped.
ctemplate::TemplateDictionary dict("t1");
dict.SetValue("color", "<blue>");
// Expand the template with this dictionary.
string result;
ctemplate::ExpandTemplate(FLAGS_test_srcdir + "templates/my_template.html",
ctemplate::STRIP_WHITESPACE, &dict, &result);
// Assert that the expansion has the appropriate text in it.
EXPECT_THAT(result, HasSubstr("&lt;blue&gt;"));
}
void TestColorAppearsBeforeShape() {
// This time, the condition under test is that the "color" element of
// the dictionary appears before the "shape" element.
// Create an appropriate dictionary.
ctemplate::TemplateDictionary dict("t2"); // Note: use sufficiently unique
dict.SetValue("color", "white_asdf"); // strings that they won't occur
dict.SetValue("shape", "square_asdf"); // "bare" in the template.
string result;
ctemplate::ExpandTemplate(FLAGS_test_srcdir + "templates/my_template.html",
ctemplate::STRIP_WHITESPACE, &dict, &result);
// Assert that color comes before shape.
EXPECT_THAT(result, ContainsRegex("white_asdf.*square_asdf"));
}
</pre>
<h2> <A NAME="security">Security Considerations</A> </h2>
<p>Like all web applications, programs that use the Ctemplate
System to create HTML documents can be vulnerable to
Cross-Site-Scripting (XSS) attacks unless data inserted into a
template is appropriately sanitized and/or escaped. Which specific
form of escaping or sanitization is required depends on the context in
which the template variable appears within a HTML document (such as,
regular "inner text", within a <code><script></code> tag, or
within an <code>onClick</code> handler).
<p>If you are concerned with XSS, your are strongly encouraged to
leverage the <a href="auto_escape.html">Auto Escape</a> mode developed
specifically to better defend your application against XSS. The Auto
Escape mode follows the guidelines outlined below. Do note however
that regardless of whether you use Auto Escape or not, escaping alone
while generally required, is often not enough! You also may need to
sanitize or validate the input, as for instance with URL attributes.
For further information, refer to additional <a
href="xss_resources.html">resources</a> on Cross-Site-Scripting
issues.</p>
The remainder of this section provides a brief summary of techniques
to prevent XSS vulnerabilities due to template variables in various
HTML contexts.
<ol class=bluelist>
<li> Regular text (outside of tags and other special situations).
<p>Use the auto-escape pragma to html-escape the variable.</p>
</li>
<li> HTML tag attributes.
<p>In addition to the auto-escape pragma, ensure that the
attribute is enclosed in double quotes in the template.</p>
</li>
<li> URL attributes (eg., href/src).
<p>In addition to the auto-escape pragma, ensure that the
attribute is enclosed in double quotes in the template.</p>
</li>
<li> Beware of inserting variables containing data from untrusted
sources into the context of a <code>style</code> tag or
attribute.
<p>Certain CSS style-sheet constructs can result in the
invocation of javascript. To prevent XSS, the variable must be
carefully validated and sanitized.</p>
</li>
<li> Populating javascript variables.
<p>In addition to the auto-escape pragma, ensure that the
literal is enclosed in quotes in the template:</p>
<pre>
<script>
var msg_text = '{{MESSAGE}}';
</script>
</pre>
<p>Literals of non-string types cannot be quoted and escaped.
Instead, ensure that the variable's value is set such that it is
guaranteed that the resulting string corresponds to a javascript
literal of the expected type. For example, use</p>
<pre>
dict->SetValueInt("NUM_ITEMS", num_items);
</pre>
<p>to populate an integer javascript variable in the template
fragment</p>
<pre>
<script>
var num_items = {{NUM_ITEMS}};
</script>
</pre>
</li>
<li> Populating javascript variables within event handlers such as
<code>onClick</code>.
<p>Tag attributes whose values are evaluated as a javascript
expression (such as <code>on{Click,Load,etc}</code> handlers)
generally require HTML-Escape in addition to Javascript-Escape,
since the attribute's value is HTML-unescaped by the browser
before it is passed to the javascript interpreter.</p>
<p>However, the javascript-escaping provided by auto-escape
makes a subsequent HTML-Escape unnecessary. As such you can
apply the same rules for variables within event handlers
as you would for javascript variables in string literals:</p>
<pre>
<button ...
onclick='GotoUrl("{{TARGET_URL}}");'>
</pre>
</li>
<li> Consider potential non-template sources of XSS.
<p>There are a number of scenarios in which XSS can arise that
are unrelated to the insertion of values into HTML templates,
including,</p>
<ul class=blacklist>
<li> injection into HTTP headers such as <code>Location</code>,</li>
<li> incorrect browser-side guess of the content-encoding of a HTML
document without explicitly specified <code>charset</code>,</li>