diff --git a/src/block_types.rs b/src/block_types.rs index 0698077..535f7b4 100644 --- a/src/block_types.rs +++ b/src/block_types.rs @@ -1,30 +1,96 @@ +use log::warn; +use sea_orm::{DatabaseConnection, EntityTrait}; use serde::Deserialize; -use crate::entities::image; +use crate::entities::{prelude::*, *}; pub enum BlockTypes { HR, - HEADER { - text: String, - size: i8, - }, - PARAGRAPH { - text: String, - }, - MARKDOWN { - content: String, - }, - HTML { - content: String, - }, - IMAGE { - content: Option - }, - UNSUPPORTED + HEADER { id: String, text: String, size: i8 }, + PARAGRAPH { text: String }, + MARKDOWN { content: String }, + HTML { content: String }, + IMAGE { content: Option }, + QUOTE { quote: String, caption: String }, + UNSUPPORTED, } +// Database JSON types + #[derive(Deserialize)] pub struct Header { + pub id: String, pub text: String, pub size: i8, } + +#[derive(Deserialize)] +pub struct Quote { + pub quote: String, + pub caption: String, +} + +// Content block handling + +pub struct GenericBlock { + pub id: String, + pub owner: String, + pub order: i32, + pub block_type: String, + pub content: String, +} + +pub async fn generate_content_blocks( + db_conn: &DatabaseConnection, + blocks: Vec, +) -> Vec { + let mut content_blocks: Vec = vec![]; + + for block in blocks { + content_blocks.push(match block.block_type.as_str() { + "HR" => BlockTypes::HR, + "PARAGRAPH" => BlockTypes::PARAGRAPH { + text: block.content, + }, + "MARKDOWN" => BlockTypes::MARKDOWN { + content: block.content, + }, + "HEADER" => { + let deserde: Header = serde_json::from_str(block.content.as_str()) + .expect("Incorrect HEADER block formatting"); + + BlockTypes::HEADER { + id: deserde.id, + text: deserde.text, + size: deserde.size, + } + } + "HTML" => BlockTypes::HTML { + content: block.content, + }, + "IMAGE" => BlockTypes::IMAGE { + content: { + Image::find_by_id(block.content) + .one(db_conn) + .await + .expect("Failed to get image! HALTING") + }, + }, + "QUOTE" => { + let deserde: Quote = serde_json::from_str(block.content.as_str()) + .expect("Incorrect QUOTE block formatting"); + + BlockTypes::QUOTE { + quote: deserde.quote, + caption: deserde.caption, + } + } + _ => { + warn!("Unsupported block type! ({})", block.block_type.as_str()); + BlockTypes::UNSUPPORTED + } + }); + } + + content_blocks +} diff --git a/src/routes/mod.rs b/src/routes/mod.rs index b4188aa..58c8284 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -9,9 +9,8 @@ use chrono::{Datelike, Utc}; use axum::extract::State; use axum::http::StatusCode; -use log::warn; -use crate::block_types; +use crate::block_types::{generate_content_blocks, GenericBlock}; use crate::entities::{prelude::*, *}; use sea_orm::*; @@ -87,50 +86,23 @@ pub(crate) async fn root(state: State) -> impl IntoResponse { None => panic!("Missing \"home\" page in database!"), }; - let blocks: Vec = page_meta + let blocks: Vec = page_meta .find_related(PageBlock) .order_by_asc(page_block::Column::Order) .all(&state.db_conn) .await - .expect("Failed to get home page blocks! HALTING"); + .expect("Failed to get home page blocks! HALTING") + .into_iter() + .map(|f| GenericBlock { + id: f.id, + owner: f.owner, + order: f.order, + block_type: f.r#type, + content: f.content, + }) + .collect(); - let mut content_blocks: Vec = vec![]; - - for block in blocks { - content_blocks.push(match block.r#type.as_str() { - "HR" => BlockTypes::HR, - "PARAGRAPH" => BlockTypes::PARAGRAPH { - text: block.content, - }, - "MARKDOWN" => BlockTypes::MARKDOWN { - content: block.content, - }, - "HEADER" => { - let deserde: block_types::Header = serde_json::from_str(block.content.as_str()) - .expect("Incorrect HEADER block formatting"); - - BlockTypes::HEADER { - text: deserde.text, - size: deserde.size, - } - } - "HTML" => BlockTypes::HTML { - content: block.content, - }, - "IMAGE" => BlockTypes::IMAGE { - content: { - Image::find_by_id(block.content) - .one(&state.db_conn) - .await - .expect("Failed to get image! HALTING") - }, - }, - _ => { - warn!("Unsupported block type! ({})", block.r#type.as_str()); - BlockTypes::UNSUPPORTED - } - }); - } + let content_blocks = generate_content_blocks(&state.db_conn, blocks).await; let menu: Vec = match Menu::find() .filter(menu::Column::Name.eq("primary")) diff --git a/src/routes/page_resolver.rs b/src/routes/page_resolver.rs index 5c22359..09329fb 100644 --- a/src/routes/page_resolver.rs +++ b/src/routes/page_resolver.rs @@ -1,13 +1,13 @@ use askama_axum::IntoResponse; use axum::extract::{Path, State}; use axum::http::StatusCode; -use log::{error, warn}; +use log::error; -use crate::block_types; use crate::entities::{prelude::*, *}; -use crate::{block_types::BlockTypes, AppState}; +use crate::AppState; use sea_orm::*; +use crate::block_types::{generate_content_blocks, GenericBlock}; use chrono::{Datelike, Utc}; use super::{PageNotFoundTemplate, PageTemplate}; @@ -68,50 +68,23 @@ pub(crate) async fn resolver( } }; - let blocks: Vec = page_meta + let blocks: Vec = page_meta .find_related(PageBlock) .order_by_asc(page_block::Column::Order) .all(&state.db_conn) .await - .expect("Failed to get home page blocks! HALTING"); + .expect("Failed to get home page blocks! HALTING") + .into_iter() + .map(|f| GenericBlock { + id: f.id, + owner: f.owner, + order: f.order, + block_type: f.r#type, + content: f.content, + }) + .collect(); - let mut content_blocks: Vec = vec![]; - - for block in blocks { - content_blocks.push(match block.r#type.as_str() { - "HR" => BlockTypes::HR, - "PARAGRAPH" => BlockTypes::PARAGRAPH { - text: block.content, - }, - "MARKDOWN" => BlockTypes::MARKDOWN { - content: block.content, - }, - "HEADER" => { - let deserde: block_types::Header = serde_json::from_str(block.content.as_str()) - .expect("Incorrect HEADER block formatting"); - - BlockTypes::HEADER { - text: deserde.text, - size: deserde.size, - } - } - "HTML" => BlockTypes::HTML { - content: block.content, - }, - "IMAGE" => BlockTypes::IMAGE { - content: { - Image::find_by_id(block.content) - .one(&state.db_conn) - .await - .expect("Failed to get image! HALTING") - }, - }, - _ => { - warn!("Unsupported block type! ({})", block.r#type.as_str()); - BlockTypes::UNSUPPORTED - } - }); - } + let content_blocks = generate_content_blocks(&state.db_conn, blocks).await; ( StatusCode::OK, diff --git a/src/routes/post_resolver.rs b/src/routes/post_resolver.rs index f3981d8..0919ff0 100644 --- a/src/routes/post_resolver.rs +++ b/src/routes/post_resolver.rs @@ -1,13 +1,13 @@ use askama_axum::IntoResponse; use axum::extract::{Path, State}; use axum::http::StatusCode; -use log::{error, warn}; +use log::error; -use crate::block_types; use crate::entities::{prelude::*, *}; -use crate::{block_types::BlockTypes, AppState}; +use crate::AppState; use sea_orm::*; +use crate::block_types::{generate_content_blocks, GenericBlock}; use chrono::{Datelike, Utc}; use super::{PostNotFoundTemplate, PostTemplate}; @@ -68,50 +68,23 @@ pub(crate) async fn resolver( } }; - let blocks: Vec = post_meta + let blocks: Vec = post_meta .find_related(PostBlock) .order_by_asc(post_block::Column::Order) .all(&state.db_conn) .await - .expect("Failed to get post blocks! HALTING"); + .expect("Failed to get post blocks! HALTING") + .into_iter() + .map(|f| GenericBlock { + id: f.id, + owner: f.owner, + order: f.order, + block_type: f.r#type, + content: f.content, + }) + .collect(); - let mut content_blocks: Vec = vec![]; - - for block in blocks { - content_blocks.push(match block.r#type.as_str() { - "HR" => BlockTypes::HR, - "PARAGRAPH" => BlockTypes::PARAGRAPH { - text: block.content, - }, - "MARKDOWN" => BlockTypes::MARKDOWN { - content: block.content, - }, - "HEADER" => { - let deserde: block_types::Header = serde_json::from_str(block.content.as_str()) - .expect("Incorrect HEADER block formatting"); - - BlockTypes::HEADER { - text: deserde.text, - size: deserde.size, - } - } - "HTML" => BlockTypes::HTML { - content: block.content, - }, - "IMAGE" => BlockTypes::IMAGE { - content: { - Image::find_by_id(block.content) - .one(&state.db_conn) - .await - .expect("Failed to get image! HALTING") - }, - }, - _ => { - warn!("Unsupported block type! ({})", block.r#type.as_str()); - BlockTypes::UNSUPPORTED - } - }); - } + let content_blocks = generate_content_blocks(&state.db_conn, blocks).await; let last_updated = post_meta.clone().updated.map(|updated| updated.to_string()); diff --git a/templates/resolve_content.html b/templates/resolve_content.html index a35464f..9ea27da 100644 --- a/templates/resolve_content.html +++ b/templates/resolve_content.html @@ -7,8 +7,8 @@ {{ content|markdown }} {% when BlockTypes::HTML { content } %} {{ content|safe }} - {% when BlockTypes::HEADER { text, size } %} - {{text}} + {% when BlockTypes::HEADER { id, text, size } %} + {{ text }} {% when BlockTypes::IMAGE { content } %} {% match content %} {% when Some with (image) %} @@ -31,6 +31,15 @@
{% when None %} {% endmatch %} + {% when BlockTypes::QUOTE { quote, caption } %} +
+
+

{{ quote }}

+
+ + {{ caption }} + +
{% else %} UNSUPPORTED block type here! {% endmatch %}