htmlua - Lua HTML templater
One of my favorite features in the Lua language is a piece of syntactic sugar: Lua lets you remove parentheses when calling functions with a single table or string argument, e.g.
require 'torch'
print{1, 2, 3}
I have used this elegant feature to build libraries such as luaclass and luaimport.
htmlua takes advantage of this syntactic sugar to build a pure-lua HMTL templating engine. This project is now integrated into waffle.
Example Usage
local html = require 'htmlua'
return html.html {
html.head {
html.title "Title"
},
html.body {
html.p "yo",
html.img {
src="https://www.google.com/images/srpr/logo11w.png"
}
}
}
renders as
Titleyo
Amazingly, there is no compiler, no 3rd-party language, that's pure lua! That means that all of your typical lua language structure, libraries, variables, etc. can be used seamlessly. But I've built some helpers in too:
Conditionals
local x = 5
IF {
x == 5,
THEN(h.p "x == 5"),
ELSE(h.p "x ~= 5")
}
x == 5
Loops
Option 1
DO(function()
local rv = ''
for _, name in pairs(names) do
rv = rv .. h.li(name)
end
return h.ul(rv)
end)
Option 2
local names = {'lua', 'python', 'javascript'}
h.ul(each(names, h.li))
Both render as:
- lua
- python
- javascript
Option 3
h.ul(
loop{1, 2, 3, 'test', key=5}(function(k, v)
return h.li(v)
end)
)
- 1
- 2
- 3
- test
- 5
Comments
comment "test comment",
comment {
h.p "p",
h.div {
h.h3 "h3"
}
}
Note that traditional lua comments can also be put inside an htmlua template, since it's executing pure-lua.
Blocks
Blocks allow for template inheritance
-- base.html
return h.html {
h.head {
h.title 'Base'
},
h.body {
defblock 'content',
defblock 'content2',
h.p 'base'
}
}
-- ext.lua
h = require 'htmlua'
base = extends 'examples/base.lua'
base = block(base, 'content')(h.h1 'content')
base = block(base, 'content2'){
h.div {
h.p 'content2'
}
}
Basecontent
content2
base
HTML Entities
HTML entities display reserved characters in HTML, e.g. the non-breaking space, less than, greather than, etc.
h.div {
h.span "hello", h.lt, h.nbsp, h.gt, h.span "hello2"
}
String Interpolation
h.p '${name} is cool' % {name='htmlua'}
htmlua is cool
Async Rendering (with a larger example)
-- basetemp.lua
return h.html {
h.head {
h.title 'Base'
},
h.body {
defblock 'content',
h.p '${msg}'
}
}
-- midtemp.lua
local base = extends 'examples/basetemp.lua'
return block(base, 'content'){
h.ul(each([[${users}]], h.li)),
defblock 'content2'
}
-- temp.lua
local base = extends 'examples/midtemp.lua'
return block(base, 'content2'){
h.div {
h.p {
h.b 'Time: ',
h.i '${time}'
}
}
}
local args = {
msg = 'Hello World',
users = {'lua', 'python', 'javascript'},
time = os.time()
}
render('examples/temp.lua', args, print)
Base- lua
- python
- javascript
Time: 1437167130
Hello World
htmlua (executable)
The htmlua executable lets you compile and save lua source as html.
> htmlua -f examples/test.lua -o out.html
Inspirations
This project takes inspiration from: