Page variables

Page variables offer a straightforward way to interact with the HTML templating from the markdown and much more.

Overview

The general syntax to define a page variable is to write @def varname = value on a new line e.g.:

@def author = "Septimia Zenobia"

where you could set the variable to a string, a number, a date,... anything. Definitions can span multiple lines but if they do, the subsequent lines must be indented e.g.:

@def some_str = """A string
    on several lines is ok
    but lines must be indented"""

You can also define them in blocks surrounded by +++...+++, the entire content of which will be evaluated as if it was Julia code but all assigned variables will be considered as page variables:

+++
var1 = [1, 2,
  3, 4]
var2 = "Hello goodbye"
+++

These variables can serve multiple purposes but, primarily, they can be accessed from the HTML template blocks e.g.:

<footer>
  This is the footer. &copy; {{fill author}}.
</footer>

which could be useful as footer on all pages.

The syntax {{ ... }} indicates a HTML function, fill is the function name and the rest of the bracket elements are page variables (here author) serving as arguments of the function.

⚠ Note
Argument-less calls such as {{ name }} will be interpreted in either one of two way: first it will check whether there is a html function name and if so will call it, otherwise it will check whether there is a page variable name and will just insert it – it will be treated as a shortcut for {{fill name}}.

Local page variables denote variables that are defined on a single page and accessible on that page only by contrast to global page variables which are set globally (in the config.md file) and accessible on all pages.

In both cases there are default page variables set by Franklin with default values which you can both change and use. You can of course also define your own variables, both global and local.

Using page variables

Both local and global page variables are meant for essentially two purposes:

  1. control the HTML template from the markdown,

  2. modify how Franklin generates HTML.

The second one is a bit less prevalent but, for instance, you can specify the default programming language for all code blocks so that code blocks that don't specify a language would use the default language for highlighting:

@def lang = "julia"

In the first case, you can access variables in your HTML template via one of the HTML functions such as the fill function shown above.

HTML functions

