Setup leptop_i18n
This commit is contained in:
parent
09d1e72ac5
commit
2af602d8b1
11 changed files with 1056 additions and 77 deletions
871
Cargo.lock
generated
871
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
13
Cargo.toml
13
Cargo.toml
|
@ -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
6
locales/en.yaml
Normal 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
6
locales/eo.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
home: Hejmo
|
||||
available_in: "Havebla en:"
|
||||
partial_translations:
|
||||
|
||||
|
||||
tanguy_gerome:
|
6
locales/et.yaml
Normal file
6
locales/et.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
home: Kodu
|
||||
available_in: "Saadaval keeles:"
|
||||
partial_translations:
|
||||
|
||||
|
||||
tanguy_gerome:
|
6
locales/fi.yaml
Normal file
6
locales/fi.yaml
Normal 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
6
locales/fr.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
home: Accueil
|
||||
available_in: "Disponible en:"
|
||||
partial_translations: (traductions partielles)
|
||||
|
||||
|
||||
tanguy_gerome:
|
6
locales/jbo.yaml
Normal file
6
locales/jbo.yaml
Normal 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
6
locales/sv.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
home: Hem
|
||||
available_in: "Finns på:"
|
||||
partial_translations:
|
||||
|
||||
|
||||
tanguy_gerome:
|
94
src/app.rs
94
src/app.rs
|
@ -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>
|
||||
|
|
113
style/main.scss
113
style/main.scss
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue