Skip to content

Templates & Projector Logic

The Projector (src/projector.rs) is the engine responsible for bridging the gap between Semantic Vyasa commands and the output (usually HTML).

Instead of hardcoding HTML generation in Rust (e.g. write!(w, "<h1>{}</h1>", title)), the compiler uses Templates defined in Vyasa itself (stdlib.vy or context.vy).

  1. Input: Semantic Node (e.g. `heading { The Title }).
  2. Lookup: The Projector checks env.templates for a matching heading template.
  3. Expansion: If found, it replaces the Semantic Node with the template’s body, interpolating variables.
  4. Recursion: The output is processed again (allowing templates to use other templates).

Templates are defined using the template command (usually sugar syntax in .vy):

`template { target="heading"
`h2 { $.text }
}
  • $.text: Replaced by the semantic command’s children.
  • $.var: Replaced by the value of attribute var from the semantic command.
  • $.context.key: (Advanced) Access global context.

The Projector supports basic logic:

Conditionals based on attribute values.

`if { lhs="$.type" op="eq" rhs="warning"
`div { class="alert warning" ... }
}

Iterating over lists (collections).

`each { "work.chapters"
`li {
`a { href="$.url" $.title }
}
}
  • View Template: Used to render a single source file. Defines the body command behavior.
  • Collection Template: Used to generate an index page (e.g. Table of Contents) by iterating over build stats (work.items).