summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWriterV2 <primary-v2@protonmail.com>2026-04-03 02:13:43 +0200
committerWriterV2 <primary-v2@protonmail.com>2026-04-03 02:13:43 +0200
commitc40fb1213ca852df4ec138a84275e277e7f7614b (patch)
tree94474242184c780a723d5bfb2bd270398f6261e3
parent902a1f2d582e5f20daa0842a2c13b6714e898655 (diff)
Refactor page builder
-rw-r--r--src/main.rs119
-rw-r--r--src/page.rs110
2 files changed, 123 insertions, 106 deletions
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<Story>,
}
-impl Data {
- fn render_stories(self) -> Markup {
+impl page::Page for Vec<Story> {
+ 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)))
+ }
+}