5 Templates
A Page template is used to define the overall html element for all generated pages. Some types of pages also use a nested Post template or an Index template.
Frog uses the Racket web-server/templates
system based on @ Syntax. This means that the files are
basically normal HTML format, with the ability to use @ to
reference a template variable —
In contrast to most templating systems, you have a full programming language available should you need it. However most of what you need to do will probably be very simple, such as the occasional if or when test, or perhaps defineing a helper function to minimize repetition.
5.1 Page template
The "page-template.html" template specifies an <html> element used by Frog to generate every page on your site.
Anything in the file that looks like @variable or @|variable| is a template variable supplied by Frog. Most of these should be self-explanatory from their name and from seeing how they are used in the default template.
template variable
contents : string?
template variable
description : string?
template variable
keywords : string?
template variable
uri-prefix : string?
template variable
uri-path : string?
template variable
atom-feed-uri : string?
template variable
rss-feed-uri : string?
template variable
tag : (or/c string? #f)
template variable
tags-list-items : string?
template variable
tags/feeds : string?
template variable
rel-prev : (or/c string? #f)
@(when rel-prev @list{<link rel="next" href="@|rel-next|">}) |
template variable
rel-next : (or/c string? #f)
@(when rel-next @list{<link rel="prev" href="@|rel-prev|">}) |
5.2 Post template
The "post-template.html" template determines how blog posts are laid out on pages that are dedicated to one post. The default template defines an <article> element.
For pages that are blog posts, the result of "post-template.html" becomes most of the @|contents| variable in the Page template. In other words, the post template is effectively nested in the page template. (They are two separate templates so that the page template can also be used for pages that are not blog post pages.)
+---------------------------+
| page-template |
| |
| +---------------+ |
| | post-template | |
| +---------------+ |
| |
+---------------------------+
This template does not control how a blog post is laid out on
an index page such as "/index.html" or
"/tags/<some-tag>.html" —
The main purpose of this template is to specify things like Disqus
comments, Tweet and +1 sharing buttons, and older/newer links —
Anything in the file that looks like @variable or @|variable| is a template variable supplied by Frog. Most of these should be self-explanatory from their name and from seeing how they are used in the default template.
template variable
uri-prefix : string?
template variable
uri-path : string?
template variable
date-8601 : string?
template variable
date-struct : date?
template variable
tags : string?
template variable
date+tags : string?
template variable
content : string?
template variable
older-uri : (or/c string? #f)
template variable
older-title : (or/c string? #f)
template variable
newer-uri : (or/c string? #f)
template variable
newer-title : (or/c string? #f)
5.3 Index template
The "index-template.html" template determines how blog posts are laid out on index pages.
Typically it would be similar to your Post template, but without some "footer" items like comments or previous/next post buttons.
+----------------------------+
| page-template |
| |
| +----------------+ |
| | index-template | |
| +----------------+ |
| |
| +----------------+ |
| | index-template | |
| +----------------+ |
| |
| +----------------+ |
| | index-template | |
| +----------------+ |
| . . . |
| |
+----------------------------+
Anything in the file that looks like @variable or @|variable| is a template variable supplied by Frog. Most of these should be self-explanatory from their name and from seeing how they are used in the default template.
template variable
uri-prefix : string?
template variable
uri-path : string?
template variable
date-8601 : string?
template variable
date-struct : date?
template variable
tags : string?
template variable
date+tags : string?
template variable
content : string?
template variable
content-only : string?
template variable
more? : boolean?
5.4 Template Example
Let’s say you want to customize the date display format of your posts. Instead of the default ISO-8601 YYYY-MM-DD format, you want it to be the default of Racket’s date->string function. Here is what you could do in your Index template:
index-template.html
@(local-require racket/date)
<article>
<header>
<h2><a href='@|uri-path|'>@|title|</a></h2>
<p class='date-and-tags'>
<time datetime='@|date-8601|' pubdate='true'>
@(date->string date-struct)
</time>
:: @|tags|</p>
</header>
@|content|
</article>
If you need to require a Racket module in your template, you must use local-require. Plain require won’t work because the template is not evaluated at a module level or top level.
5.5 General Template Tips
5.5.1 Use |s to delimit template variables
Because Racket is extremely liberal in valid characters for identifiers, you may need to use pipe characters to delimit a template variable from surrounding text.
For example <p>@foo</p> will read as if foo</p> were the identifier, because that is a perfectly valid identifier name in Racket. Instead you can write: <p>@|foo|</p>.
It is probaby simplest to get in the habit of always using @|variable| so you don’t need to think about when it’s necessary.
5.5.2 Use local-require in templates
If you need to require a Racket module in your template, you must use local-require. Plain require won’t work because the template is not evaluated at a module level or top level.
5.5.3 Literal @
In @ Syntax, @ has special meaning. How do you write a literal @ in your template? Use @"@". For example if you need to write an email address: foo@"@"bar.com renders as foo@bar.com.
Understanding why this works may help you remember it:
@ means "evaluate the following s-expression as Racket code".
"@" is the Racket expression for the string literal @.
Therefore @"@" evaluates to the string "@" and that is the text produced by your template.
5.5.4 More
See also Gotchas.
5.6 Widgets
In addition to the variables described above for each template, some predefined functions are available for templates to use: “widgets”.
Anything a widget can do, you could code directly in the template. There’s no magic. But widgets minimize clutter in the templates. Plus they make clearer what are the user-specific parameters (as opposed to putting stuff like <!-- CHANGE THIS! --> in the template).
See the example page template and example post template for usage examples.
If you’d like to add a widget, pull requests are welcome!
(require frog/widgets) | package: frog |
In your templates, this module is already required.
procedure
(older/newer-links older-uri older-title newer-uri newer-title [ #:for-bs for-bs]) → list? older-uri : (or/c #f string?) older-title : (or/c #f string?) newer-uri : (or/c #f string?) newer-title : (or/c #f string?) for-bs : (or/c 3 4) = 3
procedure
(disqus-comments short-name [ #:identifier identifier #:title title #:url url #:category-id category-id]) → list? short-name : string? identifier : (or/c #f string? number?) = #f title : (or/c #f string?) = #f url : (or/c #f string?) = #f category-id : (or/c #f string?) = #f
procedure
(intense-debate id-account) → list?
id-account : string?
procedure
(google-universal-analytics account) → list?
account : string?
procedure
(google-analytics account domain) → list?
account : string? domain : string?
procedure
(google-plus-share-button full-uri) → list?
full-uri : string?
procedure
(twitter-follow-button name [label]) → list?
name : string? label : (or/c #f string?) = #f
procedure
(twitter-timeline user widget-id [ #:width width #:height height #:lang lang #:theme data-theme #:link-color data-link-color #:border-color data-border-color #:tweet-limit data-tweet-limit #:chrome data-chrome #:aria-polite data-aria-polite #:related data-related]) → list? user : string? widget-id : string? width : (or/c #f number?) = #f height : (or/c #f number?) = #f lang : (or/c #f string?) = #f data-theme : (or/c #f string?) = #f data-link-color : (or/c #f string?) = #f data-border-color : (or/c #f string?) = #f data-tweet-limit : (or/c #f string?) = #f data-chrome : (or/c #f string?) = #f data-aria-polite : (or/c #f string?) = #f data-related : (or/c #f string?) = #f
procedure
(twitter-share-button uri) → list?
uri : string?
procedure
src : string? = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" config : string? = "TeX-AMS-MML_HTMLorMML"
Use this in the <head> of your Page template.
In your markdown source files, use \\( some math \\) for inline and \\[ some math \\] for display. Note the double backslashes, \\, because in markdown \ already has a meaning.
You can specify the source URL and configuration options with the src & config arguments: they default to something reasonable.