mirror of
https://github.com/TangentFoxy/etlua.git
synced 2025-07-27 18:42:17 +00:00
188 lines
4.9 KiB
Markdown
188 lines
4.9 KiB
Markdown
# etlua
|
|
|
|
Embedded Lua templating
|
|
|
|
## Install
|
|
|
|
```bash
|
|
$ luarocks install etlua
|
|
```
|
|
|
|
## Tutorial
|
|
|
|
```lua
|
|
local etlua = require "etlua"
|
|
local template = etlua.compile([[
|
|
Hello <%= name %>,
|
|
Here are your items:
|
|
<% for i, item in pairs(items) do %>
|
|
* <%= item -%>
|
|
<% end %>
|
|
]])
|
|
|
|
print(template({
|
|
name = "leafo",
|
|
items = { "Shoe", "Reflector", "Scarf" }
|
|
}))
|
|
|
|
```
|
|
|
|
## Reference
|
|
|
|
The following tags are supported
|
|
|
|
* `<% lua_code %>` runs lua code verbatim
|
|
* `<%= lua_expression %>` writes result of expression to output, HTML escaped
|
|
* `<%- lua_expression %>` same as above but with no HTML escaping
|
|
|
|
Any of the embedded Lua tags can use the `-%>` closing tag to suppress a
|
|
following newline if there is one, for example: `<%= 'hello' -%>`.
|
|
|
|
The module can be loaded by doing:
|
|
|
|
```lua
|
|
local etlua = require "etlua"
|
|
```
|
|
|
|
### Methods
|
|
|
|
#### `func = etlua.compile(template_string)`
|
|
|
|
Compiles the template into a function, the returned function can be called to
|
|
render the template. The function takes one argument: a table to use as the
|
|
environment within the template. `_G` is used to look up a variable if it can't
|
|
be found in the environment.
|
|
|
|
#### `result = etlua.render(template_string, env)`
|
|
|
|
Compiles and renders the template in a single call. If you are concerned about
|
|
high performance this should be avoided in favor of `compile` if it's possible
|
|
to cache the compiled template.
|
|
|
|
### Errors
|
|
|
|
If any of the methods fail they will return `nil`, followed by the error
|
|
message.
|
|
|
|
### How it works
|
|
|
|
* Templates are transparently translated into Lua code and then loaded as a
|
|
function. Rendering a compiled template is very fast.
|
|
* Any compile time errors are rewritten to show the original source position in
|
|
the template.
|
|
* The parser is aware of strings so you can put closing tags inside of a string
|
|
literal without any problems.
|
|
|
|
## Raw API
|
|
|
|
The raw API is a bit more complicated but it lets you insert code between the
|
|
compile stages in addition to exposing the internal buffer of the template.
|
|
|
|
All methods require a parser object:
|
|
|
|
```lua
|
|
local parser = etlua.Parser()
|
|
```
|
|
|
|
#### `lua_code, err = parser.compile_to_lua(etlua_code)`
|
|
|
|
Parses a string of etlua code, returns the compiled Lua version as a
|
|
string.
|
|
|
|
Here's an example of the generated Lua code:
|
|
|
|
```lua
|
|
local parser = etlua.Parser()
|
|
print(parser:compile_to_lua("hello<%= world %>"))
|
|
```
|
|
|
|
```lua
|
|
local _b, _b_i, _tostring, _concat, _escape = ...
|
|
_b_i = _b_i + 1
|
|
_b[_b_i] = "hello"
|
|
_b_i = _b_i + 1
|
|
--[[9]] _b[_b_i] = _escape(_tostring( world ))
|
|
_b_i = _b_i + 1
|
|
_b[_b_i] = ""
|
|
return _b
|
|
```
|
|
|
|
There are a few interesting things: there are no global variable references,
|
|
all required values are passed in as arguments, and comments are inserted to
|
|
annotate the positions of where code originated from. `_b` is expected to be a
|
|
regular Lua table that is the buffer where chunks of the template are inserted
|
|
as it's executed.
|
|
|
|
#### `fn, err = parser.load(lua_code)`
|
|
|
|
Converts the Lua code returned by `parser.compile_to_lua` into an actual
|
|
function object. If there are any syntax errors then `nil` is returned along
|
|
with the error message. At this stage syntax errors are rewritten to point to
|
|
the original location in the etlua code and not the generated code.
|
|
|
|
#### `result = parser.run(fn, env={}, buffer={})`
|
|
|
|
Executes a loaded function returned by `parser.load` with the specified buffer
|
|
and environment. Returns the result of fn, which is typically the buffer. The
|
|
environment is applied to `fn` with `setfenv` (a version is included for Lua
|
|
5.2).
|
|
|
|
### Example
|
|
|
|
For example we can render multiple templates into the same buffer:
|
|
|
|
```lua
|
|
parser = etlua.Parser()
|
|
|
|
first_fn = parser:load(parser:compile_to_lua("Hello "))
|
|
second_fn = parser:load(parser:compile_to_lua("World"))
|
|
|
|
buffer = {}
|
|
parser:run(first_fn, nil, buffer, #buffer)
|
|
parser:run(second_fn, nil, buffer, #buffer)
|
|
|
|
print(table.concat(buffer)) -- print 'Hello World'
|
|
```
|
|
|
|
## Custom compiler
|
|
|
|
If you need to customize the Lua code that is generated by etlua to integrate
|
|
with your own output buffers then you can provide a custom compiler.
|
|
|
|
You can extend `etlua.Compiler` and override it's methods to control the
|
|
output. See <https://github.com/leafo/etlua/blob/master/etlua.moon#L42> for the
|
|
implementation of the default compiler
|
|
|
|
For an example we'll create a debug compiler that prints whenever a template is
|
|
executed.
|
|
|
|
```moonscript
|
|
-- create a custom compiler
|
|
import Compiler from require "etlua"
|
|
|
|
class DebugCompiler extends Compiler
|
|
header: =>
|
|
@push 'print("Running template")\n'
|
|
super!
|
|
|
|
-- try it out
|
|
import Parser from require "etlua"
|
|
|
|
print Parser!\compile_to_lua "hello", DebugCompiler
|
|
```
|
|
|
|
`compile_to_lua` takes an optional second argument of the compiler class to
|
|
use.
|
|
|
|
## Editor Support
|
|
|
|
* [Vim](https://github.com/VaiN474/vim-etlua)
|
|
* [Visual Studio Code](https://github.com/commita/vscode-lua-templates)
|
|
* [Sublime/Textmate](https://github.com/VaiN474/etlua-tmLanguage)
|
|
* [Atom](https://github.com/VaiN474/language-etlua)
|
|
|
|
## License
|
|
|
|
MIT, Copyright (C) 2014 by Leaf Corcoran
|
|
|