9 releases
0.1.10 | Feb 12, 2023 |
---|---|
0.1.9 | Feb 12, 2023 |
0.1.6 | Oct 9, 2022 |
0.1.4 | Sep 12, 2022 |
#124 in Template engine
70KB
1.5K
SLoC
sato
an s-expression based html templating system.
sato template language examples
basic template example
(html
(head
(title "basic example")))
tag attributes
(html
(head (@ (some thing))
(title "basic example")))
variables
variables in sato are prefixed with a $
.
(html
(head
(title $some_variable)))
conditionals
(html
(head
(title (if (is-set $some_variable)
(div "$some_variable")
(div "variable is not set")))))
iteration over arrays
(html
(body
(for i in $some_array
(div "element: " $i))))
iteration over maps
(html
(body
(for k v in $some_map
(div $k ": " $v))))
switch/case
(html
(body
(switch $blah
(case asdf
qwer)
(case zxcv
(div what else))
(case hjkl
nm))))
basic library example
use sato::renderer::Renderer;
use sato::context::RenderContext;
use sato::template::Template;
let renderer = Renderer::builder()
.build();
let expr = r#"(html (head (title "basic example")))"#;
let template = Template::from_str(expr).unwrap();
let html = renderer.render(&template, &RenderContext::default()).unwrap();
assert_eq!(html, "<!doctype html5><html><head><title>basic example</title></head></html>")
using variables
use sato::renderer::Renderer;
use sato::context::RenderContext;
use sato::template::Template;
let renderer = Renderer::builder()
.build();
let expr = r#"(html (body (if (eq $asdf qwer) (for i in $array (div $i)))))"#;
let template = Template::from_str(expr).unwrap();
let context = RenderContext::builder()
.insert("asdf", "qwer")
.insert("array", vec!["zxc", "xcv", "cvb"])
.build();
let html = renderer.render(&template, &context).unwrap();
assert_eq!(html, "<!doctype html5><html><body><div>zxc</div><div>xcv</div><div>cvb</div></body></html>")
custom handler functions
use sato::renderer::{Attributes, Renderer, RenderError};
use sato::context::RenderContext;
use sato::template::{Template, TemplateExprNode};
let post_expr = r##"(div (h2 $title) (span "posted by $author") $content (br) (div (for tag in $tags (span "#$tag"))))"##;
let blogpost_template = Template::from_str(post_expr).unwrap();
let renderer = Renderer::builder()
.function("blogpost", Box::new(move |attrs, expr, renderer, context| {
let title = attrs.get("title").unwrap();
let author = attrs.get("author").unwrap();
let mut new_context = context.clone();
new_context.insert("title", title);
new_context.insert("author", author);
new_context.insert("content", renderer.evaluate_multiple(expr, &new_context)?);
Ok(vec![renderer.render(&blogpost_template, &new_context).unwrap()])
}))
.build();
let expr = r#"(html (body (blogpost (@ (title faketitle) (author me)) (div "my content here"))))"#;
let template = Template::from_str(expr).unwrap();
let context = RenderContext::builder()
.insert("tags", vec!["zxc", "xcv", "cvb"])
.build();
let html = renderer.render(&template, &context).unwrap();
assert_eq!(html, "<!doctype html5><html><body><div><h2>faketitle</h2><span>posted by me</span><div>my content here</div><br /><div><span>#zxc</span><span>#xcv</span><span>#cvb</span></div></div></body></html>")
Dependencies
~280–750KB
~18K SLoC