<html><head><metahttp-equiv="content-type"content="text/html; charset=utf-8"/><title>6 Second tutorial</title><linkrel="stylesheet"type="text/css"href="scribble.css"title="default"/><linkrel="stylesheet"type="text/css"href="racket.css"title="default"/><linkrel="stylesheet"type="text/css"href="manual-style.css"title="default"/><linkrel="stylesheet"type="text/css"href="manual-racket.css"title="default"/><scripttype="text/javascript"src="scribble-common.js"></script><scripttype="text/javascript"src="manual-racket.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><bodyid="scribble-racket-lang-org"><divclass="tocset"><divclass="tocview"><divclass="tocviewlist tocviewlisttopspace"><divclass="tocviewtitle"><tablecellspacing="0"cellpadding="0"><tr><tdstyle="width: 1em;"><ahref="javascript:void(0);"title="Expand/Collapse"class="tocviewtoggle"onclick="TocviewToggle(this,"tocview_0");">▼</a></td><td></td><td><ahref="index.html"class="tocviewlink"data-pltdoc="x">Pollen:<spanclass="mywbr"> </span> the book is a program</a></td></tr></table></div><divclass="tocviewsublisttop"style="display: block;"id="tocview_0"><tablecellspacing="0"cellpadding="0"><tr><tdalign="right">1 </td><td><ahref="Installation.html"class="tocviewlink"data-pltdoc="x">Installation</a></td></tr><tr><tdalign="right">2 </td><td><ahref="quick-tour.html"class="tocviewlink"data-pltdoc="x">Quick tour</a></td></tr><tr><tdalign="right">3 </td><td><ahref="Backstory.html"class="tocviewlink"data-pltdoc="x">Backstory</a></td></tr><tr><tdalign="right">4 </td><td><ahref="big-picture.html"class="tocviewlink"data-pltdoc="x">The big picture</a></td></tr><tr><tdalign="right">5 </td><td><ahref="first-tutorial.html"class="tocviewlink"data-pltdoc="x">First tutorial</a></td></tr><tr><tdalign="right">6 </td><td><ahref="second-tutorial.html"class="tocviewselflink"data-pltdoc="x">Second tutorial</a></td></tr><tr><tdalign="right">7 </td><td><ahref="raco-pollen.html"class="tocviewlink"data-pltdoc="x">Using <spanclass="stt">raco pollen</span></a></td></tr><tr><tdalign="right">8 </td><td><ahref="File_formats.html"class="tocviewlink"data-pltdoc="x">File formats</a></td></tr><tr><tdalign="right">9 </td><td><ahref="reader.html"class="tocviewlink"data-pltdoc="x">◊ command overview</a></td></tr><tr><tdalign="right">10 </td><td><ahref="Module_reference.html"class="tocviewlink"data-pltdoc="x">Module reference</a></td></tr><tr><tdalign="right">11 </td><td><ahref="Acknowledgments.html"class="tocviewlink"data-pltdoc="x">Acknowledgments</a></td></tr><tr><tdalign="right">12 </td><td><ahref="License___source_code.html"class="tocviewlink"data-pltdoc="x">License & source code</a></td></tr><tr><tdalign="right"></td><td><ahref="doc-index.html"class="tocviewlink"data-pltdoc="x">Index</a></td></tr></table></div></div><divclass="tocviewlist"><tablecellspacing="0"cellpadding="0"><tr><tdstyle="width: 1em;"><ahref="javascript:void(0);"title="Expand/Collapse"class="tocviewtoggle"onclick="TocviewToggle(this,"tocview_1");">►</a></td><td>6 </td><td><ahref="second-tutorial.html"class="tocviewselflink"data-pltdoc="x">Second tutorial</a></td></tr></table><divclass="tocviewsublistbottom"style="display: none;"id="tocview_1"><tablecellspacing="0"cellpadding="0"><tr><tdalign="right">6.1 </td><td><ahref="second-tutorial.html#%28part._tutorial-2._.Prerequisites%29"class="tocviewlink"data-pltdoc="x">Prerequisites</a></td></tr><tr><tdalign="right">6.2 </td><td><ahref="second-tutorial.html#%28part._.Prelude__my_principled_objection_to_.Markdown%29"class="tocviewlink"data-pltdoc="x">Prelude:<spanclass="mywbr"> </span> my principled objection to Markdown</a></td></tr><tr><tdalign="right">6.3 </td><td><ahref="second-tutorial.html#%28part._.Markdown_in_.Pollen__two_options%29"class="tocviewlink"data-pltdoc="x">Markdo
<br/>(strong () "so") " happy to be writing this."))</span></p></blockquote><p>You should now be able to recognize this as an X-expression. In authoring mode, Pollen parses your Markdown into the corresponding HTML entities, but then provides the data as an X-expression rather than finished HTML.</p><blockquoteclass="refpara"><blockquoteclass="refcolumn"><blockquoteclass="refcontent"><p>The empty parentheses <spanclass="RktVal">()</span> after <spanclass="RktVal">p</span> and <spanclass="RktVal">strong</span> signal that the tag’s attributes are empty. When you write an X-expression without attributes, these parentheses are optional —<spanclass="RktVal">(tag () "text")</span> and <spanclass="RktVal">(tag "text")</span> are equivalent — but Pollen will always print X-expressions this way.</p></blockquote></blockquote></blockquote><p>From what you learned in the last section, it should be evident that this X-expression corresponds to HTML that looks like this:</p><blockquoteclass="SCodeFlow"><p><spanclass="RktVal"><root><h1 id="my-article">Deep Thought</h1><p>I am <br/><strong>so</strong> happy to be writing this.</p></root></span></p></blockquote><p>“But what’s this <spanclass="stt">root</span> tag? That’s not HTML.” An X-expression must have a root tag, so in the spirit of obviousness, every X-expression produced by a source file in authoring mode will start with <spanclass="stt">root</span>. If you don’t need it, you can discard it. But it also creates a useful hook for further processing, as we’ll see later.</p><p>By the way, as review, let’s remind ourselves how this is different from preprocessor mode. Let’s take the same Markdown content, but this time put it into a preprocessor source file called <spanclass="stt">article.md.pp</span>.</p><blockquoteclass="Rfilebox"><pclass="Rfiletitle"><spanclass="Rfilename"><spanclass="stt">"article.md.pp"</span></span></p><blockquoteclass="Rfilecontent"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt">#lang pollen</span></p></td></tr><tr><td><p><spanclass="stt"></span><spanclass="hspace"> </span></p></td></tr><tr><td><p><spanclass="stt">Deep Thought</span></p></td></tr><tr><td><p><spanclass="stt">============</span></p></td></tr><tr><td><p><spanclass="stt"></span><spanclass="hspace"> </span></p></td></tr><tr><td><p><spanclass="stt">I am **so** happy to be writing this.</span></p></td></tr></table></blockquote></blockquote><p>When you run this file in DrRacket, you’ll see:</p><blockquoteclass="SCodeFlow"><p><spanclass="RktVal">Deep Thought<br/>============<br/><br/>I am **so** happy to be writing this.</span></p></blockquote><p>Hopefully, this result makes sense to you: when you run Markdown source in preprocessor mode, you get Markdown. When you run Markdown source in authoring mode, you get an X-expression.</p><h4>6.4<tt> </tt><aname="(part._tutorial-2._.Templates)"></a>Templates</h4><p>So how do you convert an X-expression into a finished file? You use a Pollen <spanstyle="font-style: italic">template</span>, which takes data from an X-expression and converts it to the target format.</p><p>If you’ve used other web-publishing systems, templates are probably a familiar idea. Templates in Pollen are in some ways similar to the ones you’ve seen before, but in other ways different.</p><p>First, the similarities. At its simplest, a template holds boilerplate material that you want to reuse across multiple pages. For instance, in a set of HTML pages, you might have layout and navigation elements that stay the same, while the content changes. In that case, you could put the layout and navigation in the template, and keep the content in your Pollen source files. When you want to add a new page, you can make a new source file and just use it with the existing template. Moreover, if you want to change the layout and navigation globally, you can just change the template, rather than changing the
<br/><root><h1 id="my-article">Deep Thought</h1><p>I am
<br/><strong>so</strong> happy to be writing this.</p></root>
<br/></body></html></span></p></blockquote><p>But wait — where did the template come from? When you view an authoring-mode source file in the project server without specifying a template, Pollen helps you out and uses its <spanstyle="font-style: italic">fallback template</span>. The fallback template is just a minimal template that’s used as a last resort. Under ordinary circumstances, seeing the fallback template usually signals a problem (e.g., Pollen couldn’t find the template you asked for).</p><p>But we can learn a few things from the fallback template about how to make an HTML template.</p><h5>6.4.1<tt> </tt><aname="(part._tutorial-2._.The_-_html_function_and_the_doc_variable)"></a>The <spanclass="stt">->html</span> function and the <spanclass="stt">doc</span> variable</h5><p>This is the fallback template that Pollen uses.</p><blockquoteclass="Rfilebox"><pclass="Rfiletitle"><spanclass="Rfilename"><spanclass="stt">"fallback.html"</span></span></p><blockquoteclass="Rfilecontent"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt">◊(->html (html (head (meta 'charset: "UTF-8")) (body doc)))</span></p></td></tr></table></blockquote></blockquote><p>It has three key ingredients.</p><p>First, there’s an X-expression that represents a basic HTML page:</p><blockquoteclass="SCodeFlow"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt">(html (head (meta 'charset: "UTF-8")) (body))</span></p></td></tr></table></blockquote><p>This is equivalent to the HTML:</p><blockquoteclass="SCodeFlow"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt"><html><head><meta charset="UTF-8"></head><body></body></html></span></p></td></tr></table></blockquote><p>But within a template, we need to explicitly convert from X-expression to HTML. So we wrap this X-expression with our second key ingredient, the Pollen command <spanclass="RktSym"><spanclass="nobreak">-></span>html</span>:</p><blockquoteclass="SCodeFlow"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt">◊(->html (html (head (meta 'charset: "UTF-8")) (body)))</span></p></td></tr></table></blockquote><p>Third, we need to include the content from our source file. We do this by putting the variable <spanclass="stt">doc</span> inside the <spanclass="stt">body</span> tag.</p><blockquoteclass="SCodeFlow"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt">◊(->html (html (head (meta 'charset: "UTF-8")) (body doc)))</span></p></td></tr></table></blockquote><p>By convention, every Pollen source file makes its output available through the variable <spanclass="stt">doc</span>. A source file in preprocessor mode puts its text result in <spanclass="stt">doc</span>. And a source file in authoring mode puts its X-expression result in <spanclass="stt">doc</span>.</p><blockquoteclass="refpara"><blockquoteclass="refcolumn"><blockquoteclass="refcontent"><p>You can change the name to something other than <spanclass="stt">doc</span> by changing <spanclass="RktSym"><ahref="World.html#%28def._%28%28lib._pollen%2Fworld..rkt%29._world~3amain-pollen-export%29%29"class="RktValLink"data-pltdoc="x">world:main-pollen-export</a></span>.</p></blockquote></blockquote></blockquote><p>Under the hood, a template is just a partial program that relies on a set of variables defined by another source file (fancy name: <spanstyle="font-style: italic">lexical context</span>). So if you ran this template on its own, nothing would happen, because <spanclass="stt">doc</span> isn’t defined. But when you run it in the context of another source file, it picks up the <spanclass="stt">doc</span> that’s defined by that file.</p><p>Caution — despite the name, a Pollen template is not necessarily a file of the type suggested by its extension. For instance, <spanclass="stt">fallback.html</span> is a file that ultimately produces HTML, but it’s not actually written in HTML.</p><p>It could be,
<br/>(strong () "so") " happy to be writing this."))</span></p></blockquote><p>Either way, now we know that the text <spanstyle="font-style: italic">Deep Thought</span> lives in the <spanclass="stt">h1</span> tag. So we update our template accordingly (for brevity, I’m going to omit the <spanclass="stt">style</span> tag in these examples, but it’s fine to leave it in):</p><blockquoteclass="Rfilebox"><pclass="Rfiletitle"><spanclass="Rfilename"><spanclass="stt">"template.html"</span></span></p><blockquoteclass="Rfilecontent"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt"><html></span></p></td></tr><tr><td><p><spanclass="stt"><head><meta charset="UTF-8"></span></p></td></tr><tr><td><p><spanclass="stt"><title>◊(select 'h1 doc)</title></head></span></p></td></tr><tr><td><p><spanclass="stt"><body>◊(->html doc)</body></span></p></td></tr><tr><td><p><spanclass="stt"></html></span></p></td></tr></table></blockquote></blockquote><p>When you refresh the page in the project server, the page title will now appear as “Deep Thought.” Of course, you can also combine static and dynamic elements in your template, like so:</p><blockquoteclass="Rfilebox"><pclass="Rfiletitle"><spanclass="Rfilename"><spanclass="stt">"template.html"</span></span></p><blockquoteclass="Rfilecontent"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt"><html></span></p></td></tr><tr><td><p><spanclass="stt"><head><meta charset="UTF-8"></span></p></td></tr><tr><td><p><spanclass="stt"><title>◊(select 'h1 doc), by MB</title></head></span></p></td></tr><tr><td><p><spanclass="stt"><body>◊(->html doc)</body></span></p></td></tr><tr><td><p><spanclass="stt"></html></span></p></td></tr></table></blockquote></blockquote><p>The page title will now be “Deep Thought, by MB”.</p><p>A couple notes on command syntax. We inserted the <spanclass="RktSym">select</span> and <spanclass="RktSym"><spanclass="nobreak">-></span>html</span> commands using Racket-mode syntax. We could also use text-mode syntax and write the commands this way:</p><blockquoteclass="Rfilebox"><pclass="Rfiletitle"><spanclass="Rfilename"><spanclass="stt">"template.html"</span></span></p><blockquoteclass="Rfilecontent"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt"><html></span></p></td></tr><tr><td><p><spanclass="stt"><head><meta charset="UTF-8"></span></p></td></tr><tr><td><p><spanclass="stt"><title>◊select['h1 doc], by MB</title></head></span></p></td></tr><tr><td><p><spanclass="stt"><body>◊->html[doc]</body></span></p></td></tr><tr><td><p><spanclass="stt"></html></span></p></td></tr></table></blockquote></blockquote><p>This is exactly equivalent to the previous example. Skeptics are welcome to confirm this by checking the result in the project server.</p><p>Finally, notice that in the <spanclass="RktSym">select</span> command, the tag name <spanclass="RktVal">'</span><spanclass="RktVal">h1</span> is written with a quote mark, whereas <spanclass="stt">doc</span> is not. This is an easy place to get tripped up, but the rule is simple: you don’t use a quote mark when you’re referring to the name of an existing function or variable (like <spanclass="RktSym">select</span> or <spanclass="stt">doc</span>). But you do need a quote mark when you’re using the text as a literal value.</p><blockquoteclass="refpara"><blockquoteclass="refcolumn"><blockquoteclass="refcontent"><p>Racket (and hence Pollen) makes a distinction between <ahref="http://docs.racket-lang.org/guide/symbols.html"data-pltdoc="x">Symbols</a> (e.g. <spanclass="RktVal">'</span><spanclass="RktVal">h1</span>) and <ahref="http://docs.racket-lang.org/reference/strings.html"data-pltdoc="x">Strings</a> (e.g. <spanclass="RktVal">"h1"</span>). Without getting into the weeds, just note for now that
<br/>Can you mix dynamic and static style sheets? Yes.
<br/>Can you add a dynamic JavaScript file? Yes.
<br/>You’re getting the general idea, right? So let’s move on.</p><h4>6.5<tt> </tt><aname="(part._tutorial-2._.Intermission)"></a>Intermission</h4><p>If you only need one page for your article, you can stop here. You now know everything necessary to publish a single-page article using authoring mode. You know how to create the mandatory ingredients — a source file and a template — and you also know how to link to an optional CSS file, which can be dynamically generated.</p><p>If you want to create a multi-page article, however, you need to get through one more big idea. This might be a good time to take a break.</p><h4>6.6<tt> </tt><aname="(part._tutorial-2._.Pagetrees)"></a>Pagetrees</h4><p>A <spanstyle="font-style: italic">pagetree</span> is a hierarchical list of Pollen pages. When you have multiple pages in your project, the pagetree establishes relationships among those pages. At its most basic, a pagetree establishes a linear sequence for the pages. But pagetrees can also establish hierarchical relationships — for instance, a book-length project can be organized into chapters, the chapters into sections, and so on. The pagetree doesn’t impose any semantics on the organization of your project. It’s just a tree, and it’s up to you how many layers to establish, what those layers mean, and so on.</p><blockquoteclass="refpara"><blockquoteclass="refcolumn"><blockquoteclass="refcontent"><p><spanstyle="font-style: italic">Pagemap</span> might’ve been an equally good name, and perhaps more consistent with similar concepts in other web-publishing systems. But I avoided it out of deference to Racket’s <spanclass="RktSym"><ahref="http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Fprivate%2Fmap..rkt%29._map%29%29"class="RktValLink"data-pltdoc="x">map</a></span> function, which means something completely different.</p></blockquote></blockquote></blockquote><h5>6.6.1<tt> </tt><aname="(part._tutorial-2._.Pagetree_navigation)"></a>Pagetree navigation</h5><p>Pagetrees are used in various ways throughout Pollen. But the most obvious use for a pagetree is to add navigational links to your pages. Obviously, in a multi-page article, readers need a way of getting from one page to the next. In this part of the tutorial, we’ll expand our sample article from one page to three, and see how to create “previous page” and “next page” links in our template that are dynamically generated relative to the current page.</p><h5>6.6.2<tt> </tt><aname="(part._tutorial-2._.Using_the_automatic_pagetree)"></a>Using the automatic pagetree</h5><p>You’ve actually already been exposed to pagetrees (though I didn’t tell you about it at the time). Recall that the dashboard of the project server is located at <spanclass="stt">http://localhost:8080/index.ptree</span>. The list of files you see in the dashboard is a pagetree that Pollen creates by reading the files in the current directory and arranging them in alphabetical order.</p><p>If the multiple pages in your project are already ordered by filename, then you can rely on this automatic pagetree.</p><p>From earlier in the tutorial, you have a Markdown source file called <spanclass="stt">article.html.pmd</span> that looks like this:</p><blockquoteclass="Rfilebox"><pclass="Rfiletitle"><spanclass="Rfilename"><spanclass="stt">"article.html.pmd"</span></span></p><blockquoteclass="Rfilecontent"><tablecellspacing="0"cellpadding="0"><tr><td><p><spanclass="stt">#lang pollen</span></p></td></tr><tr><td><p><spanclass="stt"></span><spanclass="hspace"> </span></p></td></tr><tr><td><p><spanclass="stt">Deep Thought</span></p></td></tr><tr><td><p><spanclass="stt">============</span></p></td></tr><tr><td><p><spanclass="stt"></span><spanclass="hspace"> </span></p></td></tr><tr><td><p><spanclass="stt">I am **so** happy to be writing this.</span></p></td></tr></table></blockquote></blockquote><p>Let’s supplement this source file by