diff --git a/src/html/elements.rs b/src/html/elements.rs
index 570b61c..edb6166 100644
--- a/src/html/elements.rs
+++ b/src/html/elements.rs
@@ -1,115 +1,160 @@
use crate::html::Render;
-#[allow(non_camel_case_types)]
-pub(crate) struct h1 {
+pub(crate) struct Heading {
+ level: u8,
+ id: String,
text: String,
+ classes: Vec,
}
-impl Render for h1 {
+impl Render for Heading {
fn render(&self) -> String {
- format!("{}
", self.text)
+ let classes = self.classes.join(" ");
+ format!(
+ "{}",
+ self.level, self.id, classes, self.text, self.level
+ )
}
}
-impl h1 {
- pub(crate) fn new(text: T) -> Self
+impl Heading {
+ pub(crate) fn builder() -> HeadingBuilder {
+ HeadingBuilder::new()
+ }
+}
+
+pub(crate) struct HeadingBuilder {
+ level: Option,
+ id: Option,
+ text: Option,
+ classes: Option>,
+}
+
+impl HeadingBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ level: None,
+ id: None,
+ text: None,
+ classes: None,
+ }
+ }
+
+ pub(crate) fn level(self, level: u8) -> Self {
+ Self {
+ level: Some(level),
+ ..self
+ }
+ }
+
+ pub(crate) fn id(self, id: T) -> Self
where
T: Into,
{
- Self { text: text.into() }
+ Self {
+ id: Some(id.into()),
+ ..self
+ }
}
-}
-#[allow(non_camel_case_types)]
-pub(crate) struct h2 {
- text: String,
-}
-
-impl Render for h2 {
- fn render(&self) -> String {
- format!("{}
", self.text)
- }
-}
-
-impl h2 {
- pub(crate) fn new(text: T) -> Self
+ pub(crate) fn text(self, text: T) -> Self
where
T: Into,
{
- Self { text: text.into() }
+ Self {
+ text: Some(text.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn classes(self, classes: Vec) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ classes: Some(classes.into_iter().map(|x| x.into()).collect()),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Heading {
+ let level = self.level.unwrap_or(1);
+ let id = self.id.unwrap_or(String::new());
+ let text = self.text.unwrap_or(String::new());
+ let classes = self.classes.unwrap_or(Vec::new());
+ Heading {
+ level,
+ id,
+ text,
+ classes,
+ }
}
}
-#[allow(non_camel_case_types)]
-pub(crate) struct link {
+pub(crate) struct Link {
rel: String,
href: String,
}
-impl Render for link {
+impl Render for Link {
fn render(&self) -> String {
format!("", self.rel, self.href)
}
}
-impl link {
- pub(crate) fn new(rel: T, href: U) -> Self
- where
- T: Into,
- U: Into,
- {
- Self {
- rel: rel.into(),
- href: href.into(),
- }
+impl Link {
+ pub(crate) fn builder() -> LinkBuilder {
+ LinkBuilder::new()
}
}
-#[allow(non_camel_case_types)]
-pub(crate) struct div {
- id: String,
- classes: Vec,
- content: Vec>,
+pub(crate) struct LinkBuilder {
+ rel: Option,
+ href: Option,
}
-impl Render for div {
- fn render(&self) -> String {
- let classes = self.classes.join(" ");
- format!(
- "{}
",
- self.id,
- classes,
- self.content.render()
- )
- }
-}
-
-impl div {
- pub(crate) fn new(id: T, classes: Vec) -> Self
- where
- T: Into,
- U: Into + Clone,
- {
+impl LinkBuilder {
+ pub(crate) fn new() -> Self {
Self {
- id: id.into(),
- classes: classes.iter().map(|x| x.clone().into()).collect(),
- content: vec![],
+ rel: None,
+ href: None,
}
}
- pub(crate) fn append_element(&mut self, element: impl Render + 'static) {
- self.content.push(Box::new(element));
+ pub(crate) fn rel(self, rel: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ rel: Some(rel.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn href(self, href: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ href: Some(href.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Link {
+ let rel = self.rel.unwrap_or(String::new());
+ let href = self.href.unwrap_or(String::new());
+ Link { rel, href }
}
}
-#[allow(non_camel_case_types)]
-pub(crate) struct p {
+pub(crate) struct Paragraph {
id: String,
classes: Vec,
text: String,
}
-impl Render for p {
+impl Render for Paragraph {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!(
@@ -119,29 +164,72 @@ impl Render for p {
}
}
-impl p {
- pub(crate) fn new(id: T, classes: Vec, text: V) -> Self
- where
- T: Into,
- U: Into + Clone,
- V: Into,
- {
- Self {
- id: id.into(),
- classes: classes.iter().map(|x| x.clone().into()).collect(),
- text: text.into(),
- }
+impl Paragraph {
+ pub(crate) fn builder() -> ParagraphBuilder {
+ ParagraphBuilder::new()
}
}
-#[allow(non_camel_case_types)]
-pub(crate) struct img {
+pub(crate) struct ParagraphBuilder {
+ id: Option,
+ classes: Option>,
+ text: Option,
+}
+
+impl ParagraphBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ id: None,
+ classes: None,
+ text: None,
+ }
+ }
+
+ pub(crate) fn id(self, id: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ id: Some(id.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn classes(self, classes: Vec) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ classes: Some(classes.into_iter().map(|x| x.into()).collect()),
+ ..self
+ }
+ }
+
+ pub(crate) fn text(self, text: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ text: Some(text.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Paragraph {
+ let id = self.id.unwrap_or(String::new());
+ let classes = self.classes.unwrap_or(Vec::new());
+ let text = self.text.unwrap_or(String::new());
+ Paragraph { id, classes, text }
+ }
+}
+
+pub(crate) struct Image {
id: String,
classes: Vec,
src: String,
}
-impl Render for img {
+impl Render for Image {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!(
@@ -151,30 +239,73 @@ impl Render for img {
}
}
-impl img {
- pub(crate) fn new(id: T, classes: Vec, src: V) -> Self
- where
- T: Into,
- U: Into + Clone,
- V: Into,
- {
- Self {
- id: id.into(),
- classes: classes.iter().map(|x| x.clone().into()).collect(),
- src: src.into(),
- }
+impl Image {
+ pub(crate) fn builder() -> ImageBuilder {
+ ImageBuilder::new()
}
}
-#[allow(non_camel_case_types)]
-pub(crate) struct a {
+pub(crate) struct ImageBuilder {
+ id: Option,
+ classes: Option>,
+ src: Option,
+}
+
+impl ImageBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ id: None,
+ classes: None,
+ src: None,
+ }
+ }
+
+ pub(crate) fn id(self, id: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ id: Some(id.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn classes(self, classes: Vec) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ classes: Some(classes.into_iter().map(|x| x.into()).collect()),
+ ..self
+ }
+ }
+
+ pub(crate) fn src(self, src: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ src: Some(src.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Image {
+ let id = self.id.unwrap_or(String::new());
+ let classes = self.classes.unwrap_or(Vec::new());
+ let src = self.src.unwrap_or(String::new());
+ Image { id, classes, src }
+ }
+}
+
+pub(crate) struct Anchor {
id: String,
classes: Vec,
href: String,
text: String,
}
-impl Render for a {
+impl Render for Anchor {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!(
@@ -184,19 +315,78 @@ impl Render for a {
}
}
-impl a {
- pub(crate) fn new(id: T, classes: Vec, href: V, text: W) -> Self
+impl Anchor {
+ pub(crate) fn builder() -> AnchorBuilder {
+ AnchorBuilder::new()
+ }
+}
+
+pub(crate) struct AnchorBuilder {
+ id: Option,
+ classes: Option>,
+ href: Option,
+ text: Option,
+}
+
+impl AnchorBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ id: None,
+ classes: None,
+ href: None,
+ text: None,
+ }
+ }
+
+ pub(crate) fn id(self, id: T) -> Self
where
T: Into,
- U: Into + Clone,
- V: Into,
- W: Into,
{
Self {
- id: id.into(),
- classes: classes.iter().map(|x| x.clone().into()).collect(),
- href: href.into(),
- text: text.into(),
+ id: Some(id.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn classes(self, classes: Vec) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ classes: Some(classes.into_iter().map(|x| x.into()).collect()),
+ ..self
+ }
+ }
+
+ pub(crate) fn href(self, href: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ href: Some(href.into()),
+ ..self
+ }
+ }
+ pub(crate) fn text(self, text: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ text: Some(text.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Anchor {
+ let id = self.id.unwrap_or(String::new());
+ let classes = self.classes.unwrap_or(Vec::new());
+ let href = self.href.unwrap_or(String::new());
+ let text = self.text.unwrap_or(String::new());
+ Anchor {
+ id,
+ classes,
+ href,
+ text,
}
}
}
diff --git a/src/html/layouts.rs b/src/html/layouts.rs
new file mode 100644
index 0000000..2d8bc92
--- /dev/null
+++ b/src/html/layouts.rs
@@ -0,0 +1,83 @@
+use crate::html::Render;
+
+pub(crate) struct Division {
+ id: String,
+ classes: Vec,
+ elements: Vec>,
+}
+
+impl Render for Division {
+ fn render(&self) -> String {
+ let classes = self.classes.join(" ");
+ format!(
+ "{}
",
+ self.id,
+ classes,
+ self.elements.render()
+ )
+ }
+}
+
+impl Division {
+ pub(crate) fn builder() -> DivisionBuilder {
+ DivisionBuilder::new()
+ }
+
+ pub(crate) fn append_element(&mut self, element: impl Render + 'static) {
+ self.elements.push(Box::new(element));
+ }
+}
+
+pub(crate) struct DivisionBuilder {
+ id: Option,
+ classes: Option>,
+ elements: Option>>,
+}
+
+impl DivisionBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ id: None,
+ classes: None,
+ elements: None,
+ }
+ }
+
+ pub(crate) fn id(self, id: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ id: Some(id.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn classes(self, classes: Vec) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ classes: Some(classes.into_iter().map(|x| x.into()).collect()),
+ ..self
+ }
+ }
+
+ pub(crate) fn elements(self, elements: Vec>) -> Self {
+ Self {
+ elements: Some(elements),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Division {
+ let id = self.id.unwrap_or(String::new());
+ let classes = self.classes.unwrap_or(Vec::new());
+ let elements = self.elements.unwrap_or(Vec::new());
+ Division {
+ id,
+ classes,
+ elements,
+ }
+ }
+}
diff --git a/src/html/mod.rs b/src/html/mod.rs
index d0ba92f..3499232 100644
--- a/src/html/mod.rs
+++ b/src/html/mod.rs
@@ -1,92 +1,31 @@
pub(crate) mod elements;
+pub(crate) mod layouts;
+pub(crate) mod pages;
+
+macro_rules! boxed_vec {
+ ($($element:ident),+) => {
+ vec![
+ $(
+ Box::new($element) as Box,
+ )*
+ ]
+ };
+}
+
+pub(crate) use boxed_vec;
pub(crate) trait Render {
fn render(&self) -> String;
}
-pub(crate) struct Page {
- title: String,
- head: Vec>,
- body: Vec>,
-}
-
-pub(crate) struct PageBuilder {
- title: Option,
- head: Option>>
- body: Option>>
-}
-
-impl PageBuilder {
- pub(crate) fn new() -> Self {
- Self {
- title: None,
- head: None,
- body: None,
- }
- }
-
- pub(crate) fn title(mut self, title: T)
- where T: Into
- {
- self.title = Some(title.into());
- }
-}
-
impl Render for Vec> {
fn render(&self) -> String {
let mut result = String::new();
for element in self {
let render = element.render();
result.push_str(&render);
+ result.push('\n');
}
result
}
}
-
-impl Render for Page {
- fn render(&self) -> String {
- format!(
- "\
-
-
-
-
- {}
-
-{}
-
-
-{}
-
-",
- self.title,
- self.head.render(),
- self.body.render()
- )
- }
-}
-
-impl Page {
- pub(crate) fn builder() -> PageBuilder {
- PageBuilder::new()
- }
-
- pub(crate) fn new(title: T) -> Self
- where
- T: Into,
- {
- Page {
- title: title.into(),
- head: vec![],
- body: vec![],
- }
- }
-
- pub(crate) fn append_element_to_body(&mut self, element: impl Render + 'static) {
- self.body.push(Box::new(element));
- }
-
- pub(crate) fn append_element_to_head(&mut self, element: impl Render + 'static) {
- self.head.push(Box::new(element));
- }
-}
diff --git a/src/html/pages.rs b/src/html/pages.rs
new file mode 100644
index 0000000..a380e81
--- /dev/null
+++ b/src/html/pages.rs
@@ -0,0 +1,199 @@
+use crate::html::Render;
+use crate::html::boxed_vec;
+use crate::html::elements::{Anchor, Image, Link, Paragraph};
+use crate::html::layouts::Division;
+
+pub(crate) struct Page {
+ title: String,
+ head: Vec>,
+ body: Vec>,
+}
+
+impl Render for Page {
+ fn render(&self) -> String {
+ format!(
+ "\
+
+
+
+
+ {}
+
+{}
+
+
+{}
+
+",
+ self.title,
+ self.head.render(),
+ self.body.render()
+ )
+ }
+}
+
+impl Page {
+ pub(crate) fn builder() -> PageBuilder {
+ PageBuilder::new()
+ }
+
+ pub(crate) fn append_element_to_body(&mut self, element: impl Render + 'static) {
+ self.body.push(Box::new(element));
+ }
+
+ pub(crate) fn append_element_to_head(&mut self, element: impl Render + 'static) {
+ self.head.push(Box::new(element));
+ }
+}
+
+pub(crate) struct PageBuilder {
+ title: Option,
+ head: Option>>,
+ body: Option>>,
+}
+
+impl PageBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ title: None,
+ head: None,
+ body: None,
+ }
+ }
+
+ pub(crate) fn title(self, title: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ title: Some(title.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn head(self, head: Vec>) -> Self {
+ Self {
+ head: Some(head),
+ ..self
+ }
+ }
+
+ pub(crate) fn body(self, body: Vec>) -> Self {
+ Self {
+ body: Some(body),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> Page {
+ let title = self.title.unwrap_or(String::new());
+ let head = self.head.unwrap_or(Vec::new());
+ let body = self.body.unwrap_or(Vec::new());
+ Page { title, head, body }
+ }
+}
+
+pub(crate) struct BasePage {
+ page: Page,
+}
+
+impl BasePage {
+ pub(crate) fn builder() -> BasePageBuilder {
+ BasePageBuilder::new()
+ }
+
+ pub(crate) fn append_element_to_head(&mut self, element: impl Render + 'static) {
+ self.page.append_element_to_head(element);
+ }
+ pub(crate) fn append_element_to_body(&mut self, element: impl Render + 'static) {
+ self.page.append_element_to_body(element);
+ }
+}
+
+impl Render for BasePage {
+ fn render(&self) -> String {
+ self.page.render()
+ }
+}
+
+pub(crate) struct BasePageBuilder {
+ title: Option,
+ head: Option>>,
+ body: Option>>,
+}
+
+impl BasePageBuilder {
+ pub(crate) fn new() -> Self {
+ Self {
+ title: None,
+ head: None,
+ body: None,
+ }
+ }
+
+ pub(crate) fn title(self, title: T) -> Self
+ where
+ T: Into,
+ {
+ Self {
+ title: Some(title.into()),
+ ..self
+ }
+ }
+
+ pub(crate) fn head(self, head: Vec>) -> Self {
+ Self {
+ head: Some(head),
+ ..self
+ }
+ }
+ pub(crate) fn body(self, body: Vec>) -> Self {
+ Self {
+ body: Some(body),
+ ..self
+ }
+ }
+
+ pub(crate) fn build(self) -> BasePage {
+ let title = self.title.unwrap_or(String::new());
+ let head = self.head.unwrap_or(Vec::new());
+ let body = self.body.unwrap_or(Vec::new());
+ let name = Paragraph::builder()
+ .id("name")
+ .classes(vec!["name"])
+ .text("AINDUSTRIES")
+ .build();
+ let home = Anchor::builder().id("home").classes(vec!["nav-button"]).href("/").text("Home").build();
+ let projects = Anchor::builder().id("projects").classes(vec!["nav-button"]).href("/projects").text("Projects").build();
+ let buttons = Division::builder()
+ .classes(vec!["nav-buttons"])
+ .elements(boxed_vec![home, projects])
+ .build();
+ let header = Division::builder()
+ .id("header")
+ .classes(vec!["header"])
+ .elements(boxed_vec![name, buttons])
+ .build();
+ // background
+ let image = Image::builder()
+ .id("background")
+ .classes(vec!["background"])
+ .src("/static/img/background.png")
+ .build();
+ // css
+ let base = Link::builder()
+ .rel("stylesheet")
+ .href("/static/css/base.css")
+ .build();
+ let mut final_head = boxed_vec![base];
+ final_head.extend(head);
+ let mut final_body = boxed_vec![image, header];
+ final_body.extend(body);
+ let page = Page::builder()
+ .title(title)
+ .head(final_head)
+ .body(final_body)
+ .build();
+ BasePage { page }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 5f64ca6..783b333 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,7 +20,12 @@ use pages::{
#[derive(Parser)]
#[command(name = "aindustries-be", version, about = "This is the amazing webserver for aindustries.be!", long_about = None)]
struct Cli {
- #[arg(short, long, value_name = "CONFIG", help = "Path to config file, defaults to /etc/aindustries-be/config.toml")]
+ #[arg(
+ short,
+ long,
+ value_name = "CONFIG",
+ help = "Path to config file, defaults to /etc/aindustries-be/config.toml"
+ )]
config: Option,
}
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index a6ee46c..3a10661 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -1,76 +1,39 @@
pub(crate) mod files;
pub(crate) mod projects;
-use crate::html::elements::{a, div, h1, h2, img, link, p};
-use crate::html::{Page, Render};
+use crate::html::elements::{Heading, Link};
+use crate::html::layouts::Division;
+use crate::html::pages::BasePage;
+use crate::html::{Render, boxed_vec};
use actix_web::{Responder, get};
-pub(crate) struct BasePage {
- page: Page,
-}
-
-impl BasePage {
- pub(crate) fn new(title: T) -> Self
- where
- T: Into,
- {
- let mut page = Page::new(title);
- // header
- let mut header = div::new("header", vec!["header"]);
- let name = p::new("name", vec!["name"], "AINDUSTRIES");
- let mut buttons = div::new("buttons", vec!["nav-buttons"]);
- let home = a::new("home", vec!["nav-button"], "/", "Home");
- let projects = a::new("projects", vec!["nav-button"], "/projects", "Projects");
- buttons.append_element(home);
- buttons.append_element(projects);
- header.append_element(name);
- header.append_element(buttons);
- // background
- let image = img::new(
- "background",
- vec!["background"],
- "/static/img/background.png",
- );
- // css
- let base = link::new("stylesheet", "/static/css/base.css");
- // add elements to the page in order
- page.append_element_to_head(base);
- page.append_element_to_body(image);
- page.append_element_to_body(header);
- Self { page }
- }
-
- pub(crate) fn append_element_to_head(&mut self, element: impl Render + 'static) {
- self.page.append_element_to_head(element);
- }
- pub(crate) fn append_element_to_body(&mut self, element: impl Render + 'static) {
- self.page.append_element_to_body(element);
- }
-}
-
-impl Render for BasePage {
- fn render(&self) -> String {
- self.page.render()
- }
-}
-
#[get("/")]
async fn index() -> impl Responder {
- let mut page = BasePage::new("AINDUSTRIES");
// introduction
- let mut intro = div::new("intro", vec!["intro"]);
- let hi = h1::new("Hello and welcome!");
- let detail = h2::new(
- "This here is a small website to show the passion I have for computers.
\
+ let hi = Heading::builder().text("Hello and welcome!").build();
+ let detail = Heading::builder()
+ .level(2)
+ .text(
+ "This here is a small website to show the passion I have for computers.
\
I have always had a good time creating and discovering new things.
\
- Your may discover some of my projects here on this showcase.",
- );
- intro.append_element(hi);
- intro.append_element(detail);
+ Your may discover some of my projects here on this little showcase.",
+ )
+ .build();
+ let intro = Division::builder()
+ .id("intro")
+ .classes(vec!["intro"])
+ .elements(boxed_vec![hi, detail])
+ .build();
// css
- let index = link::new("stylesheet", "static/css/index.css");
+ let index = Link::builder()
+ .rel("stylesheet")
+ .href("static/css/index.css")
+ .build();
// add elements to the page in order
- page.append_element_to_head(index);
- page.append_element_to_body(intro);
+ let page = BasePage::builder()
+ .title("AINDUSTRIES")
+ .head(boxed_vec![index])
+ .body(boxed_vec![intro])
+ .build();
page.render()
}
diff --git a/src/pages/projects.rs b/src/pages/projects.rs
index 8b423ef..d2a4e0b 100644
--- a/src/pages/projects.rs
+++ b/src/pages/projects.rs
@@ -1,64 +1,70 @@
-use super::BasePage;
-use crate::html::Render;
-use crate::html::elements::{a, div, h1, h2, link, p};
+use crate::html::elements::{Anchor, Heading, Link, Paragraph};
+use crate::html::layouts::Division;
+use crate::html::pages::BasePage;
+use crate::html::{Render, boxed_vec};
use actix_web::{Responder, get, web};
#[get("/projects")]
async fn projects() -> impl Responder {
- let mut page = BasePage::new("Projects");
- let title = h1::new("My projects");
- let desc = h2::new(
- "Here you will find all my projects which deserve to be shown
\
+ let title = Heading::builder().text("My projects").build();
+ let desc = Heading::builder()
+ .level(2)
+ .text(
+ "Here you will find all my projects which deserve to be shown
\
(I've done a lot of small projects but they are not worth it.)",
- );
- let mut website = div::new("project-website", vec!["project"]);
- let website_title = h1::new("Website");
- let mut info = div::new("project-website-info", vec!["project-info"]);
- let website_desc = p::new(
- "website-desc",
- vec!["project-desc"],
- "This project is the website you currently are on.",
- );
- let view = a::new(
- "website-view",
- vec!["project-view"],
- "/projects/website",
- "Learn More",
- );
- info.append_element(website_desc);
- info.append_element(view);
- website.append_element(website_title);
- website.append_element(info);
- let css = link::new("stylesheet", "/static/css/projects.css");
- page.append_element_to_head(css);
- page.append_element_to_body(title);
- page.append_element_to_body(desc);
- page.append_element_to_body(website);
+ )
+ .build();
+ let website_title = Heading::builder().text("Website").build();
+ let website_desc = Paragraph::builder()
+ .classes(vec!["project-desc"])
+ .text("This project is the website you currently are on.")
+ .build();
+ let view = Anchor::builder().classes(vec!["project-view"]).href("/projects/website").text("Learn More").build();
+ let info = Division::builder()
+ .classes(vec!["project-info"])
+ .elements(boxed_vec![website_desc, view])
+ .build();
+ let website = Division::builder()
+ .classes(vec!["project"])
+ .elements(boxed_vec![website_title, info])
+ .build();
+ let css = Link::builder()
+ .rel("stylesheet")
+ .href("/static/css/projects.css")
+ .build();
+ let page = BasePage::builder()
+ .title("Projects")
+ .head(boxed_vec![css])
+ .body(boxed_vec![title, desc, website])
+ .build();
page.render()
}
#[get("/projects/{project}")]
async fn project(project: web::Path) -> impl Responder {
let project = project.into_inner();
- let mut page = BasePage::new(format!("Project-{}", project));
+ let css = Link::builder()
+ .rel("stylesheet")
+ .href("/static/css/project.css")
+ .build();
+ let mut page = BasePage::builder()
+ .title(format!("Project-{}", project))
+ .head(boxed_vec![css])
+ .build();
match project.as_str() {
"website" => {
- let title = h1::new("Website");
- let desc = p::new(
- "description",
- vec!["description"],
+ let title = Heading::builder().text("Website").build();
+ let desc = Paragraph::builder().classes(vec!["description"]).text(
"This project, the website you are on, \
is made in Rust such that all the pages are generated by code.
\
That is that each html element is represented by a struct which implements the Render trait (as in render the element to html).
\
As it is right now the system is not that impressive but I believe it can do amazing things in the futur.
\
\
Wish to see more? Check out the gitea repository: ",
- );
+ ).build();
page.append_element_to_body(title);
page.append_element_to_body(desc);
}
_ => {}
}
- let css = link::new("stylesheet", "/static/css/project.css");
- page.append_element_to_head(css);
page.render()
}