blob: 723065bbdca7266e1563c0fba6477f6e6e0a2493 [file] [log] [blame]
Brian Silverman70325d62015-09-20 17:00:43 -04001
2<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
3<html>
4<head>
5<title>Tips and Guidelines for Using the Ctemplate System</title>
6
7<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
8<link href="designstyle.css" type="text/css" rel="stylesheet">
9<style type="text/css">
10 ol.bluelist li {
11 color: #3366ff;
12 font-family: sans-serif;
13 }
14 ol.bluelist li p {
15 color: #000;
16 font-family: "Times Roman", times, serif;
17 }
18 ul.blacklist li {
19 color: #000;
20 font-family: "Times Roman", times, serif;
21 }
22</style>
23</head>
24
25<body>
26
27<h1>Tips and Guidelines for Using the Ctemplate System</h1>
28<small>(as of 10 March 2010)</small>
29
30<br>
31
32<p>The <A HREF="guide.html">basic rules</A> of the template system are
33enough to use it, but over time, we at Google have developed some
34tips, guidelines, and best practices that make it easier to use
35templates effectively, and to avoid common template errors.</p>
36
37
38<h2> Program Design Considerations </h2>
39
40<h3> <a name=versioning>Template naming and versioning</a> </h3>
41
42<p> Early in Google's use of templates, we noticed a problem: if a
43binary that uses a template and its corresponding template were both
44modified, particularly if the change were such that the old binary
45could not work with the new template or the new binary could not work
46with the old template, then somehow they both had to be deployed at
47the same instant to not present errors to our users. This was hard to
48do. The solution was to adopt a template naming and versioning
49convention. The procedure to use it follows:</p>
50
51<ul>
52 <li> Each template name ends with <code>_postYYYYMMDD.tpl</code>,
53 where YYYMMDD is the date of this version's initial
54 creation. </li>
55
56 <li> Before making (non-backward-compatible) modifications to a
57 template, copy the template to a new name, incorporating a
58 later date than the original one being copied. </li>
59
60 <li> Edit the new file, and push it to the production server. </li>
61
62 <li> Finally, update the code to refer to the new template-name
63 (ideally, using the <A
64 HREF="guide.html#register"><code>RegisterTemplateFilename</code>
65 idiom</A>), and push the new executable to the production
66 server. </li>
67</ul>
68
69<p>When this convention is followed, the new template file does not
70overwrite the old one when it is deployed, because it is a new file
71with a new name. The old template file is still there to be used as
72long as the old binary is still in production and the new template
73file just sits there being ignored. Then when the new binary finally
74gets deployed, it immediately starts using the new template file,
75because it is coded (in <code>RegisterTemplateFilename</code>) to do
76so. After that, it is the old template file that continues to sit
77there ignored.</p>
78
79<p>The <A
80HREF="reference.html#make_tpl_varnames_h"><code>make_tpl_varnames_h</code>
81utility</A> knows about the "_postYYYYMMDD" naming convention, so it
82is important that you use that convention exactly if you use the
83<code>make_tpl_varnames_h</code>.</p>
84
85
86<h3> Processing Phases </h3>
87
88<p>Typically a program using the Ctemplate System will
89perform the following phases, usually in this order:</p>
90
91<ol>
92 <li> Retrieve and prepare the data used to fill a dictionary. </li>
93
94 <li> Build the data dictionary, including all its
95 sub-dictionaries, that will supply the values to the
96 designated template object, its sections, and its
97 included templates. </li>
98
99 <li> Retrieve the top-level template object required to
100 format the data. (This may or may
101 not involve reading and parsing a template file,
102 depending on whether the requested file has already
103 been read and parsed by the running program or
104 whether that file has been marked "reload if changed"
105 and was in fact changed.) </li>
106
107 <li> Expand the template object into an output buffer
108 using the completed data dictionary. </li>
109
110 <li> Output the buffer. </li>
111
112 <li> Clean up: Destroy the top-level data dictionary
113 whenever it is no longer needed. </li>
114
115 <li> Optionally, clear the cache at the end of program
116 execution. </li>
117</ol>
118
119
120<h3> <A NAME="oneone">One template / One procedure call</A> </h3>
121
122<p> Most of the code of the program will be in Phases 1 and
1232. Clearly, Phase 1 is outside the scope of the template system. But
124in designing the code for Phase 2 (building the data dictionary), it
125is wise to have the structure of the program reflect the structure of
126the templates being used. Specifically, there should be a single
127procedure call to build the dictionary for a single template. That
128procedure call should take parameters that include all the data
129required to populate the data dictionary for that template and all the
130templates it includes. Following this "one template/one procedure
131call" guideline further, for each included template, another procedure
132should be called to populate the (or <i>each</i>) data dictionary for
133that included template. This maintains the "one template/one procedure
134call" principle in a nested fashion that reflects the nesting of the
135templates.</p>
136
137<p> This is not to imply that the "one procedure call" for a template
138should not be modularized into sub-procedures for readability and
139maintainability, or that it should not call other auxilliary
140procedures for such things as formatting the data and converting it to
141the appropriate strings, etc. But it does mean that there should be
142one entry point for building the dictionary tree for one template and
143that entry point should show the data dependencies of that template
144through its parameter list. This code for populating the data
145dictionary should <i>NOT</i> be intermingled with data gathering code
146that should have been done in Phase 1.</p>
147
148<p>(Inside Google, the convention has been used to name the dictionary
149building procedure using the pattern <code>fill_..._dictionary</code>
150where the dots are related to the name of the template the data is
151being prepared for. For instance, the data for the template named
152one_search_result.tpl might be placed in a dictionary via a function
153named <code>fill_one_search_result_dictionary</code>.)
154
155
156<h2> <A name=tips>Tips, Idioms, and Conventions</a> </h2>
157
158<ol class=bluelist>
159
160<li> Choose template names to create unique constant prefixes.
161
162 <p>Template names should contain <em>at least two words</em>
163 to avoid constant prefix clashes (e.g. <code>kxy_</code>
164 instead of <code>kx_</code> ) The name of a new template
165 should be checked against the existing names before
166 proceeding. If your new template name produces a prefix that
167 conflicts with an already existing template, you should change
168 the name of your new template, even though it may be the only
169 perfect name you can come up with. You'll have to use a less
170 than perfect name in that case. (See "Template Syntax Checker
171 and Header File Generator" below for more explanation about
172 constant prefixes.)</p> </li>
173
174<li> <a name="tip_setformattedvalue"></a>Use SetFormattedValue
175 discriminately.
176
177 <p> This method should never be used to sneak HTML into the
178 executable as in</p>
179
180 <pre>
181 dictionary->SetFormattedValue(kxy_VAR,
182 "&lt;b&gt;%s&lt;/b&gt;",
183 some_const_char_string);
184 </pre>
185
186 <p>In that case, the <code>&lt;b&gt;</code> and
187 <code>&lt;/b&gt;</code> should be moved into the template.</p>
188
189<li> Never have a section encompass an entire template.
190
191 <p>If the first line of a template is a start section marker
192 and the last line is its matching end section marker, then
193 those markers are unnecessary in almost all cases. They are
194 usually put there to allow the entire template to be hidden or
195 iterated, but since it encompasses the entire file, the
196 section may be hidden by not expanding the file (or by hiding
197 the template-include section that includes the file) and it
198 may be iterated by iterating the template-include marker of
199 the including template. (The only exception might be if the
200 entire page is to be iterated, but this seems a bit of a
201 stretch.)</p> </li>
202
203<li> An included template is just a section whose contents are
204 located in a separate file. You may iterate over it just
205 like you do sections.
206
207 <p>For example, if your template has the following
208 template-include marker:</p>
209 <pre>
210 {{>MY_INCLUDED_TEMPLATE}}
211 </pre>
212 <p>you may call</p>
213 <pre>
214 ctemplate::TemplateDictionary *child_dict =
215 dictionary->AddIncludeDictionary(kxy_MY_INCLUDED_TEMPLATE);
216 </pre>
217 <p>to iterate that section. (Note: Make sure you call
218 <code>child_dict->SetFilename()</code>! If your included
219 template is not showing in the output, this is the first thing
220 you should check.)</p> </li>
221
222<li> The recommended idiom to fill an include-template dictionary is
223 like this:
224 <pre>
225 fill_include_template_dictionary(dict->AddIncludeDictionary(name), ...);
226 </pre>
227
228 <p>But what do you do if you decide, in
229 <code>fill_include_template_dictionary</code>, that you don't
230 want to display anything for this include-template after all? It
231 seems like it's too late: you've already created the
232 sub-dictionary. The solution is simple: just be sure that
233 <code>fill_include_template_dictionary()</code> doesn't call
234 <code>SetFilename()</code> in that case.</p>
235
236<li> Never have a section which only contains another section.
237 <p>For example, don't do this:</p>
238 <pre>
239 {{#OUTER_SECTION}}
240 {{#INNER_SECTION}}
241 section contents here
242 {{/INNER_SECTION}}
243 {{/OUTER_SECTION}}
244 </pre>
245 <p>or this equivalent template code (see the previous item):</p>
246 <pre>
247 {{#OUTER_SECTION}}
248 {{>INCLUDED_SECTION}}
249 {{/OUTER_SECTION}}
250 </pre>
251
252 <p>This is usually done because the developer thinks the outer
253 section must be used to hide the section when the inner
254 section, intended for iteration, has no iterations. In both
255 cases, you should only have one section (either
256 <code>INNER_SECTION</code> or <code>INCLUDED_SECTION</code> in
257 the examples) and iterate that section either 0 times or more
258 than 0 times. It's the wonder of the dual use of sections,
259 i.e. that they may be conditional or iterative or, in this case,
260 both.</p>
261
262 <p>A related suggestion: Do not have a section whose entire
263 contents is one variable marker with nothing else, unless you
264 need to iterate over that section with multiple values of that
265 variable. You don't need the surrounding section just to hide
266 the marker. A variable marker that is not set, does not
267 produce output. By convention, we set such variables to the
268 empty string. But in neither case do you need to hide it by
269 hiding a surrounding section that contains nothing else.</p>
270
271<li> Use this hide/show idiom for <code>if-else</code> blocks.
272
273 <p>Since sections are hidden by default, you can use represent
274 if-else logic in your code via <code>ShowSection</code>. For
275 example:</p>
276
277 <pre>
278 if ( my_test ) {
279 dict->ShowSection(kxyz_TRUE_BLOCK);
280 [ more code to fill the values for that section]
281 } else {
282 dict->ShowSection(kxyz_FALSE_BLOCK);
283 [ more code to fill the values for that section]
284 }
285 </pre>
286
287<li> <code>Write...</code> vs. <code>Fill...Dictionary</code> methods
288 - Observe the proper division of labor, don't mix them.
289
290 <p>The output (or write) function should create the top level
291 template dictionary, call one or more fill-dictionary routines
292 with it, then get the template and expand it. It should not call
293 dictionary modifying methods, like <code>ShowSection</code>
294 and <code>SetValue</code>. By keeping these separated into
295 their own fill-dictionary routine, the code is more modular and
296 lends itself to template re-use. If you maintain the proper
297 division of labor, the template you are filling and outputting
298 may be filled and included in a larger template by someone
299 else.</p> </li>
300
301<li> Use <code>AddSectionDictionary</code> only when you want to
302 iterate over a section or, secondarily, if you need to avoid name
303 conflicts.
304
305 <p>Sometimes developers get the idea that every section requires
306 its own child dictionary created by an
307 <code>AddSectionDictionary</code> call. Because of variable
308 inheritence, this isn't usually so. The intended purpose of
309 <code>AddSectionDictionary</code> is to enable iteration over a
310 section. Secondarily, if the section contains generic names that
311 may conflict with the same name in other parts of the template,
312 it may be safer to call <code>AddSectionDictionary</code> to
313 create a separate namespace. In any case, do not assume you must
314 call <code>AddSectionDictionary</code> just because you are
315 working within a section. The main dictionary can be used for all
316 levels of conditional sections as long as you avoid name
317 conflicts by keeping the marker names unique.</p> </li>
318
319<li> Do not place <code>RegisterTemplateFilename</code>
320 statements in header (<code>.h</code>) files.
321
322 <p><code>RegisterTemplateFilename</code> is a macro that
323 instantiates a <code>TemplateNamelist</code> object. If you place
324 it in a header file, a different object will get created each time
325 it is included in another <code>.cc</code> file.
326
327 <p>The <code>RegisterTemplateFilename</code> statement and its
328 associated <code>#include</code> of the <code>varnames.h</code>
329 file should occur only in the <code>.cc</code> file that
330 implements the fill-dictionary routine for that template. You
331 should never have more than one
332 <code>RegisterTemplateFilename</code> for a single template and
333 you should try hard not to copy the <code>#include</code> file to
334 other files as well. The template versioning makes this more
335 important because a developer may not know that the template name
336 with included version number needs to be updated in more than one
337 file when versioning occurs. [Also see above for more information
338 about what routine uses the filename declared by the
339 <code>RegisterTemplateFilename</code> statement.]</p> </li>
340
341<li> Never reference more than one template in a
342 fill...dictionary method.
343
344 <p>Each template should have its own fill-dictionary
345 routine. That routine should only reference marker names defined
346 in that template. If this convention is followed, then all the
347 prefixes in a fill-dictionary routine will be the same. [Note
348 that an implication of this convention is that if the template
349 includes another template, via a template-include marker, then
350 containing template's fill-dictionary routine should call the
351 included template's fill-dictionary routine (being careful to
352 observe the convention described above). But
353 then, this is merely a restatement of <A HREF="#oneone">"One
354 template / One procedure call"</A>.]</p> </li>
355
356<li> Have fill...dictionary call <code>SetFilename</code> even if the
357 dictionary is never used for a template-include.
358
359 <p>SetFilename() is required when a dictionary is created via
360 <code>AddIncludeDictionary()</code>. However, it's safe to set
361 all the time. By setting it always, you make the code work
362 properly if this dictionary ever changes to be template-included
363 after all. Even if not, by saying what template file the
364 dictionary is intended to go with, you are self-documenting your
365 code.</p> </li>
366
367<li> Do not call <code>c_str()</code> on strings to pass them to
368 <code>TemplateDictionary</code> methods.
369
370 <p>Note that all the TemplateDictionary methods are defined to
371 take <code>TemplateString</code> objects. These are created
372 automatically from both strings and char*'s (and can be created
373 manually if you have a char* and a length). So if you have a
374 string, it's safe and efficient to just pass it in directly; you
375 do not need to extract the const char * from your string object
376 to pass it to these methods. For some reason, this is a common
377 error of novice template coders.</p>
378
379 <p>The one exception to this rule is when using the method
380 <code>SetFormattedValue</code>. When calling that
381 method, you must call <code>c_str()</code> on strings that are to
382 be inserted
383 into the format string, just as you would when providing data for
384 any other printf format string.</p> </li>
385
386<li> Do not use <code>SetGlobalValue</code> when you could use
387 <code>SetValue</code> or <code>SetTemplateGlobalValue</code>.
388
389 <p><code>SetGlobalValue</code> should be used quite rarely, for
390 constants that really are consistent across all your templates.
391 It's slower to look up a value in the global dictionary than it
392 is in the template-specific dictionary.</p> </li>
393
394<li> Do not use <code>StringToTemplateCache</code> unless you have
395 a specific need for its non-file-based attributes.
396
397 <p><code>ctemplate::StringToTemplateCache</code> was created for
398 use in highly constrained cases where file I/O may be impaired or
399 undesirable, for instance to produce a server error message
400 where there may be disk problems or to produce formatted
401 output where there are processes that do not have a facility
402 for updating data files dynamically. It is not recommended for
403 ordinary use since it cannot be updated dynamically via a
404 data-push; changes always require a binary push.</p>
405 </ul>
406 </li>
407
408<li> Use <A HREF="auto_escape.html">auto-escaping</A> to prevent
409 Cross-Site-Scripting security vulnerabilities.
410
411 <p>Use <code>{{%AUTOESCAPE}}</code> consistently. Use the
412 <code>:none</code> modifier to override autoesacping only in
413 those (usually rare) cases where there is a specific reason the
414 template variable should not be escaped, for example:
415 <ul class=blacklist>
416 <li>The template variable contains HTML markup that should be
417 interpreted by the browser. In this case you must be very careful to
418 ensure that the variable can in no case contain "harmful" HTML. Also,
419 keep in mind the <a href="#tip_setformattedvalue">above
420 recommendation</a> on the use of <code>SetFormattedValue</code> and
421 consider moving the HTML markup into the template.</li>
422
423 <li>The variable is known to be already escaped at the point it
424 is inserted into the template (for example, the value might be
425 kept in escaped form in a storage backend). Here, escaping again
426 via a variable-modifier would result in "double escaping". You
427 must ensure that the variable comes escaped in the appropriate
428 context (that is, if you're inserting the variable into an html
429 document, it's html-escaped and not java-escaped).</li>
430 </ul>
431 </li>
432
433<li> Do not leave an extra space when using <code>{{BI_SPACE}}</code>
434
435 <p>The built-in template variable <code>BI_SPACE</code> is itself
436 replaced by a single space. It is used where you need to make
437 sure a space is preserved at the end of a line. It is a common
438 mistake to leave an extra space before this marker, which results
439 in not one, but two, spaces created in the document.</p>
440
441 <p>Incorrect:</p><pre>
442&lt;table border=0 {{BI_SPACE}}
443 align=center></pre>
444
445 <p>Correct:</p><pre>
446&lt;table border=0{{BI_SPACE}}
447 align=center></pre>
448
449 </li>
450
451</ol>
452
453<hr>
454<ul>
455 <li> <A HREF="guide.html">User's Guide</A> </li>
456 <li> <A HREF="reference.html">Reference Manual</A> </li>
457 <li> <A HREF="auto_escape.html">Auto Escape</A> </li>
458<!--
459 <li> <A HREF="tips.html">Tips</A> </li>
460-->
461 <li> <A HREF="example.html">Example</A> </li>
462</ul>
463
464<hr>
465<address>
466Craig Silverstein<br>
467<script type=text/javascript>
468 var lm = new Date(document.lastModified);
469 document.write(lm.toDateString());
470</script>
471</address>
472
473</body>
474</html>