aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@blos.sm>2024-02-10 06:54:25 +0000
committerLibravatar cel 🌸 <cel@blos.sm>2024-02-10 06:54:25 +0000
commit88fa09755ff31b39b0454f0da58bc41a90263e89 (patch)
tree31e91e27324366bbea20b4af2a17ec10f73322e9 /src
parent205a71efa9f60938c86d57bba07f6d33b21790a2 (diff)
downloadblossom-88fa09755ff31b39b0454f0da58bc41a90263e89.tar.gz
blossom-88fa09755ff31b39b0454f0da58bc41a90263e89.tar.bz2
blossom-88fa09755ff31b39b0454f0da58bc41a90263e89.zip
add initial localisation
Diffstat (limited to 'src')
-rw-r--r--src/error.rs1
-rw-r--r--src/main.rs54
-rw-r--r--src/templates.rs22
3 files changed, 63 insertions, 14 deletions
diff --git a/src/error.rs b/src/error.rs
index 611ce79..adaf77f 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -56,6 +56,7 @@ impl ResponseError for BlossomError {
Self: std::error::Error + Send + Sync + 'static,
{
templates::Error {
+ title: self.to_string(),
status: self.status(),
message: self.to_string(),
}
diff --git a/src/main.rs b/src/main.rs
index 2f1a00b..de7bc73 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,6 +15,7 @@ mod utils;
use std::{collections::HashSet, time::Duration};
use poem::http::StatusCode;
+use poem::i18n::{I18NResources, Locale};
use poem::{
endpoint::EmbeddedFilesEndpoint,
get, handler,
@@ -44,7 +45,7 @@ type Result<T> = std::result::Result<T, BlossomError>;
struct Static;
#[handler]
-async fn home(Data(reqwest): Data<&reqwest::Client>) -> templates::Home {
+async fn home(Data(reqwest): Data<&reqwest::Client>, locale: Locale) -> templates::Home {
let listenbrainz_client = listenbrainz::raw::Client::new();
let (live, listenbrainz, blogposts, poems) = tokio::join!(
live::get_live_status(reqwest),
@@ -59,20 +60,27 @@ async fn home(Data(reqwest): Data<&reqwest::Client>) -> templates::Home {
let poems = poems.unwrap_or_default();
let poem = poems.choose(&mut rand::thread_rng()).cloned();
templates::Home {
+ title: locale.text("title").unwrap(),
is_live,
listenbrainz,
blogposts,
poem,
+ locale,
}
}
// #[get("/blog/<blogpost>")]
#[handler]
-async fn blogpost(Path(blogpost): Path<String>) -> Result<templates::Blogpost> {
+async fn blogpost(Path(blogpost): Path<String>, locale: Locale) -> Result<templates::Blogpost> {
let blogpost = Blogpost::get_article(&blogpost).await?;
Ok(templates::Blogpost {
+ title: blogpost
+ .subject()
+ .unwrap_or(locale.text("untitled").unwrap().as_str())
+ .to_owned(),
blogpost,
filter_tags: HashSet::new(),
+ locale,
})
}
@@ -83,7 +91,10 @@ struct FilterTags {
// #[get("/blog?<filter>")]
#[handler]
-async fn get_blog(filter_tags: Option<Query<FilterTags>>) -> Result<templates::Blog> {
+async fn get_blog(
+ filter_tags: Option<Query<FilterTags>>,
+ locale: Locale,
+) -> Result<templates::Blog> {
let mut blogposts = Blogpost::get_articles().await?;
let tags: Vec<String> = posts::Post::get_tags(&blogposts)
.into_iter()
@@ -95,12 +106,15 @@ async fn get_blog(filter_tags: Option<Query<FilterTags>>) -> Result<templates::B
blogposts = posts::Post::filter_by_tags(blogposts, &filter_hashset);
}
Ok(templates::Blog {
+ title: locale.text("title-blog").unwrap(),
blogposts,
tags,
filter_tags: filter_hashset,
+ locale,
})
}
+// TODO: localize feed
#[handler]
async fn feed() -> Result<Response> {
let blogposts: Vec<Box<dyn Post + Send + Sync>> = Blogpost::get_articles()
@@ -132,8 +146,11 @@ async fn feed() -> Result<Response> {
}
#[handler]
-async fn contact() -> templates::Contact {
- templates::Contact
+async fn contact(locale: Locale) -> templates::Contact {
+ templates::Contact {
+ title: locale.text("title-contact").unwrap(),
+ locale,
+ }
}
#[handler]
@@ -142,21 +159,34 @@ async fn plants() -> Result<()> {
}
#[handler]
-async fn get_poem(Path(poem): Path<String>) -> Result<templates::Poem> {
+async fn get_poem(Path(poem): Path<String>, locale: Locale) -> Result<templates::Poem> {
let poem = Poem::get_article(&poem).await?;
- Ok(templates::Poem { poem, jiggle: 4 })
+ Ok(templates::Poem {
+ title: (&poem.title)
+ .clone()
+ .unwrap_or(locale.text("untitled").unwrap()),
+ poem,
+ jiggle: 4,
+ locale,
+ })
}
#[handler]
-async fn get_poetry() -> Result<templates::Poetry> {
+async fn get_poetry(locale: Locale) -> Result<templates::Poetry> {
let mut poems = Poem::get_articles().await?;
poems.sort_by_key(|poem| poem.created_at);
poems.reverse();
- Ok(templates::Poetry { poems, jiggle: 16 })
+ Ok(templates::Poetry {
+ title: locale.text("title-poetry").unwrap(),
+ poems,
+ jiggle: 16,
+ locale,
+ })
}
async fn custom_error(err: poem::Error) -> impl IntoResponse {
templates::Error {
+ title: err.to_string(),
status: err.status(),
message: err.to_string(),
}
@@ -171,6 +201,11 @@ async fn main() -> std::result::Result<(), std::io::Error> {
// let mut skinny_data = mastodon_async::Data::default();
// skinny_data.base = Cow::from("https://skinnyver.se");
+ let resources = I18NResources::builder()
+ .add_path("./resources")
+ .build()
+ .unwrap();
+
let blossom = Route::new()
.at("/", get(home))
.at("/blog", get(get_blog))
@@ -182,6 +217,7 @@ async fn main() -> std::result::Result<(), std::io::Error> {
.at("/plants", get(plants))
.nest("/static/", EmbeddedFilesEndpoint::<Static>::new())
.catch_all_error(custom_error)
+ .data(resources)
.with(Tracing)
.with(AddData::new(
reqwest::Client::builder()
diff --git a/src/templates.rs b/src/templates.rs
index 4bcb64b..2ab9c41 100644
--- a/src/templates.rs
+++ b/src/templates.rs
@@ -2,6 +2,7 @@ use std::collections::HashSet;
use askama::Template;
use poem::http::StatusCode;
+use poem::i18n::Locale;
use rand::{thread_rng, Rng};
use crate::poetry;
@@ -17,55 +18,66 @@ mod filters {
}
#[derive(Template)]
-#[template(path = "base.html")]
-struct Base;
-
-#[derive(Template)]
#[template(path = "home.html")]
pub struct Home {
+ pub title: String,
pub is_live: bool,
pub listenbrainz: NowPlayingData,
pub blogposts: Vec<blog::Blogpost>,
pub poem: Option<poetry::Poem>,
+ pub locale: Locale,
}
#[derive(Template)]
#[template(path = "blogpost.html")]
pub struct Blogpost {
+ pub title: String,
pub blogpost: blog::Blogpost,
pub filter_tags: HashSet<String>,
+ pub locale: Locale,
}
// filtertags, blogpost-panel
#[derive(Template)]
#[template(path = "blog.html")]
pub struct Blog {
+ pub title: String,
pub blogposts: Vec<blog::Blogpost>,
pub tags: Vec<String>,
pub filter_tags: HashSet<String>,
+ pub locale: Locale,
}
#[derive(Template)]
#[template(path = "poem.html")]
pub struct Poem {
+ pub title: String,
pub poem: poetry::Poem,
pub jiggle: isize,
+ pub locale: Locale,
}
#[derive(Template)]
#[template(path = "poetry.html")]
pub struct Poetry {
+ pub title: String,
pub poems: Vec<poetry::Poem>,
pub jiggle: isize,
+ pub locale: Locale,
}
#[derive(Template)]
#[template(path = "contact.html")]
-pub struct Contact;
+pub struct Contact {
+ pub title: String,
+ pub locale: Locale,
+}
#[derive(Template)]
#[template(path = "error.html")]
pub struct Error {
+ pub title: String,
pub status: StatusCode,
pub message: String,
+ // TODO: localize error page
}