html-templater/README.md
2024-07-31 18:29:17 -05:00

54 lines
1.8 KiB
Markdown

# 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.
```rust
// 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.
```html
<!-- 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](https://crates.io/crates/inkjet) and
[v_htmlescape](https://crates.io/crates/v_htmlescape) crates.