Skip to the content.

Luma API Documentation

Complete API reference for the Luma template engine.

Table of Contents

  1. Core API
  2. Compiler API
  3. Runtime API
  4. Filters API
  5. Python Bindings

Core API

luma.render(template, context, options)

Render a template string with context data.

Parameters:

Returns: (string) Rendered output

Example:

local luma = require("luma")

local result = luma.render("Hello, $name!", {name = "World"})
print(result)  -- "Hello, World!"

Error Handling:

local ok, result = pcall(function()
    return luma.render(template, context)
end)

if not ok then
    print("Error:", result)
end

luma.compile(template, options)

Compile a template for reuse.

Parameters:

Returns: (table) Compiled template object

Example:

local luma = require("luma")

-- Compile once
local compiled = luma.compile("Hello, $name!")

-- Render many times
local filters = require("luma.filters")
local runtime = require("luma.runtime")

for _, user in ipairs(users) do
    local result = compiled:render(
        {name = user.name},
        filters.get_all(),
        runtime
    )
    print(result)
end

Performance: Compiling and reusing templates is 50-100x faster than rendering from source each time.

luma.new_environment(options)

Create a template environment with shared state.

Parameters:

Returns: (table) Environment object

Methods:

Example:

local luma = require("luma")

local env = luma.new_environment({
    paths = {"/templates", "."},
    globals = {site_name = "My Site"},
})

local result = env:render_file("page.luma", {title = "Home"})

Compiler API

compiler.compile(source, options)

Low-level template compilation.

Parameters:

Returns: (table) Compiled template with metadata

Example:

local compiler = require("luma.compiler")

local compiled = compiler.compile(source, {name = "mytemplate"})

