refactor(v0): render shell with hemplate

Move the v0 page shell from a Rust format! raw HTML string into a hemplate AppShell view and cover the rendered document structure with scraper.

req: html_safety/002

req: view/001

req: test/005
This commit is contained in:
slhx agent
2026-05-25 21:54:04 +02:00
parent f8d46e1a40
commit 58e96162d4
2 changed files with 46 additions and 22 deletions
+26 -22
View File
@@ -43,6 +43,11 @@ struct PageSwap {
title: &'static str,
}
#[derive(Hemplate)]
struct AppShell {
body: SafeHtml,
}
#[derive(Hemplate)]
#[hemplate = "partials"]
struct DocsContent {
@@ -180,28 +185,10 @@ fn all_examples() -> String {
}
fn shell(body: String) -> String {
format!(
r#"<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>slhx v0 examples</title>
<script src="/slhx.js" defer></script>
<style>
body {{ font-family: system-ui, sans-serif; margin: 2rem; max-width: 54rem; }}
section, main {{ border: 1px solid #ddd; border-radius: .5rem; margin: 1rem 0; padding: 1rem; }}
input, button {{ font: inherit; margin: .25rem; }}
nav a {{ margin-right: .75rem; }}
</style>
</head>
<body>
<h1>slhx v0 browser examples</h1>
<p>Try the counter, todo form, wizard, login, page swap, and live SSE notifications.</p>
{body}
</body>
</html>"#
)
// req: html_safety/002 req: view/001
render_template(&AppShell {
body: SafeHtml::trusted(body),
})
}
fn render_todos(todos: &[Todo]) -> SafeHtml {
@@ -247,6 +234,23 @@ mod tests {
Selector::parse(value).expect("test selector parses")
}
// req: html_safety/002 req: view/001 req: test/005
#[test]
fn shell_is_rendered_by_a_hemplate_view() {
let html = shell(render_page_swap("Welcome", "Welcome"));
let document = Html::parse_document(&html);
assert_eq!(
document
.select(&selector("title"))
.next()
.map(|title| title.text().collect::<String>()),
Some("slhx v0 examples".to_owned())
);
assert_eq!(document.select(&selector("script[src=\"/slhx.js\"]")).count(), 1);
assert_eq!(document.select(&selector("main[data-slhx-root=\"docs\"]")).count(), 1);
assert!(!html.contains("{+="));
}
// req: html_safety/002 req: view/001 req: test/005
#[test]
fn docs_content_payload_is_rendered_by_a_hemplate_view() {