Setup leptop_i18n

This commit is contained in:
Tanguy Gérôme 2024-10-22 17:46:53 +03:00
parent 09d1e72ac5
commit 2af602d8b1
11 changed files with 1056 additions and 77 deletions

871
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -20,9 +20,15 @@ wasm-bindgen = "=0.2.93"
thiserror = "1"
tracing = { version = "0.1", optional = true }
http = "1"
leptos_i18n = { version = "0.4.1", default-features = false, features = ["yaml_files"] }
[features]
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
hydrate = [
"leptos/hydrate",
"leptos_meta/hydrate",
"leptos_router/hydrate",
"leptos_i18n/hydrate",
]
ssr = [
"dep:axum",
"dep:tokio",
@ -33,8 +39,13 @@ ssr = [
"leptos_meta/ssr",
"leptos_router/ssr",
"dep:tracing",
"leptos_i18n/axum",
]
[package.metadata.leptos-i18n]
default = "en"
locales = ["en", "fr", "fi", "et", "sv", "eo", "jbo"]
# Defines a size-optimized profile for the WASM bundle in release mode
[profile.wasm-release]
inherits = "release"

6
locales/en.yaml Normal file
View file

@ -0,0 +1,6 @@
home: Home
available_in: "Available in:"
partial_translations: (partial translations)
tanguy_gerome: Tanguy Gérôme

6
locales/eo.yaml Normal file
View file

@ -0,0 +1,6 @@
home: Hejmo
available_in: "Havebla en:"
partial_translations:
tanguy_gerome:

6
locales/et.yaml Normal file
View file

@ -0,0 +1,6 @@
home: Kodu
available_in: "Saadaval keeles:"
partial_translations:
tanguy_gerome:

6
locales/fi.yaml Normal file
View file

@ -0,0 +1,6 @@
home: Koti
available_in: "Saatavilla kielillä:"
partial_translations: (keskeneräisiä käännöksiä)
tanguy_gerome:

6
locales/fr.yaml Normal file
View file

@ -0,0 +1,6 @@
home: Accueil
available_in: "Disponible en:"
partial_translations: (traductions partielles)
tanguy_gerome:

6
locales/jbo.yaml Normal file
View file

@ -0,0 +1,6 @@
home: zdani
available_in: "fanva fi "
partial_translations: (nalmu'o puvyfanva)
tanguy_gerome: .tangis.jerom.

6
locales/sv.yaml Normal file
View file

@ -0,0 +1,6 @@
home: Hem
available_in: "Finns på:"
partial_translations:
tanguy_gerome:

View file

@ -1,65 +1,99 @@
use crate::error_template::{AppError, ErrorTemplate};
leptos_i18n::load_locales!();
use i18n::*;
use leptos::*;
use leptos_meta::*;
use leptos_router::*;
use crate::error_template::{AppError, ErrorTemplate};
#[component]
pub fn App() -> impl IntoView {
// Provides context that manages stylesheets, titles, meta tags, etc.
provide_meta_context();
view! {
<I18nContextProvider>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<Stylesheet href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@100..900&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"/>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<Stylesheet href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@100..900&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"/>
// id=leptos means cargo-leptos will hot-reload this stylesheet
<Stylesheet id="leptos" href="/pkg/tanguy-gerome-fi.css"/>
// id=leptos means cargo-leptos will hot-reload this stylesheet
<Stylesheet id="leptos" href="/pkg/tanguy-gerome-fi.css"/>
<Title text="tanguy.gerome.fi"/>
<Title text="tanguy.gerome.fi"/>
<Router fallback=|| {
let mut outside_errors = Errors::default();
outside_errors.insert_with_default_key(AppError::NotFound);
view! {
<ErrorTemplate outside_errors/>
}
.into_view()
}>
<Header/>
<Routes>
<I18nRoute view=|| view! { <Outlet /> }>
<Route path="" view=HomePage/>
</I18nRoute>
</Routes>
<Footer/>
</Router>
</I18nContextProvider>
}
}
<Router fallback=|| {
let mut outside_errors = Errors::default();
outside_errors.insert_with_default_key(AppError::NotFound);
view! {
<ErrorTemplate outside_errors/>
}
.into_view()
}>
<Header/>
<Routes>
<Route path="" view=HomePage/>
</Routes>
<Footer/>
</Router>
#[component]
pub fn LanguageSwitcher() -> impl IntoView {
let i18n = use_i18n();
view! {
<div class="language-switcher main-width">
<p>{t!(i18n, available_in)}</p>
<button class="link" on:click=move |_| i18n.set_locale(Locale::en)>english</button>
<button class="link" on:click=move |_| i18n.set_locale(Locale::fr)>français</button>
<button class="link" on:click=move |_| i18n.set_locale(Locale::fi)>suomi</button>
<button class="link" on:click=move |_| i18n.set_locale(Locale::et)>eesti</button>
<button class="link" on:click=move |_| i18n.set_locale(Locale::sv)>svenska</button>
<button class="link" on:click=move |_| i18n.set_locale(Locale::eo)>esperanto</button>
<button class="link" on:click=move |_| i18n.set_locale(Locale::jbo)>lojban</button>
<p>{t!(i18n, partial_translations)}</p>
</div>
}
}
#[component]
fn Header() -> impl IntoView {
let i18n = use_i18n();
view! {
<header>
<div class="text">
<h1><span>tanguy</span><wbr/><span>.gerome</span><span>.fi</span></h1>
<div class="links">
<div class="title-links-and-banner">
<div class="text">
<h1><span>tanguy</span><wbr/><span>.gerome</span><span>.fi</span></h1>
<div class="links">
<A href="/">{t!(i18n, home)}</A>
</div>
</div>
<img
class="image"
src="https://images.ctfassets.net/e3magj9g6dp1/14q5L7K0BCol1gx0aCSCck/d1f69bfa404efed6a2dcc71401bbc16d/P5310039-1-2.jpg?w=2000&q=90&fm=avif"
alt=""
/>
</div>
<img
class="image"
src="https://images.ctfassets.net/e3magj9g6dp1/14q5L7K0BCol1gx0aCSCck/d1f69bfa404efed6a2dcc71401bbc16d/P5310039-1-2.jpg?w=2000&q=90&fm=avif"
alt=""
/>
<LanguageSwitcher/>
</header>
}
}
#[component]
fn Footer() -> impl IntoView {
let i18n = use_i18n();
view! {
<footer>
<div class="name-and-links main-width">
<span class="name">Tanguy Gérôme</span>
<span class="name">{t!(i18n, tanguy_gerome)}</span>
<div class="links">
<a href="https://www.instagram.com/kapno.cc/" target="_blank" rel="noopener noreferrer">instagram @kapno.cc</a>
<a href="https://github.com/kapnoc" target="_blank" rel="noopener noreferrer">github @kapnoc</a>

View file

@ -1,4 +1,4 @@
$mainGreen: #2E7D32;
$mainGreen: darken(#2E7D32, 10);
$mainGrey: #0F0F0F;
@mixin top-level-padding {
@ -12,6 +12,19 @@ $mainGrey: #0F0F0F;
box-sizing: border-box;
}
button {
&.link {
all: unset;
text-decoration: underline;
color: $mainGreen!important;
cursor: pointer;
}
}
a {
color: $mainGreen!important;
}
body {
font-family: 'Ubuntu', sans-serif;
text-align: left;
@ -44,62 +57,91 @@ body {
h4 { font-size: 18px; }
header {
background: $mainGrey;
color: white;
width: 100%;
display: flex;
flex-direction: row;
flex-direction: column;
align-items: center;
justify-content: center;
@media all and (max-width: 2000px) {
justify-content: flex-end;
}
@media all and (max-width: 800px) {
flex-direction: column;
align-items: stretch;
}
.text {
@include top-level-padding;
flex-basis: auto;
flex-shrink: 0;
flex-grow: 1;
.title-links-and-banner {
background: $mainGrey;
color: white;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 16px;
h1 {
display: flex;
flex-direction: column;
align-items: flex-start;
@media all and (max-width: 2000px) {
justify-content: flex-end;
}
.links {
display: flex;
@media all and (max-width: 800px) {
flex-direction: column;
align-items: flex-end;
align-items: stretch;
}
.text {
@include top-level-padding;
flex-basis: auto;
flex-shrink: 0;
flex-grow: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 16px;
h1 {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.links {
display: flex;
flex-direction: column;
align-items: flex-end;
a {
color: white!important;
}
}
}
.image {
max-width: 800px;
width: 100%;
max-height: 300px;
height: 100%;
object-fit: cover;
object-position: top;
flex-shrink: 1;
}
}
.image {
max-width: 800px;
width: 100%;
max-height: 300px;
height: 100%;
object-fit: cover;
object-position: top;
flex-shrink: 1;
.language-switcher {
@include top-level-padding;
margin: 16px 0;
gap: 8px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
p {
margin: 0;
}
}
}
main {
@include top-level-padding;
margin-bottom: 32px;
}
footer {
@ -145,7 +187,6 @@ body {
a {
color: white!important;
text-decoration: unset;
}
}
}