Antlers is a templating language designed to be embedded within HTML, where that HTML itself is embedded within a Ruby file. Antlers is used by LowNode to render child nodes in a compositional way.
Access an instance variable with:
def render
<html>{@user}</html>
endℹ️ See Variables API.
Render a class named UserNode with:
def render
<html><{ UserNode }></html>
endℹ️ The class referenced via <{ MyClass }> syntax must implement a render method.
Props:
def render
<html><{ UserNode user=@user }></html>
endSlots:
def render
<html>
<{ LayoutNode: }>
<{ UserNode user=@user }>
<{ :LayoutNode }>
</html>
endThe LayoutNode would look like:
class LayoutNode
def render(event:)
<header>...</header>
<{ :slot }>
<footer>...</footer>
end
end# Block.
<{ if: @user.happy? }>
<{ UserNode user=@user }>
<{ :if }>
# Directive. [UNRELEASED]
<{ UserNode user=@user if: @user.happy? }># Block.
<{ for: user in: @users }>
<{ UserNode user=user }>
<{ :for }>
# Directive. [UNRELEASED]
<{ UserNode user=user for: user in: @users }>ℹ️ You can iterate a hash with for: key, value syntax.
Forms can be created in a compositional way, mixing both Antlers syntax with regular form elements:
<{ form: '/submit' }>
<input type="submit" value="Submit">
<{ :form }>Antlers generates additional markup behind the scenes:
- Sets the form's
actionto/submit - Sets the form's
methodtoPOST - Adds an anti-forgery token to prevent CSRF [UNRELEASED]
Change the POST method to GET with:
<{ form: '/search' method: 'GET' }>
<input type="search">
<input type="submit" value="search">
<{ :form }>ℹ️ Antlers provides other input helpers such as <{ label: 'Label' }>, <{ search: :query }> and <{ submit: 'Search' }>. [UNRELEASED]
Add parallelism where it makes sense and you can measure the performance outcome and keep data integrity.
Per sibling:
def render
# Both child nodes executed at the same time.
<{ parallelize: }>
<{ UserNode user=@user }>
<{ PostsNode posts=@posts }>
<{ :parallelize }>
endPer block:
def render
# Each UserNode rendered at the same time.
<{ map: user in: @users :parallelize }>
<{ UserNode user=user }>
<{ :map }>
endPer directive:
<{ UserNode user=user for: user in: @users :parallelize }>Antlers uses two different sets of start and stop characters:
- 🦌 Deerheads:
<{and}> - 🖇 Brackets:
{and}
Note
The {} Brackets syntax escapes HTML and can only render variables.
Use the <{}> Deerheads syntax to render variables without escaping HTML.
Unlike other templating languages which use syntax to distinguish between control flow and output, there is no difference in Antlers. In Antlers all constructs internally render output, even if that output is an empty string ('').
Variables ({}) are also useful for embedding text in RBX without any syntax highlighting issues:
def render
<html>{"I'm just a string"}</html>
endℹ️ Translations: Text entered this way can be translated based on region, language or any arbitrary condition. [UNRELEASED]
class UserNode < LowNode
def initialize
@user = User.new(username: "Random User", bio: "I'm a person!")
end
def render
<html>
<{ LayoutNode: title=@user.username }>
{@user.bio}
<{ :LayoutNode }>
</html>
end
endThe LayoutNode would look like:
class LayoutNode
def render(event:, title:)
<header>...</header>
<h1>{title}</h1>
<{ :slot }>
<footer>...</footer>
end
endThe result would be:
<header>...</header>
<h1>Random User</h1>
<p>I'm a person!</p>
<footer>...</footer>Parse the Antlers template into an Abstract Syntax Tree.
Render the AST and evaluate variables in the supplied binding.
Optional arguments:
parent_binding: nil- For rendering a<{ :slot }>in a child componentnamespace: nil- The original namespace that the template was defined in
Variables can evaluate the following:
- An instance variable:
{ @instance_variable }or<{ @instance_variable }> - A method call/local variable:
{ method_or_variable }or<{ method_or_variable }> - A method chain:
{ method_or_variable.method_two }or<{ method_or_variable.method_two }> - A static string:
{"Static String"}or<{"Static String"}>
Antlers creates an Abstract Syntax Tree composed of the following AntlerNodes:
Leaf nodes:
PropNodeVarNode
Branch nodes:
RootNodeSlotNodeYieldNode- RendersAntlerNodes inside aSlotNode
sequenceDiagram
autonumber
participant LowLoad
participant LowNode
participant Template
LowLoad->>LowNode: Load node
LowNode->>Template: Load template
Template->>Template: Parse Antlers
Template->>LowNode: Store template
Note over LowLoad,Template: Render event
LowNode->>Template: Render node
Template-->>LowNode: Render child nodes
- #️⃣ Syntax. Antlers uses syntax from Ruby to get syntax highlighting out of the box. But it is not Ruby and is designed to limit you to a templating language, with business logic computed in the nodes that render Antlers
- ⏳ Paralellization. Make paralellization easy by abstracting Ractors and creating immutable data structures on the user's behalf