LuaWebGen

Embedding Lua


Code Blocks

Lua can be embedded in .html, .md and .css files by default. A block of code exists between {{ and }}, which can be literally anywhere in the file (even inside HTML comment tags). Code is not context sensitive, other than what type of file it is in (e.g. HTML entities may get encoded in .html and .md files, but not in .css files).

<h1>Questions for year {{ os.date("%Y") }}</h1>
<section>
	{{
	echoRaw("<h2>")
	echo("Is 5 < 9 still true?")
	echoRaw("</h2>")
	}}
</section>

There are two main kinds of code blocks: Those that output (or "echo") a value, and those that just contain code to run.

If the block contains a value expression then the result is echoed:

<p>86 + 47 = {{ 86 + 47 }}</p>
<p>My name is {{ getMyName() .. " the 3rd" }}</p>
<p>Random double-digit number: {{
	math.random( -- Code can span multiple lines.
		10, 99
	)
}}</p>
{{ nil --[[ Nil values don't echo anything. ]] }}
{{ print("Hello!") --[[ The print function returns nothing, so nothing is echoed here either. ]] }}

Under the hood, {{valueExpression}} calls echoSmart().

Otherwise, the code just runs:

<p>
	Have you seen
	{{
	print("Just counting to 4...")
	for i = 1, 4 do
		print(i)
	end
	}}
	the cat?
</p>

There is a third special kind of block that can be used for outputting percent-encoded URLs. The block should contain a relative or absolute URL (without quotes or anything else). These three blocks are equal:

<a href="{{ /blog/2008/smörgåsbord/ }}">The Grand Smörgåsbord</a>
<a href="{{ url("/blog/2008/smörgåsbord/") }}">The Grand Smörgåsbord</a>
<a href="{{ echo(url("/blog/2008/smörgåsbord/")) }}">The Grand Smörgåsbord</a>

Whitespace around code blocks can be trimmed away by putting an asterisk (*) inside the block near {{ or }}:

A {{  echo("B")  }} C   This results in "A B C"
A {{* echo("B") *}} C   This results in "ABC"
A {{* echo("B")  }} C   This results in "AB C"

Control Structures

Control structures in templates behave pretty much like in normal Lua, but here are some additions. To use a "templateified" control structure put the keyword right after {{:

Normal if:
{{
if foo == "bar" then
	echo("Foo is bar!")
end
}}

Templateified if:
{{ if foo == "bar" }}
Foo is bar!
{{ end }}

{{   if   foo   ==   "bar"   }}
Extra spaces are fine.
{{   end   }}

Note that you don't need to write then or do in templateified if, for, or while statements.

Also note that a templateified control structure must be matched by a templateified end or until. The following is an error:

{{ if foo == "bar" }}
Templateified "if", followed by normal "end".
{{
end
}}

for / fori

Templateified for statements have several simplified versions:

{{ for 3 }}
- Loop forwards from 1 to 3: {{ i }}
{{ end }}

{{ for < 3 }}
- Loop backwards from 3 to 1: {{ i }}
{{ end }}

fori is a new keyword here and implies it's an ipairs() loop.

{{ fori dog in data.dogs }}
- {{ i }}: {{ dog.name }}
{{ end }}

{{ fori data.dogs }}
- {{ i }}: {{ it.name }}
{{ end }}

fori also supports < for looping backwards.

{{ fori < data.dogs }}
- {{ i }}: {{ it.name }}
{{ end }}

Header Code Block

A code block at the top of the page is commonly used as a place for setting page properties. Example:

{{
page.title  = "Cool Dogs"
page.date   = "1999-06-29 15:00"
page.layout = "minimal"
}}

## Golder Retriever
Blah blah blah.

## Jack Russel Terrier
Blah blah blah.

Heredoc Strings

LuaWebGen introduces a new string literal in Lua: the here document (or heredoc) string. The syntax is similar to existing long bracket strings in Lua (i.e. [===[ Blah ]===]) but without the square brackets. The heredoc string has to start at the end of a code block and end at the beginning of another one. Everything between the code blocks will be treated as the contents of the string (including other code blocks). This makes it easy to "disable" embedding of Lua code between two points.

{{ === }}

This is
{{ all treated }}
as text.

{{ === }}

The above is exactly equivalent to:

{{ "\
\
This is\
{{ all treated }}\
as text.\
\
" }}

Just like long brackets, the amount of equal signs determines the level of the string delimiter (i.e. ==== would be level 4, and must be matched by another delimiter of the same level). There must be at least three consecutive equal signs to start a heredoc string (as one and two equal signs already mean other things in Lua).

{{ ==== }}Start
of string,
{{ === }}
and end of
string.{{ ==== }}

Same as:

{{ "Start\
of string,\
{{ === }}\
and end of\
string." }}

You can use heredoc strings just like any regular string in Lua code:

{{
echoRaw("<strong>")

local anchorHtml = ===}}
<a href="http://example.com/">
	Go to the place!
</a>
{{===

echoRaw(anchorHtml)
echoRaw("</strong>")
}}

Using asterisks to trim whitespace from the beginning and the end of strings still works as expected.

{{
local untrimmed = === }} <img> {{ ===
local trimmed   = ===*}} <img> {{*===

print(untrimmed) -- " <img> "
print(trimmed)   -- "<img>"
}}

Page updated: 2021-09-20