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