These are examples of using loot. All of them assume that loot has been already loaded: local loot = require "loot".
Simple templates
template = loot.template "Hello, %username%!" -- creates a new template using provided string
filled_template = template{ -- creates a new template object using provided data
username = "mrsmith" -- fields correspond to strings between percentage signs in the template string
}
print(filled_template) -- Hello, mrsmith! -- fills in the data and prints the result
template = loot.template "Hello, %name%! This day is 20%% %kind% than yesterday!"
-- double all the percentage signs without special meaning
filled_template = template{
kind = "cooler"
}
print(filled_template) -- Hello, %name%! This day is 20% cooler than yesterday!
-- there is no data for field "name", so it's not processed at all
template = loot.template "Hello, %name%! This day is 20%% %kind% than yesterday!"
template.name = "John" -- template now contains data for marker "name"
filled_template = template{
name = "Bob",
kind = "cooler"
}
print(filled_template) -- Hello, John! This day is 20% cooler than yesterday!
-- provided data doesn't override data set for the template beforehand
Filling templates
template = loot.template "Hello, %name%! This day is 20%% %kind% than yesterday!"
filled_template = template{
name = "Bob",
kind = "cooler"
}
-- Note that this hasn't actually generated string result.
-- It only linked template to the provided data.
-- Thinking OOP, it created an object of class "template" and initialized it.
-- There are several ways to get the string result...
text = filled_template() -- call it
print(filled_template) -- print it (writing to file or socket works, too)
text = tostring(filled_template) -- tostring it
text = filled_template .. some_string -- concatenate it
Non-trivial behaviour
template = loot.template "It is %kind% outside"
function template:kind() -- marker is a method
if self.temperature > 30 then
return "hot"
elseif self.temperature > 20 then
return "warm"
elseif self.temperature >= 0 then
return "not as warm as desired"
else
return "cold"
end
end
filled_template = template{
temperature = 25
}
print(filled_template) -- It is warm outside
template = loot.template [[String "%string%" is %n% characters long. ]]
function template:n()
return self.string:len()
end
filled_template = template{
string = "foobar"
}
print(filled_template) -- String "foobar" is 6 characters long.
Nested templates
template1 = loot.template [[
<html>
<head>
<title>%title%</title>
</head>
<body>
%body%
</body>
</html>
]]
template2 = loot.template [[
<h1>%title%</h1>
<div>
%content%
</div>]]
template1.body = template2
-- usage:
filled_template = template1{
title = "My page",
content = "My content"
}
print(filled_template) --[[
<html>
<head>
<title>My page</title>
</head>
<body>
<h1>My page</h1> -- nested template sees outer data
<div>
My content
</div>
</body>
</html>
]]
Preprocessing
local md = require "markdown" -- lua library for parsing markdown
template = loot.template [[
<article>
<header>
Author: %author%<br>
%date%
</header>
<div>
%text%
</div>
</article>
]]
function template:text(text) -- methods receive outer data as argument
return md(text)
end
-- usage
filled_template = template{
author = "Mr. Smith",
date = "12.04.2013",
text = [[
# Header
Hello!
]]
}
print(filled_template) --[[
<article>
<header>
Author: Mr. Smith<br>
12.04.2013
</header>
<div>
<h1>Header</h1>
<p>Hello!</p>
</div>
</article>
]]
template = loot.template [[The string is "%string%"]]
function template:__prepare() -- this method is called right before filling template
self.string = self.string:rep(self.n) -- something weird
end
filled_template = template{
string = "foobar",
n = 3
}
print(filled_template) -- The string is "foobarfoobarfoobar"
-- Note that it's possible to define other special methods for a template class
-- and then use them in __prepare() or markers-methods (see Non-trivial behaviour)
-- Names of these methods should start with two underscores.