Functions
Utility Functions
- a
- ceil
- chooseExistingFile
- chooseExistingImage
- clampArray
- cssPrefix
- date
- entities
- errorf
- F
- fileExists
- fileExistsInOutput
- files
- find
- findAll
- floor
- formatTemplate
- generatorMeta
- getBasename
- getCompleteOutputPath
- getDataBinaryParsers
- getDataTextParsers
- getExtension
- getFilename
- getGeneratedPages
- getImageDimensions
- getKeys
- getOutputtedFiles
- gmatchAndBetween
- img
- indexOf
- ipairsr
- isAny
- isValueHtml
- json.parse
- max
- min
- newStringBuilder
- now
- pairsSorted
- percent
- prettyUrl
- printf
- printfOnce
- printObject
- printOnce
- removeItem
- round
- sortNatural
- split
- summarize
- thumb
- toDatetime
- toLua
- toml.parse
- toTime
- trim
- trimNewlines
- url
- urlAbs
- urlExists
- urlize
- urlRaw
- validateUrls
- warning
- warningOnce
a
html = a( url [, label=prettyUrl(url) ] )
Create a simple HTML <a>
element.
ceil
n = ceil( n )
Alias for math.ceil
.
chooseExistingFile
path = chooseExistingFile( pathWithoutExtension, extensions )
Get the path of an existing file with any of the specified extensions. Returns nil if no file exists.
chooseExistingImage
path = chooseExistingImage( pathWithoutExtension )
Get the path of an existing image file with any of the specified extensions. Returns nil if no image file exists.
Short form for chooseExistingFile(pathWithoutExtension, IMAGE_EXTENSIONS)
.
clampArray
array = clampArray( array, length )
v1.3 Remove all items from array after the given length. Example:
# Latest Posts
{{ fori subpage in clampArray(subpages(), 3) }}
- {{ subpage.title }}
{{ end }}
cssPrefix
css = cssPrefix( property, value )
Quick and dirty way of adding vendor-specific prefixes to a CSS property. Example:
local css = cssPrefix("flex", "auto")
-- css is "-ms-flex: auto; -moz-flex: auto; -webkit-flex: auto; flex: auto;"
date
string = date( format [, time=now ] )
Alias for os.date
.
(See the C docs for date format.)
entities
html = entities( text )
Encode &
, <
, >
, "
and '
characters into HTML entities (&
etc.).
errorf
errorf( [ level=1, ] format, ... )
Raise an error with a formatted message.
Short form for error(F(format, ...), level)
.
F
string = F( format, ... )
Alias for string.format
.
fileExists
bool = fileExists( path )
Check if a file exists in the content folder.
fileExistsInOutput
bool = fileExistsInOutput( path [, skipRewriting=false ] )
Check if a file exists in the output folder, optionally without the usual rewriting of the path.
files
paths = files( folder [, onlyFilenames=false ] )
paths = files( folder [, onlyFilenames=false ], filenamePattern )
paths = files( folder [, onlyFilenames=false ], fileExtensionArray )
paths = files( folder [, onlyFilenames=false ], filterFunction )
Get a list of files in a folder inside the content folder. Examples:
local function dogFilter(filename)
if filename:find"dog" then
return true
end
return false
end
local imagePaths = files("/images", IMAGE_EXTENSIONS)
local psdFilenames = files("/resources/misc", true, "%.psd$")
local dogPaths = files("/animal-files", dogFilter)
find
item, index = find( array, attribute, value )
Get the item in the array whose attribute
is value
.
Returns nil if no item is found.
local people = {
{id=15, name="Harry"},
{id=22, name="Jenny"},
}
print(find(people, "id", 22).name) -- Jenny
findAll
items = findAll( array, attribute, value )
Get all items in the array whose attribute
is value
.
floor
n = floor( n )
Alias for math.floor
.
formatTemplate
template = formatTemplate( format, valueTable )
Quick and dirty formatting of a template, presumably before using generateFromTemplate
.
This replaces all instances of :key:
with the corresponding field's value from valueTable
.
Example:
local templateUnformatted = [[
My dog, :dogName:, likes :thing:.
Other dogs probably like :thing: too!
]]
local template = formatTemplate(templateUnformatted, {
dogName = "Timmie the Dog",
thing = "bones",
})
generateFromTemplate("/dogs/info.md", template)
Note that generateFromTemplate
can take page parameters as an argument that code blocks in the template can use.
So, the above could be written more cleanly like this:
local template = [[
My dog, {{P.dogName}}, likes {{P.thing}}.
Other dogs probably like {{P.thing}} too!
]]
generateFromTemplate("/dogs/info.md", template, {
dogName = "Timmie the Dog",
thing = "bones",
})
generatorMeta
html = generatorMeta( [ hideVersion=false ] )
Get HTML generator meta tag (e.g. <meta name="generator" content="LuaWebGen 1.0.0">
).
This tag makes it possible to track how many websites use this generator, which is cool!
This should be placed in the <head>
element.
getBasename
basename = getBasename( filename )
Get the filename without the extension. Example:
local basename = getBasename"blog/my-post.html"
print(basename) -- "my-post"
getCompleteOutputPath
pathInCwd = getCompleteOutputPath( path )
Get the final (possibly rewritten) path for any file path. Example:
local path = "/images/dog.png"
local pathInCwd = getCompleteOutputPath(path)
print(pathInCwd) -- "output/images/dog.png"
Note: The returned path is relative to current working directory, which is always the site root folder. The LuaWebGen API generally only handle paths relative to the content folder - the return value from
getCompleteOutputPath
is an exception.
getDataBinaryParsers
parsers = getDataBinaryParsers( )
v1.2
Get all parsers for binary data files (including those defined with config.dataBinaryParsers
).
getDataTextParsers
parsers = getDataTextParsers( )
v1.2
Get all parsers for text data files (including those defined with config.dataTextParsers
).
Example:
local defaultParsers = getDataTextParsers()
config.dataTextParsers = {
wlua = defaultParsers.lua,
metainfo = defaultParsers.xml,
}
getExtension
extension = getExtension( path )
Get the extension part of a path or filename.
getFilename
filename = getFilename( path )
Get the filename part of a path.
getGeneratedPages
pages = getGeneratedPages( )
v1.3 Get an array with all pages that has finished generating.
getImageDimensions
width, height = getImageDimensions( path )
Get the width and height of an image. Returns nil and a message on error.
This function may require Lua-GD for some files. PNG files and many JPEG files should work without Lua-GD.
getKeys
keys = getKeys( table )
Get the keys from a table.
getOutputtedFiles
fileInfos = getOutputtedFiles( )
Get an array with information about outputted files/pages. Each item is a table with these fields:
-
path
: Path to the written file in the output folder (after having been rewritten byconfig.rewriteOutputPath
). -
url
: The relative URL for the file. -
sourcePath
: Path to the file in the content folder that triggered the creation of the written file (if there was one - otherwise this is an empty string).
gmatchAndBetween
for position, isMatch, capture1, capture2, ... in gmatchAndBetween( string, pattern )
v1.3
Match strings like string.gmatch
but also capture the strings between the matches.
If isMatch is false then capture1 is the string between the last match and the next. (This string is never empty.)
Example:
local text = "The year 2099 is going to be 1337"
-- Highlight numbers and make other text small.
for position, isMatch, numberOrStringBetween in gmatchAndBetween(text, "%d+") do
if isMatch then
local number = numberOrStringBetween
echoRaw("<strong>")
echo(number)
echoRaw("</strong>")
else
local stringBetween = numberOrStringBetween
echoRaw("<small>")
echo(stringBetween)
echoRaw("</small>")
end
end
img
html = img( url [, alt="", title ] )
html = img( url [, alt="", useAltAsTitle=false ] )
Create a simple HTML <img>
element.
indexOf
index = indexOf( array, value )
Get the index of a value in an array. Returns nil if the value was not found.
ipairsr
for index, value in ipairsr( array )
Iterate backwards through an array.
isAny
bool = isAny( valueToCompare, value1, value2, ... )
Compare a value against a set of values.
isValueHtml
bool = isValueHtml( value )
v1.3 Check if a value is a string, and that it looks like HTML code.
This function is used under the hood by
echoSmart
, and by extension{{valueExpression}}
.
isValueHtml("<a>foo</a>") -- true
isValueHtml("foo") -- false
isValueHtml("<img> foo") -- false
json.parse
value = json.parse( jsonString [, filePathForErrorMessages ] )
value = json( jsonString [, filePathForErrorMessages ] )
v1.3
Parse a string containing JSON.
Returns nil and a message on error.
Note that the function may return false or nil on success, if that's what jsonString
contains (but no message).
Example:
local t = json.parse[[
{
"foo": ["bar", false],
"pi": 3.14
}
]]
print(t.foo[1]) -- bar
This is currently the only function available in the global
json
object.
max
n = max( n1, n2, ... )
Alias for math.max
.
min
n = min( n1, n2, ... )
Alias for math.min
.
newStringBuilder
stringBuilder = newStringBuilder( )
Create a handy string builder object, like so:
local b = newStringBuilder()
-- Add things.
b('<img src="icon.png">') -- One argument adds a plain value.
b(42) -- The one argument can be of any type.
b("<h1>%s</h1>", entities(page.title)) -- Multiple arguments act like string.format().
-- Get the contents.
local html = b() -- No arguments returns the concatenated string.
now
datetime = now( )
Get the current date and time as a datetime string.
pairsSorted
for key, value in pairsSorted( table )
Like pairs
, iterate over the fields of a table,
but in alphabetic order of the keys (sorted naturally).
Note that the function does not detect additions or removals of table fields during the iteration.
percent
encodedString = percent( string )
v1.4
Percent-encode all unreserved characters in a string for use in a URL (spaces become "%20"
, "/"
become "%2F"
etc.).
prettyUrl
text = prettyUrl( url )
Make a URL look nice for displaying as text. Example:
local dogsUrl = "https://www.animals.com/dogs/"
local label = prettyUrl(dogsUrl) -- "animals.com/dogs"
echofRaw('<a href="%s">%s</a>', dogsUrl, label)
printf
printf( format, ... )
Short form for print(F(format, ...))
.
printfOnce
printfOnce( format, ... )
Print a formatted message only once. Meant for preventing too much spam in the console/log.
printObject
printObject( ... )
v1.1 Better printing of tables (though the function accepts any value).
Note: Does not print to the log file - only to stdout.
printOnce
printOnce( ... )
Print value(s) only once. Meant for preventing too much spam in the console/log.
removeItem
removeItem( array, value1, ... )
Remove one or more values from an array. Does not remove duplicate values.
round
number = round( number )
Round a number.
sortNatural
array = sortNatural( array [, attribute ] )
Naturally sort an array of strings. If the array contains tables you can sort by a specific attribute instead. Example:
local t = {"10","2","1"}
table.sort(t) -- t is {"1","10","2"}
sortNatural(t) -- t is {"1","2","10"}
local objects = {
{type="chair", type=1},
{type="bed", type=2},
{type="house", type=3},
}
sortNatural(objects, "type")
split
parts = split( string, separatorPattern [, startIndex=1, plain=false ] )
Split a string by a pattern. Example:
local dogs = split("Fido,Grumpy,The Destroyer", ",")
summarize
html = summarize( html, maxCharacters [, keepSomeElements=false ] )
v1.3 Limit the amount of text and restrict allowed tags in an HTML string. The result can be used e.g. as the description for an item in an RSS feed.
If keepSomeElements is true then elements like <a>
, <em>
, <code>
, <img>
and <svg>
are preserved.
Elements like <br>
and <bdo>
, and any occurrences of the dir
attribute, are always preserved.
Example for an RSS feed:
{{ fori subpage in clampArray(subpages(), 15) }}
{{ if not subpage.isIndex }}
<item>
<title>{{ subpage.title }}</title>
<description><![CDATA[{{ summarize(subpage.content, 400, true) }}]]></description>
<pubDate>{{ os.date("!%a, %d %b %Y %H:%M:%S GMT", toTime(subpage.publishDate)) }}</pubDate>
<link>{{ url(subpage.permalink) }}</link>
<guid>{{ url(subpage.permalink) }}</guid>
</item>
{{ end }}
{{ end }}
thumb
html = thumb( imagePath, thumbWidth [, thumbHeight ] [, isLink=false ] )
Create a thumbnail from an image and get HTML code for showing the thumbnail.
At least one of thumbWidth
or thumbHeight
must be a positive number.
0
means no restriction in that dimension.
Note that sides may get cut off if the aspect ratio of the thumbnail is different from the image.
Example:
{{ thumb("/images/gorillaz-fan-art.png", 400, 400, true) --[[ Size is 400x400. ]] }}
{{ thumb("/images/a-big-tree.gif", 512, true) --[[ Width is 512. ]] }}
{{ thumb("/images/a-big-tree.gif", 512, 0, true) --[[ Same as the above. ]] }}
{{ thumb("/images/1000-clown-cars.jpg", 0, 350, false) --[[ Height is 350. ]] }}
This function requires Lua-GD.
toDatetime
datetime = toDatetime( time )
Convert a time number to a datetime string.
toLua
luaString = toLua( value )
Convert a value to a Lua literal. Supported value types are: boolean, nil, number, string and table. Example:
-- Round-trip test for a string value.
local valueBefore = "foo"
local luaCode = "return "..toLua(valueBefore)
local chunk = loadstring(luaCode)
local valueAfter = chunk()
assert(valueBefore == valueAfter)
toml.parse
table = toml.parse( tomlString [, filePathForErrorMessages ] )
table = toml( tomlString [, filePathForErrorMessages ] )
v1.3 Parse a string containing TOML. Returns nil and a message on error. Example:
local t = toml.parse[===[
[[people]]
name="Alex"
[[people]]
name="Jenny"
]===]
print(t.people[2].name) -- Jenny
This is currently the only function available in the global
toml
object.
toTime
time = toTime( datetime )
Convert a datetime string to a normal time number value that standard libraries understand. Example:
local time = toTime(page.publishDate)
local publishYear = os.date("%Y", time)
trim
string = trim( string )
Remove surrounding whitespace from a string.
trimNewlines
string = trimNewlines( string )
Remove surrounding newlines from a string.
url
encodedUrl = url( urlString )
Percent-encode essential characters in a URL (spaces become %20
etc.).
Does not encode %
, so it's OK for the URL to already have some percent-encoded characters.
If the URL is relative then the path part of site.baseUrl
, if it has one, is prepended (keeping the URL relative).
Examples:
print(url"/hello world.jpg")
-- Output if baseUrl is "http://example.com/": /hello%20world.jpg
-- Output if baseUrl is "http://example.com/abc/": /abc/hello%20world.jpg
Note:
url
does not encode HTML entities, like ampersand, thus does not produce valid HTML:local src = url("/thumb.php?size=200&name=Hello world!") local html = F('<img src="%s">', entities(src)) -- Correct. local html = F('<img src="%s">', src) -- Incorrect.
urlAbs
encodedUrl = urlAbs( urlString )
Same as url
but prepends the whole site.baseUrl
to relative URLs, making them absolute.
urlExists
bool = urlExists( url )
Check that a file for the URL exists.
Useful e.g. as a sanity check after moving a bunch of pages (that now should have explicit aliases).
Note that URLs to pages that have not been generated yet will make the function return false.
See validateUrls
for multiple URL checks.
Example:
function config.validate()
local oldUrl = "/old-folder/my-post/"
if not urlExists(oldUrl) then
error("Page is missing: "..oldUrl)
end
end
urlize
urlPart = urlize( string )
Make a string look like a URL. Useful e.g. when converting page titles to URL slugs.
urlize("Hello, big world!") -- "hello-big-world"
urlRaw
encodedUrl = urlRaw( urlString )
v1.4
Same as url
but does not prepend anything to relative URLs.
validateUrls
validateUrls( urls )
Check that files for multiple URLs exist, and trigger an error if any don't exist.
Useful e.g. as a sanity check after moving a bunch of pages (that now should have explicit aliases).
See urlExists
for single URL checks.
Example:
function config.validate()
validateUrls{
"/old-folder/my-post/",
"/work-in-progress/dog.png",
}
end
warning
warning( message )
Print a big warning message to the console. Nothing else happens.
warningOnce
warningOnce( message )
Print a big warning message to the console once only. Nothing else happens.
Context-Specific Functions
- echo
- echof
- echofRaw
- echoRaw
- echoSmart
- generateFromTemplate
- include
- isCurrentUrl
- isCurrentUrlBelow
- lock
- outputRaw
- preserveRaw
- subpages
There are currently 3 contexts where code can run:
- Templates (HTML, Markdown and CSS files)
- Config (
config.before
andconfig.after
) - Validation (
config.validate
)
echo
echo( value )
Output a string (or any other kind of value) from a template.
HTML entities are encoded automatically in HTML and XML files.
In other types of templates this function behaves exactly like echoRaw
.
Available in templates.
Note: This function is used under the hood and it's often not necessary to call it manually. For example, these rows do the same thing:
{{ date"%Y" }} {{ echo(date"%Y") }}
echof
echof( format, ... )
Short form for echo(F(format, ...))
.
echofRaw
echofRaw( format, ... )
Short form for echoRaw(F(format, ...))
.
echoRaw
echoRaw( string )
Like echo
, output a string from a template, except HTML entities don't become encoded in this string.
Available in templates.
echo ("a < b") -- Output is "a < b"
echoRaw("a < b") -- Output is "a < b"
Note: In templates, if an echo function isn't used then HTML entities are sometimes encoded and sometimes not - LuaWebGen tries to be smart about it:
{{ "<br>" }} <!-- Output is "<br>" --> {{ "Foo <br>" }} <!-- Output is "Foo <br>" --> {{ echo"<br>" }} <!-- Output is "<br>" --> {{ echo"Foo <br>" }} <!-- Output is "Foo <br>" --> {{ echoRaw"<br>" }} <!-- Output is "<br>" --> {{ echoRaw"Foo <br>" }} <!-- Output is "Foo <br>" -->
echoSmart
echoSmart( value )
v1.3
Output a value from a template in a "smart" way.
This function calls echoRaw
if value looks like HTML.
Otherwise it calls echo
, unless the value is nil is which case it does nothing.
This function is used under the hood by
{{valueExpression}}
.
generateFromTemplate
page = generateFromTemplate( path, templateString )
page = generateFromTemplate( path, templateString, pageParameters )
page = generateFromTemplate( path, templateString, pageInitializer )
Generate a page from a template string.
Available in config.before
and config.after
.
path
is the file path the template would have had if it was loaded from a file in the content folder, e.g. "/blog/2020/06/fishing.md"
.
It is used to determine the template file type and URL for the page.
The function optionally takes page parameters as an argument for code blocks in the template, or it's layout, to use.
Examples:
local path = "/dogs/fido.md"
local template = "# Fido\n\nFido is fluffy!"
local page = generateFromTemplate(path, template)
printf("We generated page '%s'.", page.url)
local template = [[
{{
page.title = "Carpets"
page.layout = "normalPageWithFooter"
}}
Experience the best carpets around!
]]
local params = {
creditsInPageFooter = {
{what="Fabric", who="Soft Inc."},
{what="Paint", who="Bob Bobson Co."},
},
}
generateFromTemplate("/products/carpets.md", template, params)
v1.1
If the pageInitializer
argument is given, it should be a callback function.
It will execute before any embedded code in the template just as if the function's body was the topmost part of the header code block.
The function also will be called in the template context, so the usual global objects, like page
or params
, are accessible like normally in a template.
In other words, this is a good place to update page properties.
This example has the same outcome as the previous example:
local template = [[
Experience the best carpets around!
]]
generateFromTemplate("/products/carpets.md", template, function()
page.title = "Carpets"
page.layout = "normalPageWithFooter"
P.creditsInPageFooter = {
{what="Fabric", who="Soft Inc."},
{what="Paint", who="Bob Bobson Co."},
}
end)
include
html = include( filename )
html = include( filename, extraArgument1, ... ) -- v1.4
Get the result of a HTML template from the layouts folder. Available in templates.
Note: Exclude the extension from the filename (e.g. include("footer")
).
v1.4
Extra arguments can be sent to the layout.
They can be grabbed using the vararg expression (...
) in file scope.
Example:
<!-- content/laugh.html -->
{{ include("repeat", "ha", 3) }}
<!-- layouts/repeat.html -->
<p> I say
{{
local stringToRepeat, numberOfRepeats = ...
echo(stringToRepeat:rep(numberOfRepeats))
}}
</p>
isCurrentUrl
bool = isCurrentUrl( url )
Check if the relative URL of the current page is url
.
Available in templates.
Example:
{{ if isCurrentUrl"/blog/last-post/" }}
You've reached the end!
{{ end }}
isCurrentUrlBelow
bool = isCurrentUrlBelow( urlPrefix )
Check if the relative URL of the current page starts with urlPrefix
.
Available in templates.
Example:
{{ local class = isCurrentUrlBelow"/blog/" and "current" or "" }}
<a href="/blog/" class="{{ class }}">Blog</a>
lock
lock( )
Prevent further changes to page properties, such as page.isDraft
and page.publishDate
.
This allows the current page to be referenced elsewhere (e.g. in index pages) even during it's generation, preventing circular dependencies.
Here's an example of two pages referencing each other through subpages
:
a.md
{{
page.title = "Cute Kittens"
lock()
-- page.title = "Sly Turtles" -- Error!
}}
(imagine cute kittens)
Also see:
{{ for subpage in subpages() }}
- [{{ subpage.title }}]({{ url(subpage.url) }})
{{ end }}
b.md
{{
page.title = "Playful Puppies"
lock()
}}
(imagine playful puppies)
Also see:
{{ for subpage in subpages() }}
- [{{ subpage.title }}]({{ url(subpage.url) }})
{{ end }}
outputRaw
outputRaw( path, contents )
Output any data to a file in the output folder.
Available in config.before
and config.after
.
Example:
outputRaw("/docs/versions.txt", "Version 1\nReleased: 2002-10-16\n")
preserveRaw
preserveRaw( path )
Prevent a previously outputted raw file from being cleaned out from the output folder after the site generation is done.
This function makes it possible to not having to call outputRaw
every time the site builds which could decrease build time.
Available in config.before
and config.after
.
Note: This functionality is automatically used for all non-template files (like images or JavaScript files) in the content folder.
subpages
pages = subpages( [ includeCurrentPage=false ] ) -- Available in templates.
pages = subpages( pathPrefix ) -- v1.3 Available anywhere.
Recursively get all (non-special) pages in the current folder and below (or pages matching pathPrefix
, since v1.3),
sorted by page.publishDate
from newest to oldest.
Intended for index pages, but can be used anywhere.
Example:
# Blog Archive
{{ fori subpage in subpages() }}
- [{{ os.date("%Y-%m-%d", toTime(subpage.publishDate)) }} {{ subpage.title }}]({{ url(subpage.url) }})
{{ end }}
Note: Two pages in the same folder cannot normally request all subpages - that would result in an infinite loop as LuaWebGen tries to generate all subpages before returning a list of them. However, you can solve this by calling
lock
in all relevant pages, or enableconfig.autoLockPages
. This will prevent further changes to essential page information (such aspage.isDraft
orpage.publishDate
) and thus allowing the page to be referenced elsewhere even during it's generation.Another possible solution is to generate at least one of those two pages in
config.after
.
Page updated: 2022-04-13