HTML functions can be used in any one of your *.html file and in particular in any of the _layout/*.html files such as head.html. They are always called with the syntax {{fname pv1 pv2 ...}} where pv1 pv2 ... are page variable names.

Basic functions

A few functions are available with the {{fill ...}} arguably the most likely to be of use.

FormatRole
{{fill vname}} or {{vname}}place the value of page variable vname
{{fill vname rpath}}same but taking the value from the page at rpath where rpath is a relative path like blog/pg1
{{insert fpath}}insert the content of the file at fpath
{{href vname}}inserts a reference (mostly internal use)
{{toc}}places a table of content (mostly internal use)

The {{insert fpath}} can be useful if you want to include specific HTML scaffolding on some pages, for instance in example pages you will see in the head.html:

{{if hasmath}} {{insert head_katex.html}} {{end}}

Conditional blocks

Conditional blocks allow to specify which parts of the HTML template should be active depending on the value of given page variable(s). The format follows this structure:

{{if vname}}
...
{{elseif vname2}}
...
{{else}}
...
{{end}}

where vname and vname2 are expected to be page variable evaluating to a boolean. Of course you don't have to specify the {{elseif ...}} or {{else}} if you don't need them.

⚠ Note
The conditional blocks are fairly basic; in particular operations between page variables are not supported, so you can't write something like {{if hasmath && hascode}}. For more complex use cases, consider defining your own HTML functions using the utils file.

You can also use some dedicated conditional blocks:

FormatRole
{{ispage path/to/page}}whether the current page corresponds to the path
{{isnotpage path/to/page}}opposite of previous
{{isdef vname}}whether vname is defined
{{isnotdef vname}}opposite of previous

The {{ispage ...}} and {{isnotpage ...}} accept * as joker symbol; for instance {{ispage maths/*}} is allowed.

Note: for the C users out there, you can also use ifdef, ifndef.

Consider the following example (very similar to what is used on the current page):

<li class="{{ispage syntax/*}}active{{end}}">• Syntax
<ul>
  <!-- ... -->
  <li class="{{ispage syntax/page-variables}}active{{end}}">Page Variables
  <!-- ... -->
</ul>

This allows a simple, javascript-free, way of having a navigation menu that is styled depending on which page is currently active.

For loops

You can define iterable page variables (array, tuple, ...) and loop over them using the following syntax:

{{for x in vname}}
  ...{{fill x}}...
{{end}}

Only {{fill vname}} and {{fill vname rpath}} are allowed in such a for loop. You can also unpack an iterable like

{{for (x, y) in vname}}
  ...{{fill x}}...{{fill y}}
{{end}}

where vname would refer to something like [(1,2),(3,4)].

Global page variables

The table below list global page variables that you can set. These variables are best defined in your config.md file though you can overwrite the value locally by redefining the variable on a given page (this will then only have an effect on that page).

NameType(s)Default valueComment
authorString, Nothing"THE AUTHOR"
autocodeBooltruewhether to detect the presence of code blocks and set the local var hascode automatically
automathBooltruewhether to detect the presence of math blocks and set the local var hasmath automatically
date_formatString"U dd, yyyy"Must be a format recognised by Julia's Dates.format
date_daysVector{String}String[]Names for days of the week (*)
date_shortdaysVector{String}String[]Short names for the days of the week (*)
date_monthsVector{String}String[]Names for months (*)
date_shortmonthsVector{String}String[]Short names for months (*)
div_contentString"franklin-content"Name of the div that will englobe the processed content between head and foot
ignoreVector{String}String[]Files that should be ignored by Franklin (**)
prepathString""Use if your website is a project website (***)
website_titleString""(RSS) (****)
website_descrString""(RSS)
website_urlString""(RSS)
generate_rssBooltrue
folder_structureVersionNumberv"0.2"only relevant for users of Franklin < 0.5, see NEWS.md

Notes:
(*) must be in a format recognized by Julia's Dates.DateLocale. Defaults to English. If left unset, the short names are created automatically by using the first three characters of the full names.
(**) to ignore a file add it's relative path like "path/to/file.md", to ignore a directory end the path with a / like "path/to/dir/".
(***) say you're using GitHub pages and your username is darth, by default Franklin will assume the root URL to be darth.github.io/. However, if you want to build a project page so that the base URL is darth.github.io/vador/ then use @def prepath = "vador".
(****) these must be defined for RSS to be generated for your site (on top of generate_rss being true). See also the RSS subsection below.

Local page variables

The tables below list local page variables that you can set. These variables are typically set locally on a page. Remember that:

  • you can also define your own variables (with different names),

  • you can change the default value of a variable by defining it in your config.md.

Note that variables shown below that have a name starting with fd_ are not meant to be defined as their value is typically computed on the fly (but they can be used).

Basic settings

NameTypeDefault valueComment
titleString, Nothingnothingpage title (*)
hasmathBooltruewhether to activate KaTeX for that page
hascodeBoolfalsewhether to activate highlight.js for that page
dateString, Date, NothingDate(1)a date object (e.g. if you want to set a publication date)
langStringjuliadefault highlighting for code on the page
reflinksBooltruewhether there are things like [ID]: URL on your page (**)
indented_codeBoolfalsewhether indented blocks should be considered as code (***)
mintoclevelInt1minimum title level to go in the table of content (often you'll want this to be 2)
maxtoclevelInt10maximum title level to go in the table of content
fd_ctimeStringtime of creation of the markdown file
fd_mtimeStringtime of last modification of the markdown file
fd_mtime_rawDatetime of last modification in Date object
fd_rpathStringrelative path to file [(...)/thispage.md]

Notes:
(*) if the title is not set, the first header will be used as title.
(**) there may be cases where you want to literally type ]: in some code without it indicating a link reference. In such case, set reflinks to false to avoid ambiguities.
(***) it is recommended to fence your code blocks (use backticks) as it's not ambiguous for the parser whereas indented blocks can be. If you do want to use indented blocks as code blocks, it's your responsibility to make sure there are no ambiguities.

Code evaluation

For more informations on these, see the section on inserting and evaluating code.

NameTypeDefault valueComment
reevalBoolfalsewhether to reevaluate all code blocks on the page
showallBoolfalsenotebook mode if true where the output of the code block is shown below
fd_evalBoolfalseinternal variable to keep track of whether the scope is stale (in which case all subsequent blocks are re-evaluated)

RSS

These are variables related to RSS 2.0 specifications and must match the format indicated there. If you want proper RSS to be generated, you must define at least the rss_description or rss (which is an alias for rss_description). All these variables expect a String.

NameDefault value
rss, rss_description""
rss_titlecurrent page title
rss_authorcurrent author
rss_category""
rss_comments""
rss_enclosure""
rss_pubdate""

To recapitulate, for a working RSS feed to be generated you need:

  • to set the website_* variables in your config.md (see global page variables),

  • on appropriate pages, to define at least rss to a valid description.

For an example, see this mirror of the Julia blog posts with: