Skip to content

tetsuo/restache

Folders and files

NameName
Last commit message
Last commit date

Latest commit

632c3e7 · Apr 27, 2025
Nov 30, 2022
Apr 13, 2025
Apr 21, 2025
Apr 4, 2025
Apr 7, 2025
Jan 1, 2023
Apr 12, 2025
Mar 30, 2025
Apr 12, 2025
Apr 12, 2025
Apr 12, 2025
Apr 19, 2025
Apr 27, 2025
Apr 17, 2025
Apr 18, 2025
Apr 27, 2025
Apr 13, 2025
Apr 13, 2025
Apr 27, 2025
Apr 27, 2025
Apr 13, 2025

Repository files navigation

restache

Restache is a Mustache-inspired templating language designed for integration with React.

⚠️ Work In Progress ⚠️

Example template

<div>
  {#cart.items}
    <span>{name}</span>
  {/cart.items}
  {?cart.empty}
    <p>Your cart is empty</p>
  {/cart.empty}
  {! This is a comment and will not be rendered }
</div>

Grammar

A simplified, informal grammar for Restache is as follows:

Template     ::= (Element | ControlBlock | Variable | Comment | Text)*

Element      ::= StartTag Template EndTag | SelfClosingTag

ControlBlock ::= RangeBlock | WhenBlock | UnlessBlock

RangeBlock   ::= "{#" Expression "}" Template EndControl
WhenBlock    ::= "{?" Expression "}" Template EndControl
UnlessBlock  ::= "{^" Expression "}" Template EndControl

EndControl   ::= "{/" Expression "}"

Variable     ::= "{" Expression "}"
Comment      ::= "{!" CommentText "}"

Text         ::= Any sequence of characters that does not form part of a recognized Stache token.

Expression   ::= Identifier ('.' Identifier)*

Semantic rules

Parse tree and node types

During parsing, the template is converted into a tree of nodes. The primary node types include:

  • ComponentNode: The root node of the entire document.
  • ElementNode: Represents HTML-like elements.
  • TextNode: Contains textual content.
  • VariableNode: Represents a dynamic value inserted into the template.
  • CommentNode: Contains comments that are not rendered.
  • RangeNode, WhenNode, UnlessNode: Represent control structures that conditionally render or iterate over content.

Scope and context

  • Range: When a {# expression } token is encountered, the parser splits the expression by . and appends the parts to the current scope (stored in the node's Path field). All child nodes within this block use the extended scope for variable resolution.

  • When and Unless: These constructs do not modify the scope. They evaluate their expressions against the current context, rendering their children only when the condition holds true.

Attribute parsing

  • Expression attributes: If an attribute's value is entirely wrapped in { ... }, it is treated as an expression and evaluated at runtime.

  • Static attributes: Attribute values that contain additional text (outside of a full expression) are treated as literal strings.