Add quote block
This commit is contained in:
parent
c669c306e6
commit
0ce8ddd96e
5 changed files with 138 additions and 145 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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 %}
|
||||
|
|
Reference in a new issue