page rewrite
Some checks failed
CI / Check typos (push) Failing after 9s
CI / Check links (push) Failing after 14s
CI / Clippy (push) Successful in 53s
CI / Build and test (push) Successful in 1m19s
CI / Build container (push) Has been skipped
CI / Deploy on waypoint (push) Has been skipped
Some checks failed
CI / Check typos (push) Failing after 9s
CI / Check links (push) Failing after 14s
CI / Clippy (push) Successful in 53s
CI / Build and test (push) Successful in 1m19s
CI / Build container (push) Has been skipped
CI / Deploy on waypoint (push) Has been skipped
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
use chrono::TimeDelta;
|
||||
use maud::{DOCTYPE, Markup, PreEscaped, html};
|
||||
use page::page::{Page, PageMetadata};
|
||||
use reqwest::StatusCode;
|
||||
use std::pin::Pin;
|
||||
use maud::{Markup, PreEscaped, html};
|
||||
use page::{
|
||||
RenderContext,
|
||||
servable::{Page, PageMetadata, PageTemplate},
|
||||
};
|
||||
|
||||
use crate::components::{
|
||||
fa::FAIcon,
|
||||
md::{Markdown, backlinks, meta_from_markdown},
|
||||
md::{Markdown, meta_from_markdown},
|
||||
misc::FarLink,
|
||||
};
|
||||
|
||||
@@ -67,120 +68,119 @@ fn page_from_markdown(md: impl Into<String>, default_image: Option<String>) -> P
|
||||
|
||||
let html = PreEscaped(md.render());
|
||||
|
||||
Page {
|
||||
meta,
|
||||
immutable: true,
|
||||
response_code: StatusCode::OK,
|
||||
|
||||
html_ttl: Some(TimeDelta::days(1)),
|
||||
generate_html: Box::new(move |page, ctx| {
|
||||
MAIN_TEMPLATE
|
||||
.derive(meta, move |_page, ctx| {
|
||||
let html = html.clone();
|
||||
|
||||
Box::pin(async move {
|
||||
let inner = html! {
|
||||
@if let Some(backlinks) = backlinks(page, ctx) {
|
||||
(backlinks)
|
||||
html! {
|
||||
div class="wrapper" style="margin-top:3ex;" {
|
||||
@if let Some(backlinks) = backlinks(ctx) {
|
||||
(backlinks)
|
||||
}
|
||||
|
||||
(html)
|
||||
|
||||
(footer())
|
||||
}
|
||||
|
||||
(html)
|
||||
};
|
||||
|
||||
page_wrapper(&page.meta, inner, true).await
|
||||
}
|
||||
})
|
||||
}),
|
||||
}
|
||||
})
|
||||
.html_ttl(Some(TimeDelta::days(1)))
|
||||
.immutable(true)
|
||||
}
|
||||
|
||||
//
|
||||
// MARK: wrapper
|
||||
// MARK: components
|
||||
//
|
||||
|
||||
pub fn page_wrapper<'a>(
|
||||
meta: &'a PageMetadata,
|
||||
inner: Markup,
|
||||
footer: bool,
|
||||
) -> Pin<Box<dyn Future<Output = Markup> + 'a + Send + Sync>> {
|
||||
Box::pin(async move {
|
||||
const MAIN_TEMPLATE: PageTemplate = PageTemplate {
|
||||
// Order matters, base htmx goes first
|
||||
scripts_linked: &["/assets/htmx.js", "/assets/htmx-json.js"],
|
||||
|
||||
// TODO: use htmx for this
|
||||
scripts_inline: &["
|
||||
window.onload = function() {
|
||||
var imgs = document.querySelectorAll('.img-placeholder');
|
||||
|
||||
imgs.forEach(img => {
|
||||
img.style.border = 'none';
|
||||
img.style.filter = 'blur(10px)';
|
||||
img.style.transition = 'filter 0.3s';
|
||||
|
||||
var lg = new Image();
|
||||
lg.src = img.dataset.large;
|
||||
lg.onload = function () {
|
||||
img.src = img.dataset.large;
|
||||
img.style.filter = 'blur(0px)';
|
||||
};
|
||||
})
|
||||
}
|
||||
"],
|
||||
|
||||
styles_inline: &[],
|
||||
styles_linked: &["/assets/css/main.css"],
|
||||
|
||||
extra_meta: &[(
|
||||
"viewport",
|
||||
"width=device-width,initial-scale=1,user-scalable=no",
|
||||
)],
|
||||
|
||||
..PageTemplate::const_default()
|
||||
};
|
||||
|
||||
pub fn backlinks(ctx: &RenderContext) -> Option<Markup> {
|
||||
let mut backlinks = vec![("/", "home")];
|
||||
|
||||
let mut segments = ctx.route.split("/").skip(1).collect::<Vec<_>>();
|
||||
let last = segments.pop();
|
||||
|
||||
let mut end = 0;
|
||||
for s in segments {
|
||||
end += s.len();
|
||||
backlinks.push((&ctx.route[0..=end], s));
|
||||
end += 1; // trailing slash
|
||||
}
|
||||
|
||||
last.map(|last| {
|
||||
html! {
|
||||
(DOCTYPE)
|
||||
html {
|
||||
head {
|
||||
meta charset="UTF8" {}
|
||||
meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" {}
|
||||
meta content="text/html; charset=UTF-8" http-equiv="content-type" {}
|
||||
meta property="og:type" content="website" {}
|
||||
|
||||
link rel="stylesheet" href=("/assets/css/main.css") {}
|
||||
|
||||
(&meta)
|
||||
title { (PreEscaped(meta.title.clone())) }
|
||||
|
||||
|
||||
// Use a small blurred placeholder while full-size images load.
|
||||
// Requires no other special scripts or css, just add some tags
|
||||
// to your <img>!
|
||||
script {
|
||||
(PreEscaped("
|
||||
window.onload = function() {
|
||||
var imgs = document.querySelectorAll('.img-placeholder');
|
||||
|
||||
imgs.forEach(img => {
|
||||
img.style.border = 'none';
|
||||
img.style.filter = 'blur(10px)';
|
||||
img.style.transition = 'filter 0.3s';
|
||||
|
||||
var lg = new Image();
|
||||
lg.src = img.dataset.large;
|
||||
lg.onload = function () {
|
||||
img.src = img.dataset.large;
|
||||
img.style.filter = 'blur(0px)';
|
||||
};
|
||||
})
|
||||
}
|
||||
"))
|
||||
}
|
||||
div {
|
||||
@for (url, text) in backlinks {
|
||||
a href=(url) style="padding-left:5pt;padding-right:5pt;" { (text) }
|
||||
"/"
|
||||
}
|
||||
|
||||
body {
|
||||
main{
|
||||
div class="wrapper" style=(
|
||||
// for 404 page. Margin makes it scroll.
|
||||
match footer {
|
||||
true => "margin-top:3ex;",
|
||||
false =>""
|
||||
}
|
||||
) {
|
||||
(inner)
|
||||
|
||||
@if footer {
|
||||
footer style="margin-top:10rem;" {
|
||||
hr class = "footline" {}
|
||||
div class = "footContainer" {
|
||||
p {
|
||||
"This site was built by hand with "
|
||||
(FarLink("https://rust-lang.org", "Rust"))
|
||||
", "
|
||||
(FarLink("https://maud.lambda.xyz", "Maud"))
|
||||
", and "
|
||||
(FarLink("https://docs.rs/axum/latest/axum", "Axum"))
|
||||
". "
|
||||
|
||||
(
|
||||
FarLink(
|
||||
"https://git.betalupi.com/Mark/webpage",
|
||||
html!(
|
||||
(FAIcon::Git)
|
||||
"Source here!"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
span style="color:var(--metaColor);padding-left:5pt;padding-right:5pt;" { (last) }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn footer() -> Markup {
|
||||
html!(
|
||||
footer style="margin-top:10rem;" {
|
||||
hr class = "footline";
|
||||
div class = "footContainer" {
|
||||
p {
|
||||
"This site was built by hand with "
|
||||
(FarLink("https://rust-lang.org", "Rust"))
|
||||
", "
|
||||
(FarLink("https://maud.lambda.xyz", "Maud"))
|
||||
", and "
|
||||
(FarLink("https://docs.rs/axum/latest/axum", "Axum"))
|
||||
". "
|
||||
|
||||
(
|
||||
FarLink(
|
||||
"https://git.betalupi.com/Mark/webpage",
|
||||
html!(
|
||||
(FAIcon::Git)
|
||||
"Source here!"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user