-- Access metadata
print("Template name:", compiled.name)
print("Source:", compiled.source)  -- Generated Lua code
print("Dependencies:", #compiled.dependencies)

compiled:render(context, filters, runtime, macros, tests)

Render a compiled template.

Parameters:

Returns: (string) Rendered output


Runtime API

runtime.escape(value, column)

HTML-escape a value.

Parameters:

Returns: (string) HTML-escaped string

Example:

local runtime = require("luma.runtime")

local escaped = runtime.escape("<script>alert('xss')</script>")
-- Returns: "&lt;script&gt;alert('xss')&lt;/script&gt;"

runtime.set_paths(paths)

Set template search paths.

Parameters:

Example:

local runtime = require("luma.runtime")

runtime.set_paths({"/usr/share/templates", "./templates", "."})

runtime.load_source(name)

Load template source by name.

Parameters:

Returns:

Example:

local runtime = require("luma.runtime")

local source, err = runtime.load_source("layout.luma")
if not source then
    error("Template not found: " .. err)
end

runtime.namespace(initial)

Create a mutable namespace object for templates.

Parameters:

Returns: (table) Namespace object

Example (in template):

{% set ns = namespace(count=0) %}
{% for item in items %}
  {% do ns.count = ns.count + 1 %}
{% endfor %}
Total: {{ ns.count }}

Filters API

Built-in Filters

String Filters

upper - Convert to uppercase

{{ "hello" | upper }}  -- "HELLO"

lower - Convert to lowercase

{{ "HELLO" | lower }}  -- "hello"

title - Title case

{{ "hello world" | title }}  -- "Hello World"

capitalize - Capitalize first letter

{{ "hello" | capitalize }}  -- "Hello"

trim - Remove whitespace

{{ "  hello  " | trim }}  -- "hello"

truncate(length, end) - Truncate string

{{ "Long text" | truncate(5) }}  -- "Long..."
{{ "Long text" | truncate(5, "…") }}  -- "Long…"

replace(old, new) - Replace substring

{{ "hello world" | replace("world", "Lua") }}  -- "hello Lua"

List Filters

length - Get length

{{ items | length }}  -- number of items

join(sep) - Join list elements

{{ ["a", "b", "c"] | join(", ") }}  -- "a, b, c"

first - First element

{{ items | first }}

last - Last element

{{ items | last }}

sort - Sort list

{{ [3, 1, 2] | sort }}  -- [1, 2, 3]

reverse - Reverse list

{{ [1, 2, 3] | reverse }}  -- [3, 2, 1]

Numeric Filters

abs - Absolute value

{{ -5 | abs }}  -- 5

round(precision) - Round number

{{ 3.14159 | round(2) }}  -- 3.14

format(fmt) - Format number

{{ 1234.5 | format("%.2f") }}  -- "1234.50"

Date/Time Filters

date(format) - Format timestamp

{{ timestamp | date("%Y-%m-%d") }}

Misc Filters

default(value) - Default if nil/empty

{{ var | default("N/A") }}

escape - HTML escape (alias: e)

{{ "<script>" | escape }}  -- "&lt;script&gt;"

Custom Filters

Define custom filter:

local filters = require("luma.filters")

filters.add("double", function(value)
    return value * 2
end)

filters.add("greet", function(name, greeting)
    greeting = greeting or "Hello"
    return greeting .. ", " .. name .. "!"
end)

Use in template:

{{ 5 | double }}  -- 10
{{ "Alice" | greet }}  -- "Hello, Alice!"
{{ "Bob" | greet("Hi") }}  -- "Hi, Bob!"

Python Bindings

Template Class

from luma import Template

# Create template
template = Template("Hello, {{ name }}!", syntax="jinja")

# Render with kwargs
result = template.render(name="World")

# Render with dict
result = template.render_dict({"name": "World"})

# String representation
print(repr(template))  # <Template source="...">

Environment Class

from luma import Environment
from luma.loaders import FileSystemLoader

# Create environment
env = Environment(
    loader=FileSystemLoader("/path/to/templates"),
    autoescape=True
)

# Set globals
env.globals["site_name"] = "My Site"

# Add filter
env.filters["double"] = lambda x: x * 2

# Render template
template = env.get_template("page.html")
result = template.render(title="Home", items=[1, 2, 3])

Loaders

FileSystemLoader:

from luma.loaders import FileSystemLoader

loader = FileSystemLoader("/templates", encoding="utf-8")

DictLoader:

from luma.loaders import DictLoader

loader = DictLoader({
    "index.html": "Hello, {{ name }}!",
    "about.html": "About page",
})

PackageLoader:

from luma.loaders import PackageLoader

loader = PackageLoader("myapp", "templates")

Exceptions

from luma.exceptions import (
    TemplateError,
    TemplateSyntaxError,
    TemplateNotFoundError,
)

try:
    result = template.render(**data)
except TemplateSyntaxError as e:
    print(f"Syntax error: {e}")
except TemplateError as e:
    print(f"Template error: {e}")

Error Handling

Compilation Errors

local luma = require("luma")

local ok, compiled = pcall(function()
    return luma.compile(template_source)
end)

if not ok then
    -- compiled contains error message
    print("Compilation failed:", compiled)
end

Runtime Errors

local ok, result = pcall(function()
    return compiled:render(context, filters, runtime)
end)

if not ok then
    print("Runtime error:", result)
end

Error Messages

Luma provides detailed error messages with:

Example error:

ParseError: Expected 'end' after 'for' block
  at template.luma:15:1
  
  13 | @for item in items
  14 |   - {{ item }}
> 15 | @if condition

Performance Tips

  1. Compile Once, Reuse Many Times

    local compiled = luma.compile(template)
    for i = 1, 1000 do
        compiled:render(data, filters, runtime)
    end
    

    50-100x faster than re-compiling each time

  2. Use Native Syntax
    • Luma native syntax is cleaner and slightly faster
    • Jinja2 syntax has minimal overhead
  3. Pre-structure Data
    • Prepare data before rendering
    • Avoid complex transformations in templates
  4. Cache Compiled Templates

    local cache = {}
       
    function get_template(name)
        if not cache[name] then
            local source = load_template_source(name)
            cache[name] = luma.compile(source)
        end
        return cache[name]
    end
    

Thread Safety

Multi-threaded example (conceptual):

local compiled = luma.compile(template)  -- Shared
local filters = require("luma.filters").get_all()  -- Shared
local runtime = require("luma.runtime")  -- Shared

-- In each thread:
local result = compiled:render(
    {user = thread_specific_user},  -- Thread-local context
    filters,
    runtime
)

See Also