Go to file
2024-07-31 18:29:17 -05:00
hyper-build Rewrote and optimized 2024-04-28 17:06:53 -05:00
hyper-src Rewrote and optimized 2024-04-28 17:06:53 -05:00
src Rewrote and optimized 2024-04-28 17:06:53 -05:00
templates Rewrote and optimized 2024-04-28 17:06:53 -05:00
test_files init 2024-03-10 08:51:30 -05:00
.gitignore init 2024-03-10 08:51:30 -05:00
blueprint.html Rewrote and optimized 2024-04-28 17:06:53 -05:00
Cargo.lock Rewrote and optimized 2024-04-28 17:06:53 -05:00
Cargo.toml Rewrote and optimized 2024-04-28 17:06:53 -05:00
README.md Added README.md 2024-07-31 18:29:17 -05:00

HTML templating language

A common task with HTML is creating 'templates', or reusable components that are stitched together to form a complete document. Front end frameworks typically achieve this through scripting on the client. I prefer instead to generate static HTML files on the server. To this end, I wrote my own templating engine. It parses HTML source and template files, and produces output files which are minified and with CSS and JavaScript inlined. Additional post processing can be performed, like syntax highlighting for code blocks.

Existing Rust for parsing HTML use recursive descent, outputting a tree data structure. I prefer flat data structures and linear algorithms, and so I wrote my own parser.

// My lexeme type (fields omitted)
pub enum HtmlElement {
  DocType,
  Comment   (...),
  OpenTag   {...},
  CloseTag  {...},
  Text      (...),
  Script    {...},
  Style     {...},
  Directive {...},
}

Lexemes are stored in a flat array. Tags are consumed by taking a slice of the array from the opening tag until the closing tag. Expanding a template is done by simply copying its contents into the array. Directives, prefixed with an @ can pass properties and child nodes to a template.

<!-- This is a template definition -->
<Demo>
  <h1 id=@prop_name>
    <@children>
  </h1>
</Demo>

<!-- This is a template instantiation -->
<Demo prop_name="something">
  <i> Hello World! </i>
</Demo>

<!-- This is how the template gets expanded -->
<h1 id="something"/>
  <i> Hello World! </i>
</h1>

The templating engine is free-standing by default, but optionally integrates with Tree Sitter to highlight and format code blocks. To do this I use the inkjet and v_htmlescape crates.