/usr/share/doc/racket/web-server/templates.html is in racket-doc 6.7-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><title>7 Templates: Separation of View</title><link rel="stylesheet" type="text/css" href="../scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="../racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../doc-site.css" title="default"/><script type="text/javascript" src="../scribble-common.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../doc-site.js"></script><script type="text/javascript" src="../local-redirect/local-redirect.js"></script><script type="text/javascript" src="../local-redirect/local-user-redirect.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="doc-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_0");">▼</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">Web Applications in Racket</a></td></tr></table></div><div class="tocviewsublisttop" style="display: block;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1 </td><td><a href="run.html" class="tocviewlink" data-pltdoc="x">Running Web Servlets</a></td></tr><tr><td align="right">2 </td><td><a href="servlet.html" class="tocviewlink" data-pltdoc="x">Stateful Servlets</a></td></tr><tr><td align="right">3 </td><td><a href="stateless.html" class="tocviewlink" data-pltdoc="x">Stateless Servlets</a></td></tr><tr><td align="right">4 </td><td><a href="http.html" class="tocviewlink" data-pltdoc="x">HTTP:<span class="mywbr"> </span> Hypertext Transfer Protocol</a></td></tr><tr><td align="right">5 </td><td><a href="dispatch.html" class="tocviewlink" data-pltdoc="x">URL-<wbr></wbr>Based Dispatch</a></td></tr><tr><td align="right">6 </td><td><a href="formlets.html" class="tocviewlink" data-pltdoc="x">Formlets:<span class="mywbr"> </span> Functional Form Abstraction</a></td></tr><tr><td align="right">7 </td><td><a href="" class="tocviewselflink" data-pltdoc="x">Templates:<span class="mywbr"> </span> Separation of View</a></td></tr><tr><td align="right">8 </td><td><a href="page.html" class="tocviewlink" data-pltdoc="x">Page:<span class="mywbr"> </span> Short-<wbr></wbr>hand for Common Patterns</a></td></tr><tr><td align="right">9 </td><td><a href="test.html" class="tocviewlink" data-pltdoc="x">Testing Servlets</a></td></tr><tr><td align="right">10 </td><td><a href="faq.html" class="tocviewlink" data-pltdoc="x">Troubleshooting and Tips</a></td></tr><tr><td align="right"></td><td><a href="doc-index.html" class="tocviewlink" data-pltdoc="x">Index</a></td></tr></table></div></div><div class="tocviewlist"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,"tocview_1");">►</a></td><td>7 </td><td><a href="" class="tocviewselflink" data-pltdoc="x">Templates:<span class="mywbr"> </span> Separation of View</a></td></tr></table><div class="tocviewsublistbottom" style="display: none;" id="tocview_1"><table cellspacing="0" cellpadding="0"><tr><td align="right">7.1 </td><td><a href="#%28part._.Static%29" class="tocviewlink" data-pltdoc="x">Static</a></td></tr><tr><td align="right">7.2 </td><td><a href="#%28part._.Dynamic%29" class="tocviewlink" data-pltdoc="x">Dynamic</a></td></tr><tr><td align="right">7.3 </td><td><a href="#%28part._.Gotchas%29" class="tocviewlink" data-pltdoc="x">Gotchas</a></td></tr><tr><td align="right">7.4 </td><td><a href="#%28part._.Escaping%29" class="tocviewlink" data-pltdoc="x">Escaping</a></td></tr><tr><td align="right">7.5 </td><td><a href="#%28part._.H.T.T.P_.Responses%29" class="tocviewlink" data-pltdoc="x">HTTP Responses</a></td></tr><tr><td align="right">7.6 </td><td><a href="#%28part._.A.P.I_.Details%29" class="tocviewlink" data-pltdoc="x">API Details</a></td></tr><tr><td align="right">7.7 </td><td><a href="#%28part._.Conversion_.Example%29" class="tocviewlink" data-pltdoc="x">Conversion Example</a></td></tr></table></div></div></div><div class="tocsub"><div class="tocsubtitle">On this page:</div><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">7.1<tt> </tt></span><a href="#%28part._.Static%29" class="tocsubseclink" data-pltdoc="x">Static</a></td></tr><tr><td><span class="tocsublinknumber">7.2<tt> </tt></span><a href="#%28part._.Dynamic%29" class="tocsubseclink" data-pltdoc="x">Dynamic</a></td></tr><tr><td><span class="tocsublinknumber">7.3<tt> </tt></span><a href="#%28part._.Gotchas%29" class="tocsubseclink" data-pltdoc="x">Gotchas</a></td></tr><tr><td><span class="tocsublinknumber">7.4<tt> </tt></span><a href="#%28part._.Escaping%29" class="tocsubseclink" data-pltdoc="x">Escaping</a></td></tr><tr><td><span class="tocsublinknumber">7.5<tt> </tt></span><a href="#%28part._.H.T.T.P_.Responses%29" class="tocsubseclink" data-pltdoc="x">HTTP Responses</a></td></tr><tr><td><span class="tocsublinknumber">7.6<tt> </tt></span><a href="#%28part._.A.P.I_.Details%29" class="tocsubseclink" data-pltdoc="x">API Details</a></td></tr><tr><td><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="tocsubnonseclink" data-pltdoc="x"><span class="RktSym"><span class="RktStxLink">include-<wbr></wbr>template</span></span></a></td></tr><tr><td><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._in%29%29" class="tocsubnonseclink" data-pltdoc="x"><span class="RktSym"><span class="RktStxLink">in</span></span></a></td></tr><tr><td><span class="tocsublinknumber">7.7<tt> </tt></span><a href="#%28part._.Conversion_.Example%29" class="tocsubseclink" data-pltdoc="x">Conversion Example</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><div class="navsettop"><span class="navleft"><form class="searchform"><input class="searchbox" style="color: #888;" type="text" value="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "6.7", "../");" onfocus="this.style.color="black"; this.style.textAlign="left"; if (this.value == "...search manuals...") this.value="";" onblur="if (this.value.match(/^ *$/)) { this.style.color="#888"; this.style.textAlign="center"; this.value="...search manuals..."; }"/></form> <a href="../index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("6.7");">top</a></span><span class="navright"> <a href="formlets.html" title="backward to "6 Formlets: Functional Form Abstraction"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "Web Applications in Racket"" data-pltdoc="x">up</a> <a href="page.html" title="forward to "8 Page: Short-hand for Common Patterns"" data-pltdoc="x">next →</a></span> </div><h3 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""templates"">7<tt> </tt><a name="(part._templates)"></a><a name="(mod-path._web-server/templates)"></a>Templates: Separation of View</h3><p><table cellspacing="0" cellpadding="0" class="defmodule"><tr><td align="left"><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="stt"> </span><a href="" class="RktModLink" data-pltdoc="x"><span class="RktSym">web-server/templates</span></a><span class="RktPn">)</span></td><td align="right"><span class="RpackageSpec"><span class="Smaller"> package:</span> <span class="stt">web-server-lib</span></span></td></tr></table></p><p>The Web Server provides a powerful Web template system for separating
the presentation logic of a Web application and enabling non-programmers
to contribute to Racket-based Web applications.</p><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Although all the examples here generate HTML, the template
language and the <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=scribble-pp&rel=text.html&version=6.7" class="Sq" data-pltdoc="x">Text Generation</a> it is based on can be used to generate any
text-based format: C, SQL, form emails, reports, etc.</p></blockquote></blockquote></blockquote><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""Static"">7.1<tt> </tt><a name="(part._.Static)"></a>Static</h4><p><div class="SIntrapara">Suppose we have a file <span class="stt">"static.html"</span> with the contents:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Templates in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h1>Bang!</h1></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h2>Bang!</h2></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></div></p><p><div class="SIntrapara">If we write the following in our code:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.html"</span><span class="RktPn">)</span></p></blockquote></div></p><p><div class="SIntrapara">Then the contents of <span class="stt">"static.html"</span> will be read <span style="font-style: italic">at compile time</span> and compiled into a
racket program that returns the contents of <span class="stt">"static.html"</span> as a string:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">"<html>\n</span><span class="hspace"> </span><span class="RktVal"><head><title>Fastest Templates in the West!</title></head>\n</span><span class="hspace"> </span><span class="RktVal"><body>\n</span><span class="hspace"> </span><span class="RktVal"><h1>Bang!</h1>\n</span><span class="hspace"> </span><span class="RktVal"><h2>Bang!</h2>\n</span><span class="hspace"> </span><span class="RktVal"></body>\n</html>"</span></p></blockquote></div></p><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""Dynamic"">7.2<tt> </tt><a name="(part._.Dynamic)"></a>Dynamic</h4><p><div class="SIntrapara"><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span> gives the template access to the <span style="font-style: italic">complete lexical context</span> of the including program. This context can be
accessed via the <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=scribble&rel=reader.html&version=6.7" class="Sq" data-pltdoc="x">@ Syntax</a> syntax. For example, if <span class="stt">"simple.html"</span> contains:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest @thing in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h1>Bang!</h1></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h2>Bang!</h2></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></div></p><p><div class="SIntrapara">Then
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">thing</span><span class="hspace"> </span><span class="RktVal">"Templates"</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"simple.html"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">evaluates to the same content as the static example.</div></p><p><div class="SIntrapara">There are no constraints on how the lexical context of the template is populated. For instance, you can built template abstractions
by wrapping the inclusion of a template in a function:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktSym">thing</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"simple.html"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktVal">"Templates"</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktVal">"Noodles"</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">evalutes to two strings with the predictable contents:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Templates in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h1>Bang!</h1></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h2>Bang!</h2></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></div></p><p>and</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Noodles in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h1>Bang!</h1></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h2>Bang!</h2></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></p><p>Furthermore, there are no constraints on the Racket used by templates: they can use macros, structs, continuation marks, threads, etc.
However, Racket values that are ultimately returned must be printable by the <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=scribble-pp&rel=text.html&version=6.7" class="Sq" data-pltdoc="x">Text Generation</a>.
For example, consider the following outputs of the
title line of different calls to <span class="RktSym">fast-template</span>:</p><ul><li><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">Templates</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">...<title>Fastest Templates in the West!</title>...</span></p></td></tr></table></div></p></li><li><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktVal">42</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">...<title>Fastest 42 in the West!</title>...</span></p></td></tr></table></div></p></li><li><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktVal">"Noo"</span><span class="hspace"> </span><span class="RktVal">"dles"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">...<title>Fastest Noodles in the West!</title>...</span></p></td></tr></table></div></p></li><li><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"Thunks"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">...<title>Fastest Thunks in the West!</title>...</span></p></td></tr></table></div></p></li><li><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=Delayed_Evaluation.html%23%2528form._%2528%2528lib._racket%252Fpromise..rkt%2529._delay%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">delay</a></span><span class="hspace"> </span><span class="RktVal">"Laziness"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">...<title>Fastest Laziness in the West!</title>...</span></p></td></tr></table></div></p></li><li><p><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">fast-template</span><span class="hspace"> </span><span class="RktVal">"Embedding"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">...<title>Fastest ...<title>Fastest Embedding in the West!</title>... in the West!</title>...</span></p></td></tr></table></div></p></li></ul><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""Gotchas"">7.3<tt> </tt><a name="(part._.Gotchas)"></a>Gotchas</h4><p><div class="SIntrapara">To obtain an <span class="RktInBG"><span class="hspace"></span><span class="RktIn">@</span><span class="hspace"></span></span> character in template output, you must
escape the it, because it is the escape character of the
<a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=scribble&rel=reader.html&version=6.7" class="Sq" data-pltdoc="x">@ Syntax</a> syntax. For example, to obtain:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><head><title>Fastest @s in the West!</title></head></span></p></td></tr></table></div><div class="SIntrapara">You must write:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><head><title>Fastest @"@"s in the West!</title></head></span></p></td></tr></table></div><div class="SIntrapara">as your template: literal <span class="RktInBG"><span class="hspace"></span><span class="RktIn">@</span><span class="hspace"></span></span>s must be replaced with
<span class="RktInBG"><span class="hspace"></span><span class="RktIn">@"@"</span><span class="hspace"></span></span>. (Note that the double-quotes are basically a Racket
expression, which can be used for longer strings too.)</div></p><p><div class="SIntrapara">The <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=scribble&rel=reader.html&version=6.7" class="Sq" data-pltdoc="x">@ Syntax</a> will read Racket identifiers, so it does not terminate identifiers on punctuations or XML angle brackets. So,
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><head><title>Fastest @thing in the @place!</title></head></span></p></td></tr></table></div><div class="SIntrapara">will complain that the identifier <span class="RktSym">place!</title></head></span> is
undefined. You can subvert this by explicitly delimiting the
identifier:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><head><title>Fastest @thing in the @|place|!</title></head></span></p></td></tr></table></div></p><p><div class="SIntrapara">Another gotcha is that since the template is compiled into a Racket
program, only its results will be printed. For example, suppose we
have the template:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@for[([c clients])]{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>@(car c), @(cdr c)</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div></p><p><div class="SIntrapara">If this is included in a lexical context with <span class="RktSym">clients</span> bound
to
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Young"</span><span class="hspace"> </span><span class="RktVal">"Brigham"</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cons%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">cons</a></span><span class="hspace"> </span><span class="RktVal">"Smith"</span><span class="hspace"> </span><span class="RktVal">"Joseph"</span><span class="RktPn">)</span><span class="RktPn">)</span></p></blockquote></div><div class="SIntrapara">then the template will be printed as:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div><div class="SIntrapara">because <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">for</a></span> does not return the value of the body.
Suppose that we change the template to use <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%252Flist%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">for/list</a></span> (which combines them into a list):
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@for/list[([c clients])]{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>@(car c), @(cdr c)</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div></p><p><div class="SIntrapara">Now the result is:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div><div class="SIntrapara">because only the final expression of the body of the <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%252Flist%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">for/list</a></span>
is included in the result. We can capture all the sub-expressions by
using <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list</a></span> in the body:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@for/list[([c clients])]{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@list{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>@(car c), @(cdr c)</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div><div class="SIntrapara">Now the result is:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>Young, Brigham</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>Smith, Joseph</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div></p><p><div class="SIntrapara">The templating library provides a syntactic form to deal with this
issue for you called <span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._in%29%29" class="RktStxLink" data-pltdoc="x">in</a></span>:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><table></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@in[c clients]{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>@(car c), @(cdr c)</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></table></span></p></td></tr></table></div><div class="SIntrapara">Notice how it also avoids the absurd amount of punctuation on line two.</div></p><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""Escaping"">7.4<tt> </tt><a name="(part._.Escaping)"></a>Escaping</h4><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Thanks to Michael W. for this section.</p></blockquote></blockquote></blockquote><p>Because templates are useful for many things (scripts, CSS, HTML,
etc), the Web Server does not assume that the template is for XML-like
content. Therefore when when templates are expanded, no
XML escaping is done by default. Beware of <span style="font-style: italic">cross-site scripting</span>
vulnerabilities! For example, suppose a servlet serves the following
template where <span class="RktVar">some-variable</span> is an input string supplied by
the client:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Templates in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@some-variable</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></p><p>If the servlet contains something like the following:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">some-variable</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-input-from-user</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.htm"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>There is nothing to prevent an attacker from entering
<span class="RktInBG"><span class="hspace"></span><span class="RktIn"><script type="text/javascript">...</script></span><span class="hspace"></span></span> to make the
template expand into:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Templates in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><script type="text/javascript">...</script></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></p><p>Now the server will send the attacker’s code to millions of innocent
users. To keep this from happening when serving HTML, use the
<span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528def._%2528%2528lib._xml%252Fmain..rkt%2529._xexpr-%7E3estring%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">xexpr->string</a></span> function from the <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html&version=6.7" class="RktModLink Sq" data-pltdoc="x"><span class="RktSym">xml</span></a> module.</p><p>This can be done in the servlet:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=require.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._require%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">require</a></span><span class="hspace"> </span><span class="RktSym">xml</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=let.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fletstx-scheme..rkt%2529._let%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">let</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">some-variable</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528def._%2528%2528lib._xml%252Fmain..rkt%2529._xexpr-%7E3estring%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">xexpr->string</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">get-input-from-user</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.htm"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Alternatively, make the template responsible for its own escaping:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Templates in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@(xexpr->string some-variable)</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></p><p>The improved version renders as:</p><p><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head><title>Fastest Templates in the West!</title></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">&lt;script type=\"text/javascript\"&gt;...&lt;/script&gt;</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></p><p>When writing templates, always remember to escape user-supplied input.</p><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""HTTP_Responses"">7.5<tt> </tt><a name="(part._.H.T.T.P_.Responses)"></a>HTTP Responses</h4><p><div class="SIntrapara">The quickest way to generate an HTTP response from a template is using
a <span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response~3f%29%29" class="RktValLink" data-pltdoc="x">response?</a></span> struct:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response%2Ffull%29%29" class="RktValLink" data-pltdoc="x">response/full</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">200</span><span class="hspace"> </span><span class="RktVal">#"Okay"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=time.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._current-seconds%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">current-seconds</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._.T.E.X.T%2F.H.T.M.L-.M.I.M.E-.T.Y.P.E%29%29" class="RktValLink" data-pltdoc="x">TEXT/HTML-MIME-TYPE</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Flist..rkt%2529._empty%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">empty</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=bytestrings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-%7E3ebytes%252Futf-8%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">string->bytes/utf-8</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.html"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Finally, if you want to include the contents of a template inside a larger <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528tech._x._expression%2529&version=6.7" class="techoutside Sq" data-pltdoc="x"><span class="techinside">X-expression</span></a> :
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">html</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.html"</span><span class="RktPn">)</span><span class="RktVal">)</span></p></blockquote></div><div class="SIntrapara">will result in the literal string being included (and entity-escaped). If you actually want
the template to be unescaped, then create a <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528def._%2528%2528lib._xml%252Fmain..rkt%2529._cdata%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">cdata</a></span> structure:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">html</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528def._%2528%2528lib._xml%252Fmain..rkt%2529._make-cdata%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">make-cdata</a></span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.html"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktVal">)</span></p></blockquote></div></p><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""API_Details"">7.6<tt> </tt><a name="(part._.A.P.I_.Details)"></a>API Details</h4><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><p class="RForeground"><span class="RktPn">(</span><a name="(form._((lib._web-server/templates..rkt)._include-template))"></a><span title="Provided from: web-server/templates | Package: web-server-lib"><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">include-template</a></span></span><span class="hspace"> </span><span class="RktVar">path-spec</span><span class="RktPn">)</span></p></blockquote></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktPn">#:command-char</span><span class="hspace"> </span><span class="RktVar">command-char</span><span class="hspace"> </span><span class="RktVar">path-spec</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Compiles the template at <span class="RktVar">path-spec</span> using the <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=scribble&rel=reader.html&version=6.7" class="Sq" data-pltdoc="x">@ Syntax</a> syntax within the enclosing lexical context. The <span class="RktVar">path-spec</span> is the same format used by <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=include.html%23%2528form._%2528%2528lib._racket%252Finclude..rkt%2529._include%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">include</a></span>. Use the <span class="RktVar">command-char</span> keyword to customize the escape character.</div></p><p><div class="SIntrapara">Examples:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"static.html"</span><span class="RktPn">)</span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktPn">#:command-char</span><span class="hspace"> </span><span class="RktVal">#\$</span><span class="hspace"> </span><span class="RktVal">"dollar-static.html"</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><p class="RForeground"><span class="RktPn">(</span><a name="(form._((lib._web-server/templates..rkt)._in))"></a><span title="Provided from: web-server/templates | Package: web-server-lib"><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._in%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">in</a></span></span><span class="hspace"> </span><span class="RktVar">x</span><span class="hspace"> </span><span class="RktVar">xs</span><span class="hspace"> </span><span class="RktVar">e</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></p></blockquote></td></tr></table></blockquote></div><div class="SIntrapara">Expands into
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%252Flist%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktVar">x</span><span class="hspace"> </span><span class="RktVar">xs</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">begin/text</span><span class="hspace"> </span><span class="RktVar">e</span><span class="hspace"> </span><span class="RktMeta"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=stx-patterns.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fstxcase-scheme..rkt%2529._......%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">...</a></span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p><div class="SIntrapara">Template Example:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">@in[c clients]{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><tr><td>@(car c), @(cdr c)</td></tr></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">}</span></p></td></tr></table></div></p><p><div class="SIntrapara">Racket Example:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><p><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._in%29%29" class="RktStxLink" data-pltdoc="x">in</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="hspace"> </span><span class="RktSym">clients</span><span class="hspace"> </span><span class="RktVal">"<tr><td>"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._car%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">car</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">", "</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._cdr%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">cdr</a></span><span class="hspace"> </span><span class="RktSym">c</span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktVal">"</td></tr>"</span><span class="RktPn">)</span></p></blockquote></div></p><h4 x-source-module="(lib "web-server/scribblings/web-server.scrbl")" x-source-pkg="web-server-doc" x-part-tag=""Conversion_Example"">7.7<tt> </tt><a name="(part._.Conversion_.Example)"></a>Conversion Example</h4><p>Al Church has been maintaining a blog with Racket for some years and would like to convert to <a href="" class="RktModLink" data-pltdoc="x"><span class="RktSym">web-server/templates</span></a>.</p><p><div class="SIntrapara">The data-structures he uses are defined as:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define-struct.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define-struct%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define-struct</a></span><span class="hspace"> </span><span class="RktSym">post</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">title</span><span class="hspace"> </span><span class="RktSym">body</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">posts</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-post</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"(Y Y) Works: The Why of Y"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"Why is Y, that is the question."</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-post</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"Church and the States"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"As you may know, I grew up in DC, not technically a state."</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Actually, Al Church-encodes these posts, but for explanatory reasons, we’ll use structs.</div></p><p>He has divided his code into presentation functions and logic functions. We’ll look at the presentation functions first.</p><p><div class="SIntrapara">The first presentation function defines the common layout of all pages.
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">template</span><span class="hspace"> </span><span class="RktSym">section</span><span class="hspace"> </span><span class="RktSym">body</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fxexpr..rkt%29._response%2Fxexpr%29%29" class="RktValLink" data-pltdoc="x">response/xexpr</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">html</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">head</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">title</span><span class="hspace"> </span><span class="RktVal">"Al's Church: "</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">section</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">body</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">h1</span><span class="hspace"> </span><span class="RktVal">"Al's Church: "</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">section</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">div</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">id</span><span class="hspace"> </span><span class="RktVal">"main"</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktRdr">,@</span><span class="RktSym">body</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p>One of the things to notice here is the <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=quasiquote.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._unquote-splicing%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">unquote-splicing</a></span> on the <span class="RktSym">body</span> argument.
This indicates that the <span class="RktSym">body</span> is list of <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528tech._x._expression%2529&version=6.7" class="techoutside Sq" data-pltdoc="x"><span class="techinside">X-expression</span></a>s. If he had accidentally used only <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=quasiquote.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._unquote%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">unquote</a></span>
then there would be an error in converting the return value to an HTTP response.</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">blog-posted</span><span class="hspace"> </span><span class="RktSym">title</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym">k-url</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">h2</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">title</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">p</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">body</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">h1</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">a</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">href</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">k-url</span><span class="RktVal">]</span><span class="RktVal">)</span><span class="hspace"> </span><span class="RktVal">"Continue"</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Here’s an example of simple body that uses a list of <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528tech._x._expression%2529&version=6.7" class="techoutside Sq" data-pltdoc="x"><span class="techinside">X-expression</span></a>s to show the newly posted blog entry, before continuing to redisplay
the main page. Let’s look at a more complicated body:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">blog-posts</span><span class="hspace"> </span><span class="RktSym">k-url</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._append%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">append</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=procedures.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._apply%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">apply</a></span><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._append%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">append</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%252Flist%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">for/list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym">p</span><span class="hspace"> </span><span class="RktSym">posts</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">h2</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym">post-title</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">p</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym">post-body</span><span class="hspace"> </span><span class="RktSym">p</span><span class="RktPn">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">(</span><span class="RktVal">h1</span><span class="hspace"> </span><span class="RktVal">"New Post"</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">form</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">action</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">k-url</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">input</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">name</span><span class="hspace"> </span><span class="RktVal">"title"</span><span class="RktVal">]</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">input</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">name</span><span class="hspace"> </span><span class="RktVal">"body"</span><span class="RktVal">]</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">input</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">type</span><span class="hspace"> </span><span class="RktVal">"submit"</span><span class="RktVal">]</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>This function shows a number of common patterns that are required by <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528tech._x._expression%2529&version=6.7" class="techoutside Sq" data-pltdoc="x"><span class="techinside">X-expression</span></a>s. First, <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._append%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">append</a></span> is used to combine
different <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528tech._x._expression%2529&version=6.7" class="techoutside Sq" data-pltdoc="x"><span class="techinside">X-expression</span></a> lists. Second, <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=procedures.html%23%2528def._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._apply%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">apply</a></span><span class="stt"> </span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._append%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">append</a></span> is used to collapse and combine the results of a <span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=for.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._for%252Flist%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">for/list</a></span>
where each iteration results in a list of <a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528tech._x._expression%2529&version=6.7" class="techoutside Sq" data-pltdoc="x"><span class="techinside">X-expression</span></a>s. We’ll see that these patterns are unnecessary with templates. Another
annoying patterns shows up when Al tries to add CSS styling and some JavaScript from Google Analytics to all the pages of
his blog. He changes the <span class="RktSym">template</span> function to:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">template</span><span class="hspace"> </span><span class="RktSym">section</span><span class="hspace"> </span><span class="RktSym">body</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fxexpr..rkt%29._response%2Fxexpr%29%29" class="RktValLink" data-pltdoc="x">response/xexpr</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">`</span><span class="RktVal">(</span><span class="RktVal">html</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">head</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">title</span><span class="hspace"> </span><span class="RktVal">"Al's Church: "</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">section</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">style</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">type</span><span class="hspace"> </span><span class="RktVal">"text/css"</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"body {margin: 0px; padding: 10px;}"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"#main {background: #dddddd;}"</span><span class="RktVal">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">body</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">script</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">type</span><span class="hspace"> </span><span class="RktVal">"text/javascript"</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528def._%2528%2528lib._xml%252Fmain..rkt%2529._make-cdata%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">make-cdata</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">#f</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"var gaJsHost = ((\"https:\" =="</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"document.location.protocol)"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"? \"https://ssl.\" : \"http://www.\");"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"document.write(unescape(\"%3Cscript src='\" + gaJsHost"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"+ \"google-analytics.com/ga.js' "</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"type='text/javascript'%3E%3C/script%3E\"));"</span><span class="RktPn">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">script</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">type</span><span class="hspace"> </span><span class="RktVal">"text/javascript"</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=xml&rel=index.html%23%2528def._%2528%2528lib._xml%252Fmain..rkt%2529._make-cdata%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">make-cdata</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">#f</span><span class="hspace"> </span><span class="RktVal">#f</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"var pageTracker = _gat._getTracker(\"UA-YYYYYYY-Y\");"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">"pageTracker._trackPageview();"</span><span class="RktPn">)</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">h1</span><span class="hspace"> </span><span class="RktVal">"Al's Church: "</span><span class="hspace"> </span><span class="RktRdr">,</span><span class="RktSym">section</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">div</span><span class="hspace"> </span><span class="RktVal">(</span><span class="RktVal">[</span><span class="RktVal">id</span><span class="hspace"> </span><span class="RktVal">"main"</span><span class="RktVal">]</span><span class="RktVal">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktRdr">,@</span><span class="RktSym">body</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktVal">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><blockquote class="refpara"><blockquote class="refcolumn"><blockquote class="refcontent"><p>Some of these problems go away by using here strings, as described in the documentation on
<a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=reader.html%23%2528part._parse-string%2529&version=6.7" class="Sq" data-pltdoc="x">Reading Strings</a>.</p></blockquote></blockquote></blockquote><p>The first thing we notice is that encoding CSS as a string is rather primitive. Encoding JavaScript with strings is even worse for two
reasons: first, we are more likely to need to manually escape characters such as "; second, we need to use a CDATA object, because most
JavaScript code uses characters that "need" to be escaped in XML, such as &, but most browsers will fail if these characters are
entity-encoded. These are all problems that go away with templates.</p><p><div class="SIntrapara">Before moving to templates, let’s look at the logic functions:
</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract-post</span><span class="hspace"> </span><span class="RktSym">req</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">binds</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=continue&rel=index.html%23%2528def._%2528%2528lib._web-server%252Fservlet..rkt%2529._request-bindings%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">request-bindings</a></span><span class="hspace"> </span><span class="RktSym">req</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">title</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=continue&rel=index.html%23%2528def._%2528%2528lib._web-server%252Fservlet..rkt%2529._extract-binding%252Fsingle%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">extract-binding/single</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">title</span><span class="hspace"> </span><span class="RktSym">binds</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktSym">body</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=continue&rel=index.html%23%2528def._%2528%2528lib._web-server%252Fservlet..rkt%2529._extract-binding%252Fsingle%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">extract-binding/single</a></span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">body</span><span class="hspace"> </span><span class="RktSym">binds</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=set_.html%23%2528form._%2528%2528quote._%7E23%7E25kernel%2529._set%2521%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">set!</a></span><span class="hspace"> </span><span class="RktSym">posts</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%252A%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list*</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">make-post</span><span class="hspace"> </span><span class="RktSym">title</span><span class="hspace"> </span><span class="RktSym">body</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym">posts</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="servlet.html#%28def._%28%28lib._web-server%2Fservlet%2Fweb..rkt%29._send%2Fsuspend%29%29" class="RktValLink" data-pltdoc="x">send/suspend</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">k-url</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">template</span><span class="hspace"> </span><span class="RktVal">"Posted"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">blog-posted</span><span class="hspace"> </span><span class="RktSym">title</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym">k-url</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">display-posts</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">display-posts</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">extract-post</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="servlet.html#%28def._%28%28lib._web-server%2Fservlet%2Fweb..rkt%29._send%2Fsuspend%29%29" class="RktValLink" data-pltdoc="x">send/suspend</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=lambda.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._lambda%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">lambda</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">k-url</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">template</span><span class="hspace"> </span><span class="RktVal">"Posts"</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">blog-posts</span><span class="hspace"> </span><span class="RktSym">k-url</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">start</span><span class="hspace"> </span><span class="RktSym">req</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">display-posts</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote></div></p><p>To use templates, we need only change <span class="RktSym">template</span>, <span class="RktSym">blog-posted</span>, and <span class="RktSym">blog-posts</span>:</p><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">template</span><span class="hspace"> </span><span class="RktSym">section</span><span class="hspace"> </span><span class="RktSym">body</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response%2Ffull%29%29" class="RktValLink" data-pltdoc="x">response/full</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktVal">200</span><span class="hspace"> </span><span class="RktVal">#"Okay"</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=time.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._current-seconds%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">current-seconds</a></span><span class="RktPn">)</span><span class="hspace"> </span><span class="RktSym"><a href="http.html#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._.T.E.X.T%2F.H.T.M.L-.M.I.M.E-.T.Y.P.E%29%29" class="RktValLink" data-pltdoc="x">TEXT/HTML-MIME-TYPE</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528lib._racket%252Flist..rkt%2529._empty%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">empty</a></span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=pairs.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._list%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">list</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=bytestrings.html%23%2528def._%2528%2528quote._%7E23%7E25kernel%2529._string-%7E3ebytes%252Futf-8%2529%2529&version=6.7" class="RktValLink Sq" data-pltdoc="x">string->bytes/utf-8</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"blog.html"</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">blog-posted</span><span class="hspace"> </span><span class="RktSym">title</span><span class="hspace"> </span><span class="RktSym">body</span><span class="hspace"> </span><span class="RktSym">k-url</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"blog-posted.html"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span></td></tr><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="https://download.racket-lang.org/docs/6.7/html/local-redirect/index.html?doc=reference&rel=define.html%23%2528form._%2528%2528lib._racket%252Fprivate%252Fbase..rkt%2529._define%2529%2529&version=6.7" class="RktStxLink Sq" data-pltdoc="x">define</a></span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">blog-posts</span><span class="hspace"> </span><span class="RktSym">k-url</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym"><a href="#%28form._%28%28lib._web-server%2Ftemplates..rkt%29._include-template%29%29" class="RktStxLink" data-pltdoc="x">include-template</a></span><span class="hspace"> </span><span class="RktVal">"blog-posts.html"</span><span class="RktPn">)</span><span class="RktPn">)</span></td></tr></table></blockquote><p>Each of the templates are given below:</p><p><div class="SIntrapara"><span class="stt">"blog.html"</span>:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><html></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><title>Al's Church: @|section|</title></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><style type="text/css"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">body {</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">margin: 0px;</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">padding: 10px;</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">#main {</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">background: #dddddd;</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></style></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></head></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><script type="text/javascript"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">var gaJsHost = (("https:" == document.location.protocol) ?</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">"https://ssl." : "http://www.");</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">document.write(unescape("%3Cscript src='" + gaJsHost +</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">"google-analytics.com/ga.js'</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">type='text/javascript'%3E%3C/script%3E"));</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></script></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><script type="text/javascript"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">var pageTracker = _gat._getTracker("UA-YYYYYYY-Y");</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">pageTracker._trackPageview();</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></script></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h1>Al's Church: @|section|</h1></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><div id="main"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt">@body</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></div></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"></body></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></html></span></p></td></tr></table></div></p><p>Notice that this part of the presentation is much simpler, because the CSS and JavaScript
can be included verbatim, without resorting to any special escape-escaping patterns.
Similarly, since the <span class="RktSym">body</span> is represented as a string, there is no need to
remember if splicing is necessary.</p><p><div class="SIntrapara"><span class="stt">"blog-posted.html"</span>:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt"><h2>@|title|</h2></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"><p>@|body|</p></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"><h1><a href="@|k-url|">Continue</a></h1></span></p></td></tr></table></div></p><p><div class="SIntrapara"><span class="stt">"blog-posts.html"</span>:
</div><div class="SIntrapara"><table cellspacing="0" cellpadding="0"><tr><td><p><span class="hspace"> </span><span class="stt">@in[p posts]{</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><h2>@(post-title p)</h2></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><p>@(post-body p)</p></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt">}</span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"><h1>New Post</h1></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"><form action="@|k-url|"></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><input name="title" /></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><input name="body" /></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></span><span class="hspace"> </span><span class="stt"><input type="submit" /></span></p></td></tr><tr><td><p><span class="hspace"> </span><span class="stt"></form></span></p></td></tr></table></div></p><p>Compare this template with the original presentation function: there is no need to worry about managing how lists
are nested: the defaults <span style="font-style: italic">just work</span>.</p><div class="navsetbottom"><span class="navleft"><form class="searchform"><input class="searchbox" style="color: #888;" type="text" value="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, "6.7", "../");" onfocus="this.style.color="black"; this.style.textAlign="left"; if (this.value == "...search manuals...") this.value="";" onblur="if (this.value.match(/^ *$/)) { this.style.color="#888"; this.style.textAlign="center"; this.value="...search manuals..."; }"/></form> <a href="../index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("6.7");">top</a></span><span class="navright"> <a href="formlets.html" title="backward to "6 Formlets: Functional Form Abstraction"" data-pltdoc="x">← prev</a> <a href="index.html" title="up to "Web Applications in Racket"" data-pltdoc="x">up</a> <a href="page.html" title="forward to "8 Page: Short-hand for Common Patterns"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html>
|