Page Variables (part 2)

HTML functions and environments

By now you should already have an idea

  • XXX functions can be used in Markdown no problem
  • environments should only be used in HTML (their scope is not resolved in Markdown which so something like {{for x in iter}} **{{x}}** {{end}} will try to resolve {{x}} first, fail) (or within a raw HTML block)

Default functions

(XXX) Environments: conditionals

markdown
+++
flag = true
+++

{{if flag}}
Hello
{{else}}
Not Hello
{{end}}
result Hello
πŸš€ Tip While here the environment is demonstrated directly in Markdown, environments are best used in layout files (_layout/...) or raw HTML blocks and should, ideally, not be mixed with Markdown as the order in which elements are resolved by Franklin may not always be what you think and that can sometimes lead to unexpected results.This is even more true for loop environments introduced further below.

Naturally, you can have multiple branches with {{elseif variable}}. Here's another example

markdown
+++
flag_a = false
flag_b = true
+++

{{if flag_a}}
ABC
{{elseif flag_b}}
DEF
{{end}}
result DEF

There are some standard conditionals that can be particularly useful in layout.

conditional effect
{{ispage path}} or {{ispage path1 path2 ...}} checks whether the present page corresponds to a path or a list of paths, this can be particularly useful if you want to toggle different part of layout for different pages
{{isdef var}} ...

etc + check

(XXX) Environments: loops

markdown
+++
some_list = ["bob", "alice", "emma", "joe"]
+++

{{for x in some_list}}
{{x}} \\
{{end}}
result bob
alice
emma
joe
markdown
+++
iter = ["ab", "cd", "ef"]
+++

{{for e in iter}}
_value_ ? **{{e}}**\\
{{end}}
result value ? ab
value ? cd
value ? ef
πŸš€ Tip The example above shows mixing of Markdown inside the scope of the loop environment, here things are simple and work as expected but as indicated in the previous tip, you should generally keep environments for HTML blocks or layout files.

E-strings

E-strings allow you to run simple Julia code to define the parameters of a {{...}} block. This can be useful to

  1. insert some value derived from some page variables easily,
  2. have a conditional or a loop environment depend on a derivative of some page variables.

The first case is best illustrated with a simple example:

markdown
+++
foo = 123
+++

* {{e"1+1"}}
* {{e"$foo"}} you can refer to page variables using `$name_of_variable`
* {{e"$foo^2"}}
* {{e"round(sqrt($foo), digits=1)"}}
result
  • 2
  • 123 you can refer to page variables using $name_of_variable
  • 15129
  • 11.1

More generally the syntax is {{ e"..." }} where the ... is valid Julia code where page variables are prefixed with a $. The alternative syntax {{> ...}} is also supported:

markdown
+++
bbb = 321
+++

{{> $bbb // 3}}
result107//1

The code in the e-string is evaluated inside the utils module and so could leverage any package it imports or any function it defines. For instance we added a function

bar(x) = "hello from foo <$x>"

to utils.jl and can call it from here in an e-string as:

markdown
{{e"bar($foo)"}}
resulthello from foo <123>

As noted earlier, these e-strings can also be useful for conditional and loop environments:

  • {{if e"..."}}
  • {{for ... in e"..."}}

For the first, let's consider the case where you'd like to have some part of your layout depend on whether either one of two page variables is true. For this you can use an e-string and write {{if e"$flag1 || $flag2"}}:

markdown
+++
flag1 = false
flag2 = true
+++
{{if e"$flag1 || $flag2"}}
Hello
{{else}}
Not Hello
{{end}}
result Hello

More generally you can use an e-string for any kind of condition written in Julia as long as it evaluates to a boolean value (true or false).

For loop environments, you can likewise use an e-string that would give you some derived iterator that you'd wish to go over:

markdown
+++
iter1 = [1, 2, 3]
iter2 = ["abc", "def", "ghi"]
+++
~~~
<ul>
{{for (x, y) in e"zip($iter1, $iter2)"}}
<li><strong>{{x}}</strong>: <code>{{y}}</code></li>
{{end}}
</ul>
~~~
result
  • 1: abc
  • 2: def
  • 3: ghi
markdown
+++
team = [
  (name="Alice", role="CEO"),
  (name="Bob", role="CTO"),
  (name="Jon", role="Eng")
]
+++

~~~
<ul>
{{for person in team}}
  <li><strong>{{> $person.name}}</strong>: {{> $person.role}}</li>
{{end}}
</ul>
~~~
result
  • Alice: CEO
  • Bob: CTO
  • Jon: Eng

in that second example, we use an e-string inside the for loop and so we must use a $ to indicate that person should be obtained from the context.

More customisation

If the default functions and environments, possibly coupled with e-strings are not enough for your use case or are starting to feel a bit clunky, it's time to move on to writing custom hfuns.

This approach allows you to write {{your_function p1 p2 ...}} where your_function maps to a Julia function that you define and that produces a string based on whatever logic that would be appropriate for your use case.

Website built with Franklin.jl and the Julia programming language.