Add quote block

This commit is contained in:
Evie Viau-Chow-Stuart 2023-02-08 05:16:23 -08:00
parent c669c306e6
commit 0ce8ddd96e
Signed by: evie
GPG key ID: 928652CDFCEC8099
5 changed files with 138 additions and 145 deletions

View file

@ -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<image::Model>
},
UNSUPPORTED
HEADER { id: String, text: String, size: i8 },
PARAGRAPH { text: String },
MARKDOWN { content: String },
HTML { content: String },
IMAGE { content: Option<image::Model> },
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<GenericBlock>,
) -> Vec<BlockTypes> {
let mut content_blocks: Vec<BlockTypes> = 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
}

View file

@ -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<AppState>) -> impl IntoResponse {
None => panic!("Missing \"home\" page in database!"),
};
let blocks: Vec<page_block::Model> = page_meta
let blocks: Vec<GenericBlock> = 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<BlockTypes> = 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<menu_entry::Model> = match Menu::find()
.filter(menu::Column::Name.eq("primary"))

View file

@ -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_block::Model> = page_meta
let blocks: Vec<GenericBlock> = 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<BlockTypes> = 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,

View file

@ -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_block::Model> = post_meta
let blocks: Vec<GenericBlock> = 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<BlockTypes> = 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());

View file

@ -7,8 +7,8 @@
{{ content|markdown }}
{% when BlockTypes::HTML { content } %}
{{ content|safe }}
{% when BlockTypes::HEADER { text, size } %}
<h{{size}}>{{text}}</h{{size}}>
{% when BlockTypes::HEADER { id, text, size } %}
<h{{ size }} id="{{ id }}">{{ text }}</h{{ size }}>
{% when BlockTypes::IMAGE { content } %}
{% match content %}
{% when Some with (image) %}
@ -31,6 +31,15 @@
<br />
{% when None %}
{% endmatch %}
{% when BlockTypes::QUOTE { quote, caption } %}
<figure>
<blockquote>
<p>{{ quote }}</p>
</blockquote>
<cite>
{{ caption }}
</cite>
</figure>
{% else %}
<b>UNSUPPORTED block type here!</b>
{% endmatch %}