Styling for articles
This commit is contained in:
1 parent
824e6a5d72
commit
1d67f611fc
4 files changed
+103
-16
No files matched your search
@@ -54,10 +54,15 @@ impl CodeBlockRenderer {
|
|||||||
|
|
||||||
let html_out = html_gen.finalize();
|
let html_out = html_gen.finalize();
|
||||||
|
|
||||||
//TODO: show context & language
|
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
pre .codeblock {
|
.codeblock {
|
||||||
|
@if context.is_some() || !lang.is_empty() {
|
||||||
|
.codeblock_banner {
|
||||||
|
span .codeblock_language { (lang) }
|
||||||
|
span .codeblock_context { (context.unwrap_or("")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pre .codeblock_code {
|
||||||
code {
|
code {
|
||||||
(PreEscaped(html_out))
|
(PreEscaped(html_out))
|
||||||
}
|
}
|
||||||
@@ -65,3 +70,4 @@ impl CodeBlockRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
+17
-1
@@ -2,7 +2,7 @@ use std::{borrow, error, fmt, ops};
|
|||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use libshire::{strings::ShString22, uuid::{Uuid, UuidV5Error}};
|
use libshire::{strings::ShString22, uuid::{Uuid, UuidV5Error}};
|
||||||
use maud::{Markup, PreEscaped};
|
use maud::{Markup, PreEscaped, html};
|
||||||
|
|
||||||
use crate::codeblock::CodeBlockRenderer;
|
use crate::codeblock::CodeBlockRenderer;
|
||||||
|
|
||||||
@@ -76,6 +76,7 @@ pub struct Post {
|
|||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
id: PostId,
|
id: PostId,
|
||||||
title: String,
|
title: String,
|
||||||
|
subtitle: Option<String>,
|
||||||
author: String,
|
author: String,
|
||||||
html: Markup,
|
html: Markup,
|
||||||
tags: Vec<ShString22>,
|
tags: Vec<ShString22>,
|
||||||
@@ -96,6 +97,10 @@ impl Post {
|
|||||||
&self.title
|
&self.title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn subtitle(&self) -> Option<&str> {
|
||||||
|
self.subtitle.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn author(&self) -> &str {
|
pub fn author(&self) -> &str {
|
||||||
&self.author
|
&self.author
|
||||||
}
|
}
|
||||||
@@ -169,6 +174,7 @@ impl Post {
|
|||||||
uuid,
|
uuid,
|
||||||
id,
|
id,
|
||||||
title: mdpost.title,
|
title: mdpost.title,
|
||||||
|
subtitle: mdpost.subtitle,
|
||||||
author: mdpost.author,
|
author: mdpost.author,
|
||||||
html: PreEscaped(html_buf),
|
html: PreEscaped(html_buf),
|
||||||
tags: mdpost.tags,
|
tags: mdpost.tags,
|
||||||
@@ -226,6 +232,12 @@ impl<'e, 'p, I> Iterator for PostMdParser<'p, I> where I: Iterator<Item = pulldo
|
|||||||
Event::Html(CowStr::Boxed(highlighted.into_string().into_boxed_str()))
|
Event::Html(CowStr::Boxed(highlighted.into_string().into_boxed_str()))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Event::Code(code) => {
|
||||||
|
Event::Html(CowStr::Boxed(html! {
|
||||||
|
code .inline_code { (code) }
|
||||||
|
}.into_string().into_boxed_str()))
|
||||||
|
},
|
||||||
|
|
||||||
event => {
|
event => {
|
||||||
match &event {
|
match &event {
|
||||||
Event::Start(Tag::Link(LinkType::Inline | LinkType::Autolink, destination, _title)) => {
|
Event::Start(Tag::Link(LinkType::Inline | LinkType::Autolink, destination, _title)) => {
|
||||||
@@ -253,6 +265,8 @@ struct HeaderNode {
|
|||||||
#[knuffel(child, unwrap(argument))]
|
#[knuffel(child, unwrap(argument))]
|
||||||
title: String,
|
title: String,
|
||||||
#[knuffel(child, unwrap(argument))]
|
#[knuffel(child, unwrap(argument))]
|
||||||
|
subtitle: Option<String>,
|
||||||
|
#[knuffel(child, unwrap(argument))]
|
||||||
author: String,
|
author: String,
|
||||||
#[knuffel(children(name="tag"))]
|
#[knuffel(children(name="tag"))]
|
||||||
tags: Vec<TagNode>,
|
tags: Vec<TagNode>,
|
||||||
@@ -268,6 +282,7 @@ struct TagNode {
|
|||||||
struct MdPost {
|
struct MdPost {
|
||||||
markdown: String,
|
markdown: String,
|
||||||
title: String,
|
title: String,
|
||||||
|
subtitle: Option<String>,
|
||||||
author: String,
|
author: String,
|
||||||
tags: Vec<ShString22>,
|
tags: Vec<ShString22>,
|
||||||
}
|
}
|
||||||
@@ -287,6 +302,7 @@ impl MdPost {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
markdown: md.to_owned(),
|
markdown: md.to_owned(),
|
||||||
title: header.title,
|
title: header.title,
|
||||||
|
subtitle: header.subtitle,
|
||||||
author: header.author,
|
author: header.author,
|
||||||
tags: header.tags.into_iter().map(|tag| tag.tag.into()).collect(),
|
tags: header.tags.into_iter().map(|tag| tag.tag.into()).collect(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
use axum::extract::{Extension, Path};
|
use axum::extract::{Extension, Path};
|
||||||
use maud::html;
|
use maud::html;
|
||||||
|
|
||||||
use crate::posts_store::ConcurrentPostsStore;
|
use crate::{
|
||||||
|
posts_store::ConcurrentPostsStore,
|
||||||
|
template,
|
||||||
|
};
|
||||||
use super::response::{Error, Html};
|
use super::response::{Error, Html};
|
||||||
|
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
@@ -17,13 +20,19 @@ pub async fn handle(
|
|||||||
.with_crawler_permissive()
|
.with_crawler_permissive()
|
||||||
.with_title_owned(post.title().to_owned())
|
.with_title_owned(post.title().to_owned())
|
||||||
.with_head(html! {
|
.with_head(html! {
|
||||||
|
link href="/static/styles/main.css" rel="stylesheet";
|
||||||
link href="/static/styles/code.css" rel="stylesheet";
|
link href="/static/styles/code.css" rel="stylesheet";
|
||||||
})
|
})
|
||||||
.with_body(html! {
|
.with_body(template::main_page(html! {
|
||||||
h1 { (post.title()) }
|
section .article_header {
|
||||||
p { "by " (post.author()) }
|
h1 .article_title { (post.title()) }
|
||||||
article {
|
@if let Some(subtitle) = post.subtitle() {
|
||||||
|
p .article_subtitle { (subtitle) }
|
||||||
|
}
|
||||||
|
p .article_published_date { "Published " (post.created().format("%Y/%m/%d")) }
|
||||||
|
}
|
||||||
|
article .article_content {
|
||||||
(post.html())
|
(post.html())
|
||||||
}
|
}
|
||||||
}))
|
})))
|
||||||
}
|
}
|
||||||
+62
-6
@@ -45,7 +45,6 @@ body {
|
|||||||
grid-template-rows: auto 1fr auto;
|
grid-template-rows: auto 1fr auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
/* font-family: Gill Sans, Gill Sans MT, Calibri, sans-serif; */
|
|
||||||
font-family: Rubik, sans-serif;
|
font-family: Rubik, sans-serif;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
@@ -59,15 +58,12 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#page_nav {
|
#page_nav {
|
||||||
/* background-color: #F7B801; */
|
|
||||||
/* background-color: #7678ED; */
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 1rem 1rem;
|
padding: 1rem 1rem;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 60rem;
|
max-width: 60rem;
|
||||||
/* box-shadow: 0px 2px 10px #B8B8B8; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#page_nav #title_box {
|
#page_nav #title_box {
|
||||||
@@ -164,8 +160,6 @@ h1, h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
/* display: flex;
|
|
||||||
flex-direction: column; */
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -188,6 +182,68 @@ li {
|
|||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.article_header {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
border-bottom: 2px solid #94BFBE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article_title {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article_subtitle {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article_published_date {
|
||||||
|
color: #898989;
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeblock {
|
||||||
|
background-color: #FAF9F6;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeblock_banner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
padding-top: 0.25rem;
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeblock_code {
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline_code {
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
padding: 0.1rem 0.2rem;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeblock_banner {
|
||||||
|
background-color: #94BFBE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Palette
|
Palette
|
||||||
#94BFBE
|
#94BFBE
|
||||||
|
|||||||
Reference in new issue
Block a user