refactor(v0): render page swap with hemplate
Move the v0 docs/page-swap partial and EffectBatch content payload from raw HTML strings into hemplate views, with scraper assertions for rendered structure. req: html_safety/002 req: view/001 req: test/005
This commit is contained in:
+71
-14
@@ -37,6 +37,18 @@ struct TodoItem {
|
||||
title: String,
|
||||
}
|
||||
|
||||
#[derive(Hemplate)]
|
||||
struct PageSwap {
|
||||
content: SafeHtml,
|
||||
title: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Hemplate)]
|
||||
#[hemplate = "partials"]
|
||||
struct DocsContent {
|
||||
message: &'static str,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let state = Arc::new(ExampleState::default());
|
||||
@@ -63,16 +75,7 @@ async fn home(request: PageRequest) -> impl IntoResponse {
|
||||
|
||||
// req: page_swap/002, req: examples/001
|
||||
async fn docs(request: PageRequest) -> impl IntoResponse {
|
||||
let partial = ui::page_swap::lower_html(
|
||||
r#"<main data-slhx-root="docs">
|
||||
<nav data-slhx-slot="nav">
|
||||
<a href="/" data-slhx-nav="">Examples</a>
|
||||
<a href="/docs" data-slhx-nav="">Docs</a>
|
||||
</nav>
|
||||
<article data-slhx-slot="content"><h1>Docs</h1><p>This page was swapped without a full reload.</p></article>
|
||||
<title data-slhx-slot="title">Docs</title>
|
||||
</main>"#,
|
||||
);
|
||||
let partial = render_page_swap("Docs", "This page was swapped without a full reload.");
|
||||
request
|
||||
.page(partial, shell)
|
||||
.title("Docs")
|
||||
@@ -155,8 +158,8 @@ fn registry(state: Arc<ExampleState>) -> HandlerRegistry {
|
||||
.register(ui::page_swap::handles::load_docs.id().id, |_| {
|
||||
// req: page_swap/002, req: examples/001
|
||||
(
|
||||
ui::page_swap::slots::content.html(SafeHtml::trusted(
|
||||
"<h1>Docs</h1><p>This content came from an EffectBatch.</p>",
|
||||
ui::page_swap::slots::content.html(render_docs_content(
|
||||
"This content came from an EffectBatch.",
|
||||
)),
|
||||
ui::page_swap::slots::title.text("Docs"),
|
||||
push("/docs"),
|
||||
@@ -170,7 +173,7 @@ fn all_examples() -> String {
|
||||
ui::todos::lower_html(include_str!("../templates/todos.heml")),
|
||||
ui::wizard::lower_html(include_str!("../templates/wizard.heml")),
|
||||
ui::auth::lower_html(include_str!("../templates/auth.heml")),
|
||||
ui::page_swap::lower_html(include_str!("../templates/page_swap.heml")),
|
||||
render_page_swap("Welcome", "Welcome"),
|
||||
ui::notifications::lower_html(include_str!("../templates/notifications.heml")),
|
||||
]
|
||||
.join("\n")
|
||||
@@ -214,8 +217,25 @@ fn render_todos(todos: &[Todo]) -> SafeHtml {
|
||||
})
|
||||
}
|
||||
|
||||
fn render_page_swap(title: &'static str, message: &'static str) -> String {
|
||||
// req: html_safety/002 req: view/001
|
||||
ui::page_swap::lower_html(render_template(&PageSwap {
|
||||
content: render_docs_content(message),
|
||||
title,
|
||||
}))
|
||||
}
|
||||
|
||||
fn render_docs_content(message: &'static str) -> SafeHtml {
|
||||
// req: html_safety/002 req: view/001
|
||||
render_html(&DocsContent { message })
|
||||
}
|
||||
|
||||
fn render_html(template: &impl Hemplate) -> SafeHtml {
|
||||
SafeHtml::trusted(template.render().expect("v0 hemplate partial renders"))
|
||||
SafeHtml::trusted(render_template(template))
|
||||
}
|
||||
|
||||
fn render_template(template: &impl Hemplate) -> String {
|
||||
template.render().expect("v0 hemplate view renders")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -227,6 +247,43 @@ mod tests {
|
||||
Selector::parse(value).expect("test selector parses")
|
||||
}
|
||||
|
||||
// req: html_safety/002 req: view/001 req: test/005
|
||||
#[test]
|
||||
fn docs_content_payload_is_rendered_by_a_hemplate_view() {
|
||||
let html = render_docs_content("This content came from an EffectBatch.");
|
||||
let document = Html::parse_fragment(html.as_str());
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("h1"))
|
||||
.next()
|
||||
.map(|heading| heading.text().collect::<String>()),
|
||||
Some("Docs".to_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("p"))
|
||||
.next()
|
||||
.map(|paragraph| paragraph.text().collect::<String>()),
|
||||
Some("This content came from an EffectBatch.".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
// req: html_safety/002 req: view/001 req: test/005
|
||||
#[test]
|
||||
fn docs_page_partial_is_rendered_by_a_hemplate_view() {
|
||||
let html = render_page_swap("Docs", "This page was swapped without a full reload.");
|
||||
let document = Html::parse_fragment(&html);
|
||||
assert_eq!(document.select(&selector("main[data-slhx-root=\"docs\"]")).count(), 1);
|
||||
assert_eq!(document.select(&selector("article[data-sid]")).count(), 1);
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("article h1"))
|
||||
.next()
|
||||
.map(|heading| heading.text().collect::<String>()),
|
||||
Some("Docs".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
// req: html_safety/002 req: view/001 req: test/005
|
||||
#[test]
|
||||
fn todos_payload_is_rendered_by_a_hemplate_view() {
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
<nav data-slhx-slot="nav">
|
||||
<a href="/docs" data-slhx-nav="" data-slhx-handle="load_docs">Docs</a>
|
||||
</nav>
|
||||
<article data-slhx-slot="content">Welcome</article>
|
||||
<title data-slhx-slot="title">Welcome</title>
|
||||
<article data-slhx-slot="content">{+= self.content =+}</article>
|
||||
<title data-slhx-slot="title">{+ self.title +}</title>
|
||||
</main>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<h1>Docs</h1><p>{+ self.message +}</p>
|
||||
Reference in New Issue
Block a user