···11-use crate::layout::layout;
22-use maud::html;
31use maudit::route::prelude::*;
4253#[route(
···97pub struct Contact;
108119impl Route for Contact {
1212- fn render(&self, _ctx: &mut PageContext) -> impl Into<RenderResult> {
1313- layout(html! {
1414- h1 { "Contact" }
1515- p { "This route demonstrates different locale syntaxes:" }
1616- p { "en uses prefix syntax, sv uses prefix syntax, de uses path syntax" }
1717- p { "Results: /en/contact, /sv/contact, /de/kontakt" }
1818- nav {
1919- ul {
2020- li { a href="/contact" { "Default" } }
2121- li { a href="/en/contact" { "English" } }
2222- li { a href="/sv/contact" { "Swedish" } }
2323- li { a href="/de/kontakt" { "German" } }
2424- }
2525- }
2626- })
1010+ fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
1111+ match &ctx.variant {
1212+ Some(language) => match language.as_str() {
1313+ "en" => "Contact us.",
1414+ "sv" => "Kontakta oss.",
1515+ "de" => "Kontaktieren Sie uns.",
1616+ _ => unreachable!(),
1717+ },
1818+ _ => "Contact us.",
1919+ }
2720 }
2821}
+8-3
examples/i18n/src/routes/index.rs
···1010 layout(html! {
1111 h1 { "i18n Example" }
1212 p { "This route only exists as variants - no base path!" }
1313+ p { "The current variant is: " (if let Some(variant) = &_ctx.variant {
1414+ variant
1515+ } else {
1616+ "none"
1717+ }) }
1318 nav {
1419 ul {
1515- li { a href="/en" { "English" } }
1616- li { a href="/sv" { "Swedish" } }
1717- li { a href="/de" { "German" } }
2020+ li { a href="/en/" { "English" } }
2121+ li { a href="/sv/" { "Swedish" } }
2222+ li { a href="/de/" { "German" } }
1823 }
1924 }
2025 })
-43
examples/i18n/src/routes/mixed.rs
···11-use crate::layout::layout;
22-use maud::html;
33-use maudit::route::prelude::*;
44-55-#[derive(Params, Clone)]
66-pub struct MixedParams {
77- pub id: String,
88-}
99-1010-// Base route is static (/products)
1111-// But variants have dynamic parameters (/en/products/[id])
1212-#[route(locales(en = "/en/products/[id]", sv = "/sv/produkter/[id]"))]
1313-pub struct Mixed;
1414-1515-impl Route<MixedParams> for Mixed {
1616- fn pages(&self, _ctx: &mut DynamicRouteContext) -> Pages<MixedParams> {
1717- vec![
1818- Page::from_params(MixedParams {
1919- id: "laptop".to_string(),
2020- }),
2121- Page::from_params(MixedParams {
2222- id: "phone".to_string(),
2323- }),
2424- ]
2525- }
2626-2727- fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
2828- let params = ctx.params::<MixedParams>();
2929-3030- layout(html! {
3131- h1 { "Product: " (params.id) }
3232- p { "This route has a static base path but dynamic variants!" }
3333- nav {
3434- ul {
3535- li { a href="/en/products/laptop" { "English - Laptop" } }
3636- li { a href="/en/products/phone" { "English - Phone" } }
3737- li { a href="/sv/produkter/laptop" { "Swedish - Laptop" } }
3838- li { a href="/sv/produkter/phone" { "Swedish - Phone" } }
3939- }
4040- }
4141- })
4242- }
4343-}
-2
examples/i18n/src/routes/mod.rs
···22mod articles;
33mod contact;
44mod index;
55-mod mixed;
6576pub use about::About;
87pub use articles::Article;
98pub use contact::Contact;
109pub use index::Index;
1111-pub use mixed::Mixed;
-15
examples/i18n/src/routes/wrong_order.rs.test
···11-use crate::layout::layout;
22-use maud::html;
33-use maudit::route::prelude::*;
44-55-// This should produce a compile error because path comes after locales
66-#[route(locales(en = "/en"), "/about")]
77-pub struct WrongOrder;
88-99-impl Route for WrongOrder {
1010- fn render(&self, _ctx: &mut PageContext) -> impl Into<RenderResult> {
1111- layout(html! {
1212- h1 { "This should not compile!" }
1313- })
1414- }
1515-}
+39
website/content/docs/routing.md
···159159 }
160160}
161161```
162162+163163+## Internationalization (i18n)
164164+165165+Maudit includes the ability to generate *variants* of pages based on locales. For instance, you may have a `/about` page and want to create a `/fr/about` or `/a-propos` page with a localized slug.
166166+167167+While you could do this by duplicating your `/about` page, creating a new struct, re-implementing Route etc etc, it would be quite time consuming if your website support more languages and probably lead to a lot of duplicated code, as your Swedish about page probably uses a lot of the same layout as your Danish one.
168168+169169+To create these variants, specify the named `locales` attribute on your route, after the path:
170170+171171+```rs
172172+use maudit::route::prelude::*;
173173+174174+#[route(
175175+ "/contact",
176176+ locales(sv(prefix = "/sv"), de(path = "/de/kontakt"))
177177+)]
178178+pub struct Contact;
179179+180180+impl Route for Contact {
181181+ fn render(&self, ctx: &mut PageContext) -> impl Into<RenderResult> {
182182+ match &ctx.variant {
183183+ Some(language) => match language.as_str() {
184184+ "sv" => "Kontakta oss.",
185185+ "de" => "Kontaktieren Sie uns.",
186186+ _ => unreachable!(),
187187+ },
188188+ _ => "Contact us.",
189189+ }
190190+ }
191191+}
192192+```
193193+194194+For this example, Maudit will generate three pages:
195195+196196+- `/contact`
197197+- `/sv/contact`
198198+- `/de/kontakt`
199199+200200+Calling `render()` three times with a different `ctx.variant` each time.