From c40fb1213ca852df4ec138a84275e277e7f7614b Mon Sep 17 00:00:00 2001 From: WriterV2 Date: Fri, 3 Apr 2026 02:13:43 +0200 Subject: Refactor page builder --- src/main.rs | 119 +++++++----------------------------------------------------- src/page.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 106 deletions(-) create mode 100644 src/page.rs diff --git a/src/main.rs b/src/main.rs index 6da30fc..02aac19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,24 @@ use anyhow::{Context, Result}; -use maud::{html, Markup, DOCTYPE}; +use maud::{html, Markup}; use serde::Deserialize; +use self::page::Page; + +mod page; + #[derive(Deserialize)] struct Data { stories: Vec, } -impl Data { - fn render_stories(self) -> Markup { +impl page::Page for Vec { + fn page_title() -> String { + String::from("Storys") + } + + fn render_content(self) -> Markup { html!( - @for story in self.stories { + @for story in self { (story.render_as_card()) } ) @@ -32,112 +40,11 @@ impl Story { } } -fn render_head(page_title: &str) -> Markup { - html!( - head { - (DOCTYPE) - meta charset="utf-8"; - meta name="viewport" content="width=device-width,initial-scale=1"; - title { (page_title) } - } - ) -} - -fn render_navigation() -> Markup { - html!( - div class="navbar" { - header { - h1 { - "V2 Tales"; - } - } - nav { - a href="" { - "HOME"; - } - a href="" { - "STORIES"; - } - } - } - ) -} - -fn style() -> Markup { - html!( - style { - """ -* { - padding: 0; - margin: 0; - } - - h1 { - padding: 0.3rem; - letter-spacing: 0.8rem; - font-size: 1.5rem; - color: #0d234adb; - display: flex; - justify-content: center; - align-items: center; - gap: 2rem; - } - - h2 { - font-size: 2rem; - margin-bottom: 2rem; - color: #0d234adb; - } - - - body { - margin: 2rem 1rem; - background-color: #ffc994; - text-align: center; - } - - hr { - margin: 1rem; - } - - img { - max-width: 3rem; - max-height: 3rem; - } - - .navbar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 3rem; - } - - nav { - display: flex; - justify-content: space-around; - width: 50%; - - a { - text-decoration: none; - color: #0d234adb; - - &:hover { - text-decoration: underline; - } - } - } - """ - } - ) -} - fn main() -> Result<()> { let data_file_content = std::fs::read_to_string("data.toml").with_context(|| "Failed to read data.toml")?; let data: Data = toml::from_str(&data_file_content)?; - let stories_html = html!((render_head("Stories - V2 Tales"))(style())( - render_navigation() - )(data.render_stories())); + let stories_html = data.stories.render_page(); std::fs::write("dist/stories.html", stories_html.into_string()) .with_context(|| "Failed to write dist/stories.html")?; Ok(()) diff --git a/src/page.rs b/src/page.rs new file mode 100644 index 0000000..6d788f3 --- /dev/null +++ b/src/page.rs @@ -0,0 +1,110 @@ +use maud::{html, Markup, DOCTYPE}; + +pub trait Page: Sized { + fn render_content(self) -> Markup; + fn page_title() -> String; + fn render_head() -> Markup { + html!( + head { + (DOCTYPE) + meta charset="utf-8"; + meta name="viewport" content="width=device-width,initial-scale=1"; + title { (Self::page_title()) } + } + ) + } + + fn render_navigation() -> Markup { + html!( + div class="navbar" { + header { + h1 { + "V2 Tales"; + } + } + nav { + a href="" { + "HOME"; + } + a href="" { + "STORIES"; + } + } + } + ) + } + + fn style() -> Markup { + html!( + style { + """ +* { + padding: 0; + margin: 0; + } + + h1 { + padding: 0.3rem; + letter-spacing: 0.8rem; + font-size: 1.5rem; + color: #0d234adb; + display: flex; + justify-content: center; + align-items: center; + gap: 2rem; + } + + h2 { + font-size: 2rem; + margin-bottom: 2rem; + color: #0d234adb; + } + + + body { + margin: 2rem 1rem; + background-color: #ffc994; + text-align: center; + } + + hr { + margin: 1rem; + } + + img { + max-width: 3rem; + max-height: 3rem; + } + + .navbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 3rem; + } + + nav { + display: flex; + justify-content: space-around; + width: 50%; + + a { + text-decoration: none; + color: #0d234adb; + + &:hover { + text-decoration: underline; + } + } + } + """ + } + ) + } + + fn render_page(self) -> Markup { + html!((Self::render_head())(Self::style())( + Self::render_navigation() + )(Self::render_content(self))) + } +} -- cgit v1.2.3