https://github.com/gilzoide/molde
Zero dependency, single file template engine for Lua 5.1+ with builtin sandbox support
https://github.com/gilzoide/molde
lua luarocks sandboxed single-file template template-engine zero-dependency
Last synced: 11 months ago
JSON representation
Zero dependency, single file template engine for Lua 5.1+ with builtin sandbox support
- Host: GitHub
- URL: https://github.com/gilzoide/molde
- Owner: gilzoide
- License: lgpl-3.0
- Created: 2017-02-12T20:58:00.000Z (almost 9 years ago)
- Default Branch: main
- Last Pushed: 2023-01-08T14:41:29.000Z (about 3 years ago)
- Last Synced: 2025-02-28T16:58:43.573Z (11 months ago)
- Topics: lua, luarocks, sandboxed, single-file, template, template-engine, zero-dependency
- Language: Lua
- Homepage: https://gilzoide.github.io/molde/topics/README.md.html
- Size: 67.4 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
Molde
=====
[](https://travis-ci.org/gilzoide/molde)
Zero dependency, single file template engine for Lua 5.1+ with builtin sandbox
support.
It compiles a template string to a function that generates the final
string by substituting values by the ones in a sandboxed environment.
Templates
---------
There are 3 constructs templates recognize:
- **Literals**: Content that will be copied unmodified to the final string.
Read the [note on long strings](#note-on-long-strings)
- **Value**: A value processed by Lua and appended to the final string,
stringified by `tostring`
- **Statement**: A Lua code block to be copied unmodified to the generated code,
used for variable assignments, repetitions, conditions, etc. It doesn't
directly generate contents for the final string
**Values** are delimited by matching `{{` and `}}`, **statements** by `{%` and
`%}`, and everything else is considered **literal**. Delimiter characters `{`,
`}` and `%` can be escaped using a leading backslash. If you want literal `}}`
or `%}` in your template, they **must** be escaped, or molde will return
error.
Example:
```
NOTE: This is not a valid molde template for educational purposes.
By default, everything is copied unmodified to the final string.
Values are just Lua expressions:
- Hello {{ "world" }}
"Hello world"
- {{ 5 + 3 * 4 }}
"17"
- {{ nil or "default" }}
"default"
- You are using {{ _VERSION }}
"You are using Lua 5.3" (You may use Lua 5.1 and 5.2 as well)
- Line 1{{ "\n" }}Line 2
"Line 1
Line 2"
- Escaping \{{ Hi! \}} (Note that you MUST escape the closing '}}')
"Escaping {{ Hi! }}"
- Escaping is characterwise, so \{{ is as valid as {\{
"Escaping is characterwise, so {{ is as valid as {{"
- table.insert is used in values {{ so they must be a valid expression! }}
Error: ')' expected near 'they'
Statements are Lua statements:
- {% for i = 1, 5 do %}{{ i }} {% end %}
"1 2 3 4 5 "
- {% -- this is just a comment, y'know %}
""
- {{ unbound_variable }}{% unbound_variable = "Hi!" %} {{ unbound_variable }}
"nil Hi!"
- {% if false then %}This will never be printed{% else %}Conditionals!{% end %}
"Conditionals!"
- \{% Escaping works \%} {\% here as well %\} (You MUST escape closing '%}' too)
"{% Escaping works %} {% here as well %}"
- {% if without_then %}Statements must form valid Lua code!{% end %}
Error: 'then' expected near 'table'
```
Note on long strings
--------------------
The lua reference manual says:
For convenience, when the opening long bracket is immediately
followed by a newline, the newline is not included in the string.
The code generated by molde to insert literals uses long strings, so newlines
that come immediately after a closing value or statement **will not** be
considered in the final string.
Installing
----------
Using [LuaRocks](https://luarocks.org/):
# luarocks install molde
Or you may copy the only source file `molde.lua` to your Lua path
Using
-----
```lua
local molde = require 'molde'
-- molde.load and molde.loadfile return a function that receives a table
-- with the values to substitute, and the optional environment (default: _G)
hello_template = molde.load([[Hello {{ name or "world" }}]])
print(hello_template()) -- "Hello world"
print(hello_template{name = "gilzoide"}) -- "Hello gilzoide"
name = "gilzoide"
print(hello_template({}, _ENV or getfenv())) -- "Hello gilzoide"
-- load the template from a file (same template)
hello_template = molde.loadfile("hello_template")
name = nil
print(hello_template()) -- "Hello world"
```
Testing
-------
Run automated tests using [busted](http://olivinelabs.com/busted/):
$ busted
Documentation
-------------
The API is documented using [LDoc](https://github.com/stevedonovan/LDoc) and
is available at [github pages](http://gilzoide.github.io/molde).
To generate:
$ ldoc . -d docs
Change log
----------
+ 2.0.0 - Removed dependency on LPegLabel in favor of a pure streaming parser,
added `molde.tokenize`, changed `molde.parse` function to be an iterator
instead of returning table, move doc comments to source file, changed
`string_bracket_level` to be a function argument instead of module-wide
configuration, change `molde.load` to return `nil` + error instead of raising.
+ 1.0.1 - Fix error handling for matching on LpegLabel v1.5
+ 1.0.0 - Updated to use LpegLabel version 1.5+
+ 0.1.6 - Support for Lua 5.1