parent.",
9 | "all": "Cette section est inversé, a son cookie, et met l'attribut \"lang\".",
10 | "main": "Ce compteur utilise le context principal."
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/csr/subcontext/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "subcontext",
3 | "version": "1.0.0",
4 | "description": "This example showcase how you can introduce subcontexts in you application.",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "trunk build",
8 | "start": "trunk serve --no-autoreload",
9 | "watch": "trunk serve",
10 | "test": "npx playwright test",
11 | "prestart": "npm run build",
12 | "pretest": "npm run build"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@playwright/test": "^1.45.3",
19 | "@types/node": "^20.14.12"
20 | },
21 | "imports": {
22 | "#locales/*": "./locales/*"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/csr/subcontext/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/csr/subcontext/public/favicon.ico
--------------------------------------------------------------------------------
/examples/csr/subcontext/src/main.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | leptos_i18n::load_locales!();
5 |
6 | fn main() {
7 | use app::App;
8 | console_error_panic_hook::set_once();
9 | leptos::mount::mount_to_body(|| leptos::view! {
})
10 | }
11 |
--------------------------------------------------------------------------------
/examples/csr/subcontext/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/csr/subcontext/style/main.scss
--------------------------------------------------------------------------------
/examples/csr/subkeys/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | dist
4 | !.vscode
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
10 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/csr/subkeys/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/csr/subkeys/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "subkeys"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | leptos = { version = "0.7.0", features = ["csr"] }
10 | leptos_meta = { version = "0.7.0" }
11 | leptos_i18n = { path = "../../../leptos_i18n", features = ["csr"] }
12 | serde = { version = "1", features = ["derive"] }
13 | console_error_panic_hook = { version = "0.1" }
14 | wasm-bindgen = { version = "0.2" }
15 |
16 | [package.metadata.leptos-i18n]
17 | default = "en"
18 | locales = ["en", "fr"]
19 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/README.md:
--------------------------------------------------------------------------------
1 | # Subkeys Example
2 |
3 | This example showcase how you can use subkeys.
4 |
5 | ## How to run
6 |
7 | Simply use `trunk` to run it:
8 |
9 | ```bash
10 | trunk serve --open
11 | ```
12 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Click to change language",
3 | "subkeys": {
4 | "subkey": "subkeys subkey english",
5 | "subsubkeys": {
6 | "subsubkey": "subkeys subsubkeys subsubkey english"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Cliquez pour changez de langue",
3 | "subkeys": {
4 | "subkey": "subkeys subkey french",
5 | "subsubkeys": {
6 | "subsubkey": "subkeys subsubkeys subsubkey french"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "subkeys",
3 | "version": "1.0.0",
4 | "description": "This example showcase how you can use subkeys.",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "trunk build",
8 | "start": "trunk serve --no-autoreload",
9 | "watch": "trunk serve",
10 | "test": "npx playwright test",
11 | "prestart": "npm run build",
12 | "pretest": "npm run build"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@playwright/test": "^1.45.3",
19 | "@types/node": "^20.14.12"
20 | },
21 | "imports": {
22 | "#locales/*": "./locales/*"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/csr/subkeys/public/favicon.ico
--------------------------------------------------------------------------------
/examples/csr/subkeys/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 |
14 | }
15 | }
16 |
17 | #[component]
18 | #[allow(non_snake_case)]
19 | pub fn SwitchLang() -> impl IntoView {
20 | let i18n = use_i18n();
21 |
22 | let on_switch = move |_| {
23 | let new_lang = match i18n.get_locale() {
24 | Locale::en => Locale::fr,
25 | Locale::fr => Locale::en,
26 | };
27 | i18n.set_locale(new_lang);
28 | };
29 |
30 | view! {
31 |
{t!(i18n, click_to_change_lang)}
32 | }
33 | }
34 |
35 | #[component]
36 | #[allow(non_snake_case)]
37 | fn Subkeys() -> impl IntoView {
38 | let i18n = use_i18n_scoped!(subkeys);
39 |
40 | view! {
41 |
{t!(i18n, subkey)}
42 |
{t!(i18n, subsubkeys.subsubkey)}
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/src/main.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | leptos_i18n::load_locales!();
5 |
6 | fn main() {
7 | use app::App;
8 | console_error_panic_hook::set_once();
9 | leptos::mount::mount_to_body(|| leptos::view! {
});
10 | }
11 |
--------------------------------------------------------------------------------
/examples/csr/subkeys/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/csr/subkeys/style/main.scss
--------------------------------------------------------------------------------
/examples/csr/yaml/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | dist
4 | !.vscode
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
10 |
--------------------------------------------------------------------------------
/examples/csr/yaml/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/csr/yaml/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/csr/yaml/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/csr/yaml/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "yaml"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | leptos = { version = "0.7.0", features = ["csr"] }
10 | leptos_meta = { version = "0.7.0" }
11 | leptos_i18n = { path = "../../../leptos_i18n", default-features = false, features = [
12 | "csr",
13 | "cookie",
14 | "yaml_files",
15 | "icu_compiled_data",
16 | ] }
17 | serde = { version = "1", features = ["derive"] }
18 | console_error_panic_hook = { version = "0.1" }
19 | wasm-bindgen = { version = "0.2" }
20 |
21 | [package.metadata.leptos-i18n]
22 | default = "en"
23 | locales = ["en", "fr"]
24 |
--------------------------------------------------------------------------------
/examples/csr/yaml/README.md:
--------------------------------------------------------------------------------
1 | # YAML Example
2 |
3 | This example showcase how you can use the YAML format for declaring your locales
4 |
5 | ## How to run
6 |
7 | Simply use `trunk` to run it:
8 |
9 | ```bash
10 | trunk serve --open
11 | ```
12 |
--------------------------------------------------------------------------------
/examples/csr/yaml/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/csr/yaml/locales/en.yaml:
--------------------------------------------------------------------------------
1 | click_to_change_lang: "Click to change language"
2 | click_to_inc: "Click to increment the counter"
3 | click_count:
4 | - "u64"
5 | - ["You did not clicked yet", 0]
6 | - ["You clicked once", 1]
7 | - ["You clicked {{ count }} times"]
8 | subkeys:
9 | subkey: "subkey"
10 | sub_subkeys:
11 | sub_sbkey: "sub_subkey"
12 |
--------------------------------------------------------------------------------
/examples/csr/yaml/locales/fr.yaml:
--------------------------------------------------------------------------------
1 | click_to_change_lang: "Cliquez pour changez de langue"
2 | click_count: "Vous avez cliqué {{ count }} fois"
3 | click_to_inc: "Cliquez pour incrémenter le compteur"
4 | subkeys:
5 | subkey: "subkey fr"
6 | sub_subkeys:
7 | sub_sbkey: "sub_subkey fr"
8 |
--------------------------------------------------------------------------------
/examples/csr/yaml/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yaml",
3 | "version": "1.0.0",
4 | "description": "This example showcase how you can use the YAML format for declaring your locales",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "trunk build",
8 | "start": "trunk serve --no-autoreload",
9 | "watch": "trunk serve",
10 | "test": "npx playwright test",
11 | "prestart": "npm run build",
12 | "pretest": "npm run build"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@playwright/test": "^1.45.3",
19 | "@types/node": "^20.14.12",
20 | "yaml": "^2.5.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/csr/yaml/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/csr/yaml/public/favicon.ico
--------------------------------------------------------------------------------
/examples/csr/yaml/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 |
14 | }
15 | }
16 |
17 | #[component]
18 | #[allow(non_snake_case)]
19 | pub fn SwitchLang() -> impl IntoView {
20 | let i18n = use_i18n();
21 |
22 | let on_switch = move |_| {
23 | let new_lang = match i18n.get_locale() {
24 | Locale::en => Locale::fr,
25 | Locale::fr => Locale::en,
26 | };
27 | i18n.set_locale(new_lang);
28 | };
29 |
30 | view! {
31 |
{t!(i18n, click_to_change_lang)}
32 | }
33 | }
34 |
35 | #[component]
36 | #[allow(non_snake_case)]
37 | fn Counter() -> impl IntoView {
38 | let i18n = use_i18n();
39 |
40 | let (counter, set_counter) = signal(0u64);
41 |
42 | let inc = move |_| set_counter.update(|count| *count += 1);
43 |
44 | let count = move || counter.get();
45 |
46 | view! {
47 |
{t!(i18n, click_count, count = count)}
48 |
{t!(i18n, click_to_inc)}
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/examples/csr/yaml/src/main.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | leptos_i18n::load_locales!();
5 |
6 | fn main() {
7 | use app::App;
8 | console_error_panic_hook::set_once();
9 | leptos::mount::mount_to_body(|| leptos::view! {
});
10 | }
11 |
--------------------------------------------------------------------------------
/examples/csr/yaml/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/csr/yaml/style/main.scss
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to use `leptos_i18n` with experimental `island` feature from Leptos.
4 |
5 | ## How to run
6 |
7 | Simply use `cargo_leptos` to run it:
8 |
9 | ```sh
10 | cargo leptos watch
11 | ```
12 |
13 | and to build:
14 |
15 | ```sh
16 | cargo leptos build --release
17 | ```
18 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language",
4 | "click_count": "You clicked
{{ count }} times",
5 | "click_to_inc": "Click to increment the counter"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue",
4 | "click_count": "Vous avez cliqué
{{ count }} fois",
5 | "click_to_inc": "Cliquez pour incrémenter le compteur"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "axum_island",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to use `leptos_i18n` with experimental `island` feature from Leptos.",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/axum_island/public/favicon.ico
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | view! {
8 |
9 |
10 | {ti!(HelloWorld, hello_world)}
11 |
12 |
13 |
14 |
15 | }
16 | }
17 |
18 | #[island]
19 | #[allow(non_snake_case)]
20 | fn Counter() -> impl IntoView {
21 | let i18n = use_i18n();
22 |
23 | let (counter, set_counter) = signal(0);
24 |
25 | let inc = move |_| set_counter.update(|count| *count += 1);
26 |
27 | let count = move || counter.get();
28 |
29 | view! {
30 |
31 | {t!{
32 | i18n,
33 | click_count,
34 | count,
35 | = ,
36 | }}
37 |
38 |
{t!(i18n, click_to_inc)}
39 | }
40 | }
41 |
42 | #[island]
43 | #[allow(non_snake_case)]
44 | fn ChangeLang() -> impl IntoView {
45 | let i18n = use_i18n();
46 |
47 | let on_switch = move |_| {
48 | let new_lang = match i18n.get_locale() {
49 | Locale::en => Locale::fr,
50 | Locale::fr => Locale::en,
51 | };
52 | i18n.set_locale(new_lang);
53 | };
54 |
55 | view! {
56 |
{t!(i18n, click_to_change_lang)}
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 |
5 | leptos_i18n::load_locales!();
6 |
7 | #[cfg(feature = "hydrate")]
8 | #[wasm_bindgen::prelude::wasm_bindgen]
9 | pub fn hydrate() {
10 | console_error_panic_hook::set_once();
11 | leptos::mount::hydrate_islands();
12 | }
13 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::Router;
2 | use axum_island::app::App;
3 | use leptos::prelude::*;
4 | use leptos_axum::{generate_route_list, LeptosRoutes};
5 |
6 | #[tokio::main]
7 | async fn main() {
8 | // Setting this to None means we'll be using cargo-leptos and its env vars
9 | let conf = get_configuration(None).unwrap();
10 | let leptos_options = conf.leptos_options;
11 | let addr = leptos_options.site_addr;
12 | let routes = generate_route_list(App);
13 |
14 | // build our application with a route
15 | let app = Router::new()
16 | .leptos_routes(&leptos_options, routes, {
17 | let leptos_options = leptos_options.clone();
18 | move || shell(leptos_options.clone())
19 | })
20 | .fallback(leptos_axum::file_and_error_handler(shell))
21 | .with_state(leptos_options);
22 |
23 | // run our app with hyper
24 | // `axum::Server` is a re-export of `hyper::Server`
25 | let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
26 | println!("listening on http://{}", &addr);
27 | axum::serve(listener, app.into_make_service())
28 | .await
29 | .unwrap();
30 | }
31 |
32 | pub fn shell(options: LeptosOptions) -> impl IntoView {
33 | view! {
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/examples/dynamic_load/axum_island/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/axum_island/style/main.scss
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | dist
4 | !.vscode
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
10 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales",
4 | "rust-analyzer.cargo.buildScripts.enable": true
5 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "csr_counter"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | leptos = { version = "0.7.0", features = ["csr"] }
8 | leptos_i18n = { path = "../../../leptos_i18n", features = [
9 | "csr",
10 | "plurals",
11 | "dynamic_load",
12 | "track_locale_files",
13 | ] }
14 | console_error_panic_hook = { version = "0.1" }
15 |
16 | [package.metadata.leptos-i18n]
17 | default = "en"
18 | locales = ["en", "fr"]
19 | translations-path = "i18n/{locale}.json"
20 |
21 | [build-dependencies]
22 | leptos_i18n_build = { path = "../../../leptos_i18n_build" }
23 |
24 | [profile.release]
25 | opt-level = "z"
26 | lto = true
27 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Load CSR Counter Example
2 |
3 | This example showcase how you can use dynamic load with CSR.
4 |
5 | ## How to run
6 |
7 | Simply use `trunk` to run it:
8 |
9 | ```bash
10 | trunk serve --open
11 | ```
12 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/build.rs:
--------------------------------------------------------------------------------
1 | use leptos_i18n_build::TranslationsInfos;
2 |
3 | fn main() {
4 | println!("cargo:rerun-if-changed=build.rs");
5 | println!("cargo:rerun-if-changed=Cargo.toml");
6 |
7 | let translations_infos = TranslationsInfos::parse().unwrap();
8 |
9 | translations_infos.rerun_if_locales_changed();
10 |
11 | translations_infos
12 | .get_translations()
13 | .write_to_dir("./target/i18n")
14 | .unwrap();
15 | }
16 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Click to change language",
3 | "click_count_one": "You clicked {{ count }} time",
4 | "click_count_other": "You clicked {{ count }} times",
5 | "click_to_inc": "Click to increment the counter"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Cliquez pour changez de langue",
3 | "click_count_one": "Vous avez fait {{ count }} clique",
4 | "click_count_other": "Vous avez fait {{ count }} cliques",
5 | "click_to_inc": "Cliquez pour incrémenter le compteur"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "csr_counter",
3 | "version": "1.0.0",
4 | "description": "This example showcase how you can use dynamic load with CSR.",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "trunk build",
8 | "start": "trunk serve --no-autoreload",
9 | "watch": "trunk serve",
10 | "test": "npx playwright test",
11 | "prestart": "npm run build",
12 | "pretest": "npm run build"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@playwright/test": "^1.45.3",
19 | "@types/node": "^20.14.12"
20 | },
21 | "imports": {
22 | "#locales/*": "./locales/*"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/csr_counter/public/favicon.ico
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | view! {
8 |
9 |
10 |
11 |
12 | }
13 | }
14 |
15 | #[component]
16 | #[allow(non_snake_case)]
17 | pub fn SwitchLang() -> impl IntoView {
18 | let i18n = use_i18n();
19 |
20 | let on_switch = move |_| {
21 | let new_lang = match i18n.get_locale() {
22 | Locale::en => Locale::fr,
23 | Locale::fr => Locale::en,
24 | };
25 | i18n.set_locale(new_lang);
26 | };
27 |
28 | view! {
29 | {t!(i18n, click_to_change_lang)}
30 | }
31 | }
32 |
33 | #[component]
34 | #[allow(non_snake_case)]
35 | fn Counter() -> impl IntoView {
36 | let i18n = use_i18n();
37 |
38 | let (counter, set_counter) = signal(0);
39 |
40 | let inc = move |_| set_counter.update(|count| *count += 1);
41 |
42 | let count = move || counter.get();
43 |
44 | view! {
45 | {t!(i18n, click_count, count = count)}
46 | {t!(i18n, click_to_inc)}
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/src/main.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | leptos_i18n::load_locales!();
5 |
6 | fn main() {
7 | use app::App;
8 | console_error_panic_hook::set_once();
9 | leptos::mount::mount_to_body(|| leptos::view! { })
10 | }
11 |
--------------------------------------------------------------------------------
/examples/dynamic_load/csr_counter/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/csr_counter/style/main.scss
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to setup the files to use `leptos_i18n` and easily introduce translations in you application.
4 |
5 | This example use the `actix` backend, but all the code in relation to `leptos_i18n` would be the same using `axum`.
6 |
7 | Check the `axum` Hello World example to compare.
8 |
9 | ## How to run
10 |
11 | Simply use `cargo_leptos` to run it:
12 |
13 | ```sh
14 | cargo leptos watch
15 | ```
16 |
17 | and to build:
18 |
19 | ```sh
20 | cargo leptos build --release
21 | ```
22 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello_world_actix",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to implement a basic hello world with Leptos and Actix",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/hello_world_actix/public/favicon.ico
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 | }
14 | }
15 |
16 | #[component]
17 | #[allow(non_snake_case)]
18 | pub fn Home() -> impl IntoView {
19 | let i18n = use_i18n();
20 |
21 | let on_switch = move |_| {
22 | let new_lang = match i18n.get_locale() {
23 | Locale::en => Locale::fr,
24 | Locale::fr => Locale::en,
25 | };
26 | i18n.set_locale(new_lang);
27 | };
28 |
29 | view! {
30 | {t!(i18n, hello_world)}
31 | {t!(i18n, click_to_change_lang)}
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 |
5 | leptos_i18n::load_locales!();
6 |
7 | #[cfg(feature = "hydrate")]
8 | #[wasm_bindgen::prelude::wasm_bindgen]
9 | pub fn hydrate() {
10 | use app::App;
11 | console_error_panic_hook::set_once();
12 | leptos::mount::hydrate_body(App);
13 | }
14 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_actix/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/hello_world_actix/style/main.scss
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to setup the files to use `leptos_i18n` and easily introduce translations in you application.
4 |
5 | This example use the `axum` backend, but all the code in relation to `leptos_i18n` would be the same using `actix`.
6 |
7 | Check the `actix` Hello World example to compare.
8 |
9 | ## How to run
10 |
11 | Simply use `cargo_leptos` to run it:
12 |
13 | ```sh
14 | cargo leptos watch
15 | ```
16 |
17 | and to build:
18 |
19 | ```sh
20 | cargo leptos build --release
21 | ```
22 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language",
4 | "click_count": "You clicked {{ count }} times",
5 | "click_to_inc": "Click to increment the counter"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue",
4 | "click_count": "Vous avez cliqué {{ count }} fois",
5 | "click_to_inc": "Cliquez pour incrémenter le compteur"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello_world_axum",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to implement a basic hello world with Leptos and Axum",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/hello_world_axum/public/favicon.ico
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 | }
14 | }
15 |
16 | #[component]
17 | #[allow(non_snake_case)]
18 | pub fn Home() -> impl IntoView {
19 | let i18n = use_i18n();
20 |
21 | let (counter, set_counter) = signal(0);
22 |
23 | let inc = move |_| set_counter.update(|count| *count += 1);
24 |
25 | let on_switch = move |_| {
26 | let new_lang = match i18n.get_locale() {
27 | Locale::en => Locale::fr,
28 | Locale::fr => Locale::en,
29 | };
30 | i18n.set_locale(new_lang);
31 | };
32 |
33 | let count = move || counter.get();
34 |
35 | view! {
36 | {t!(i18n, hello_world)}
37 | {t!(i18n, click_to_change_lang)}
38 |
39 | {t!{ i18n,
40 | click_count,
41 | count,
42 | = ,
43 | }}
44 |
45 | {t!(i18n, click_to_inc)}
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/src/fileserv.rs:
--------------------------------------------------------------------------------
1 | use crate::app::App;
2 | use axum::response::Response as AxumResponse;
3 | use axum::{
4 | body::Body,
5 | extract::State,
6 | http::{Request, Response, StatusCode, Uri},
7 | response::IntoResponse,
8 | };
9 | use leptos::prelude::*;
10 | use tower::ServiceExt;
11 | use tower_http::services::{fs::ServeFileSystemResponseBody, ServeDir};
12 |
13 | pub async fn file_and_error_handler(
14 | uri: Uri,
15 | State(options): State,
16 | req: Request,
17 | ) -> AxumResponse {
18 | let root = options.site_root.clone();
19 | let res = get_static_file(uri.clone(), &root).await.unwrap();
20 |
21 | if res.status() == StatusCode::OK {
22 | res.into_response()
23 | } else {
24 | let handler = leptos_axum::render_app_to_stream(App);
25 | handler(req).await.into_response()
26 | }
27 | }
28 |
29 | async fn get_static_file(
30 | uri: Uri,
31 | root: &str,
32 | ) -> Result, (StatusCode, String)> {
33 | let req = Request::builder()
34 | .uri(uri.clone())
35 | .body(Body::empty())
36 | .unwrap();
37 | // `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
38 | // This path is relative to the cargo root
39 | ServeDir::new(root).oneshot(req).await.map_err(|err| {
40 | (
41 | StatusCode::INTERNAL_SERVER_ERROR,
42 | format!("Something went wrong: {err}"),
43 | )
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | #[cfg(feature = "ssr")]
5 | pub mod fileserv;
6 |
7 | leptos_i18n::load_locales!();
8 |
9 | #[cfg(feature = "hydrate")]
10 | #[wasm_bindgen::prelude::wasm_bindgen]
11 | pub fn hydrate() {
12 | use app::App;
13 | console_error_panic_hook::set_once();
14 | leptos::mount::hydrate_body(App);
15 | }
16 |
--------------------------------------------------------------------------------
/examples/dynamic_load/hello_world_axum/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/hello_world_axum/style/main.scss
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to setup the files to use `leptos_i18n` and easily introduce translations in you application.
4 |
5 | This example use the `axum` backend, but all the code in relation to `leptos_i18n` would be the same using `actix`.
6 |
7 | Check the `actix` Hello World example to compare.
8 |
9 | ## How to run
10 |
11 | Simply use `cargo_leptos` to run it:
12 |
13 | ```sh
14 | cargo leptos watch
15 | ```
16 |
17 | and to build:
18 |
19 | ```sh
20 | cargo leptos build --release
21 | ```
22 |
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/locales/en/change_locale.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Click to change language"
3 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/locales/en/counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_count": "You clicked {{ count }} times",
3 | "click_to_inc": "Click to increment the counter"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/locales/fr/change_locale.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Cliquez pour changez de langue"
3 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/locales/fr/counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_count": "Vous avez cliqué {{ count }} fois",
3 | "click_to_inc": "Cliquez pour incrémenter le compteur"
4 | }
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello_world_axum",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to implement a basic hello world with Leptos and Axum",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/namespaces/public/favicon.ico
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 |
14 | }
15 | }
16 |
17 | #[component]
18 | #[allow(non_snake_case)]
19 | pub fn SwitchLang() -> impl IntoView {
20 | let i18n = use_i18n();
21 |
22 | let on_switch = move |_| {
23 | let new_lang = match i18n.get_locale() {
24 | Locale::en => Locale::fr,
25 | Locale::fr => Locale::en,
26 | };
27 | i18n.set_locale(new_lang);
28 | };
29 |
30 | view! {
31 | {t!(i18n, change_locale.click_to_change_lang)}
32 | }
33 | }
34 |
35 | #[component]
36 | #[allow(non_snake_case)]
37 | fn Counter() -> impl IntoView {
38 | let i18n = use_i18n();
39 |
40 | let (counter, set_counter) = signal(0);
41 |
42 | let inc = move |_| set_counter.update(|count| *count += 1);
43 |
44 | let count = move || counter.get();
45 |
46 | view! {
47 | {t!(i18n, counter.click_count, count)}
48 | {t!(i18n, counter.click_to_inc)}
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/src/fileserv.rs:
--------------------------------------------------------------------------------
1 | use crate::app::App;
2 | use axum::response::Response as AxumResponse;
3 | use axum::{
4 | body::Body,
5 | extract::State,
6 | http::{Request, Response, StatusCode, Uri},
7 | response::IntoResponse,
8 | };
9 | use leptos::prelude::*;
10 | use tower::ServiceExt;
11 | use tower_http::services::{fs::ServeFileSystemResponseBody, ServeDir};
12 |
13 | pub async fn file_and_error_handler(
14 | uri: Uri,
15 | State(options): State,
16 | req: Request,
17 | ) -> AxumResponse {
18 | let root = options.site_root.clone();
19 | let res = get_static_file(uri.clone(), &root).await.unwrap();
20 |
21 | if res.status() == StatusCode::OK {
22 | res.into_response()
23 | } else {
24 | let handler = leptos_axum::render_app_to_stream(App);
25 | handler(req).await.into_response()
26 | }
27 | }
28 |
29 | async fn get_static_file(
30 | uri: Uri,
31 | root: &str,
32 | ) -> Result, (StatusCode, String)> {
33 | let req = Request::builder()
34 | .uri(uri.clone())
35 | .body(Body::empty())
36 | .unwrap();
37 | // `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
38 | // This path is relative to the cargo root
39 | ServeDir::new(root).oneshot(req).await.map_err(|err| {
40 | (
41 | StatusCode::INTERNAL_SERVER_ERROR,
42 | format!("Something went wrong: {err}"),
43 | )
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | #[cfg(feature = "ssr")]
5 | pub mod fileserv;
6 |
7 | leptos_i18n::load_locales!();
8 |
9 | #[cfg(feature = "hydrate")]
10 | #[wasm_bindgen::prelude::wasm_bindgen]
11 | pub fn hydrate() {
12 | use app::App;
13 | console_error_panic_hook::set_once();
14 | leptos::mount::hydrate_body(App);
15 | }
16 |
--------------------------------------------------------------------------------
/examples/dynamic_load/namespaces/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/dynamic_load/namespaces/style/main.scss
--------------------------------------------------------------------------------
/examples/ssr/axum_island/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/ssr/axum_island/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/ssr/axum_island/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/axum_island/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to use `leptos_i18n` with experimental `island` feature from Leptos.
4 |
5 | ## How to run
6 |
7 | Simply use `cargo_leptos` to run it:
8 |
9 | ```sh
10 | cargo leptos watch
11 | ```
12 |
13 | and to build:
14 |
15 | ```sh
16 | cargo leptos build --release
17 | ```
18 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language",
4 | "click_count": "You clicked {{ count }} times",
5 | "click_to_inc": "Click to increment the counter"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue",
4 | "click_count": "Vous avez cliqué {{ count }} fois",
5 | "click_to_inc": "Cliquez pour incrémenter le compteur"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "axum_island",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to use `leptos_i18n` with experimental `island` feature from Leptos.",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/axum_island/public/favicon.ico
--------------------------------------------------------------------------------
/examples/ssr/axum_island/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | view! {
8 |
9 |
10 | {ti!(HelloWorld, hello_world)}
11 |
12 |
13 |
14 |
15 | }
16 | }
17 |
18 | #[island]
19 | #[allow(non_snake_case)]
20 | fn Counter() -> impl IntoView {
21 | let i18n = use_i18n();
22 |
23 | let (counter, set_counter) = signal(0);
24 |
25 | let inc = move |_| set_counter.update(|count| *count += 1);
26 |
27 | let count = move || counter.get();
28 |
29 | view! {
30 |
31 | {t!{
32 | i18n,
33 | click_count,
34 | count,
35 | = ,
36 | }}
37 |
38 | {t!(i18n, click_to_inc)}
39 | }
40 | }
41 |
42 | #[island]
43 | #[allow(non_snake_case)]
44 | fn ChangeLang() -> impl IntoView {
45 | let i18n = use_i18n();
46 |
47 | let on_switch = move |_| {
48 | let new_lang = match i18n.get_locale() {
49 | Locale::en => Locale::fr,
50 | Locale::fr => Locale::en,
51 | };
52 | i18n.set_locale(new_lang);
53 | };
54 |
55 | view! {
56 | {t!(i18n, click_to_change_lang)}
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 |
5 | leptos_i18n::load_locales!();
6 |
7 | #[cfg(feature = "hydrate")]
8 | #[wasm_bindgen::prelude::wasm_bindgen]
9 | pub fn hydrate() {
10 | console_error_panic_hook::set_once();
11 | leptos::mount::hydrate_islands();
12 | }
13 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/src/main.rs:
--------------------------------------------------------------------------------
1 | use axum::Router;
2 | use axum_island::app::App;
3 | use leptos::prelude::*;
4 | use leptos_axum::{generate_route_list, LeptosRoutes};
5 |
6 | #[tokio::main]
7 | async fn main() {
8 | // Setting this to None means we'll be using cargo-leptos and its env vars
9 | let conf = get_configuration(None).unwrap();
10 | let leptos_options = conf.leptos_options;
11 | let addr = leptos_options.site_addr;
12 | let routes = generate_route_list(App);
13 |
14 | // build our application with a route
15 | let app = Router::new()
16 | .leptos_routes(&leptos_options, routes, {
17 | let leptos_options = leptos_options.clone();
18 | move || shell(leptos_options.clone())
19 | })
20 | .fallback(leptos_axum::file_and_error_handler(shell))
21 | .with_state(leptos_options);
22 |
23 | // run our app with hyper
24 | // `axum::Server` is a re-export of `hyper::Server`
25 | let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
26 | println!("listening on http://{}", &addr);
27 | axum::serve(listener, app.into_make_service())
28 | .await
29 | .unwrap();
30 | }
31 |
32 | pub fn shell(options: LeptosOptions) -> impl IntoView {
33 | view! {
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/examples/ssr/axum_island/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/axum_island/style/main.scss
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to setup the files to use `leptos_i18n` and easily introduce translations in you application.
4 |
5 | This example use the `actix` backend, but all the code in relation to `leptos_i18n` would be the same using `axum`.
6 |
7 | Check the `axum` Hello World example to compare.
8 |
9 | ## How to run
10 |
11 | Simply use `cargo_leptos` to run it:
12 |
13 | ```sh
14 | cargo leptos watch
15 | ```
16 |
17 | and to build:
18 |
19 | ```sh
20 | cargo leptos build --release
21 | ```
22 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello_world_actix",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to implement a basic hello world with Leptos and Actix",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/hello_world_actix/public/favicon.ico
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 | }
14 | }
15 |
16 | #[component]
17 | #[allow(non_snake_case)]
18 | pub fn Home() -> impl IntoView {
19 | let i18n = use_i18n();
20 |
21 | let on_switch = move |_| {
22 | let new_lang = match i18n.get_locale() {
23 | Locale::en => Locale::fr,
24 | Locale::fr => Locale::en,
25 | };
26 | i18n.set_locale(new_lang);
27 | };
28 |
29 | view! {
30 | {t!(i18n, hello_world)}
31 | {t!(i18n, click_to_change_lang)}
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 |
5 | leptos_i18n::load_locales!();
6 |
7 | #[cfg(feature = "hydrate")]
8 | #[wasm_bindgen::prelude::wasm_bindgen]
9 | pub fn hydrate() {
10 | use app::App;
11 | console_error_panic_hook::set_once();
12 | leptos::mount::hydrate_body(App);
13 | }
14 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_actix/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/hello_world_actix/style/main.scss
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/README.md:
--------------------------------------------------------------------------------
1 | # Hello World Example
2 |
3 | This example showcase how to setup the files to use `leptos_i18n` and easily introduce translations in you application.
4 |
5 | This example use the `axum` backend, but all the code in relation to `leptos_i18n` would be the same using `actix`.
6 |
7 | Check the `actix` Hello World example to compare.
8 |
9 | ## How to run
10 |
11 | Simply use `cargo_leptos` to run it:
12 |
13 | ```sh
14 | cargo leptos watch
15 | ```
16 |
17 | and to build:
18 |
19 | ```sh
20 | cargo leptos build --release
21 | ```
22 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language",
4 | "click_count": "You clicked {{ count }} times",
5 | "click_to_inc": "Click to increment the counter"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue",
4 | "click_count": "Vous avez cliqué {{ count }} fois",
5 | "click_to_inc": "Cliquez pour incrémenter le compteur"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello_world_axum",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to implement a basic hello world with Leptos and Axum",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/hello_world_axum/public/favicon.ico
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 | }
14 | }
15 |
16 | #[component]
17 | #[allow(non_snake_case)]
18 | pub fn Home() -> impl IntoView {
19 | let i18n = use_i18n();
20 |
21 | let (counter, set_counter) = signal(0);
22 |
23 | let inc = move |_| set_counter.update(|count| *count += 1);
24 |
25 | let on_switch = move |_| {
26 | let new_lang = match i18n.get_locale() {
27 | Locale::en => Locale::fr,
28 | Locale::fr => Locale::en,
29 | };
30 | i18n.set_locale(new_lang);
31 | };
32 |
33 | let count = move || counter.get();
34 |
35 | view! {
36 | {t!(i18n, hello_world)}
37 | {t!(i18n, click_to_change_lang)}
38 |
39 | {t!{ i18n,
40 | click_count,
41 | count,
42 | = ,
43 | }}
44 |
45 | {t!(i18n, click_to_inc)}
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/src/fileserv.rs:
--------------------------------------------------------------------------------
1 | use crate::app::App;
2 | use axum::response::Response as AxumResponse;
3 | use axum::{
4 | body::Body,
5 | extract::State,
6 | http::{Request, Response, StatusCode, Uri},
7 | response::IntoResponse,
8 | };
9 | use leptos::prelude::*;
10 | use tower::ServiceExt;
11 | use tower_http::services::{fs::ServeFileSystemResponseBody, ServeDir};
12 |
13 | pub async fn file_and_error_handler(
14 | uri: Uri,
15 | State(options): State,
16 | req: Request,
17 | ) -> AxumResponse {
18 | let root = options.site_root.clone();
19 | let res = get_static_file(uri.clone(), &root).await.unwrap();
20 |
21 | if res.status() == StatusCode::OK {
22 | res.into_response()
23 | } else {
24 | let handler = leptos_axum::render_app_to_stream(App);
25 | handler(req).await.into_response()
26 | }
27 | }
28 |
29 | async fn get_static_file(
30 | uri: Uri,
31 | root: &str,
32 | ) -> Result, (StatusCode, String)> {
33 | let req = Request::builder()
34 | .uri(uri.clone())
35 | .body(Body::empty())
36 | .unwrap();
37 | // `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
38 | // This path is relative to the cargo root
39 | ServeDir::new(root).oneshot(req).await.map_err(|err| {
40 | (
41 | StatusCode::INTERNAL_SERVER_ERROR,
42 | format!("Something went wrong: {err}"),
43 | )
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | #[cfg(feature = "ssr")]
5 | pub mod fileserv;
6 |
7 | leptos_i18n::load_locales!();
8 |
9 | #[cfg(feature = "hydrate")]
10 | #[wasm_bindgen::prelude::wasm_bindgen]
11 | pub fn hydrate() {
12 | use app::App;
13 | console_error_panic_hook::set_once();
14 | leptos::mount::hydrate_body(App);
15 | }
16 |
--------------------------------------------------------------------------------
/examples/ssr/hello_world_axum/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/hello_world_axum/style/main.scss
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/README.md:
--------------------------------------------------------------------------------
1 | # Routing SSR
2 |
3 | This example showcase how to setup the router using `leptos_i18n` in a SSR project.
4 |
5 | ## How to run
6 |
7 | Simply use `cargo_leptos` to run it:
8 |
9 | ```sh
10 | cargo leptos watch
11 | ```
12 |
13 | and to build:
14 |
15 | ```sh
16 | cargo leptos build --release
17 | ```
18 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Hello World!",
3 | "click_to_change_lang": "Click to change language",
4 | "click_count": "You clicked {{ count }} times",
5 | "click_to_inc": "Click to increment the counter",
6 | "go_home": "Homepage",
7 | "go_counter": "Counter"
8 | }
9 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello_world": "Bonjour le monde!",
3 | "click_to_change_lang": "Cliquez pour changez de langue",
4 | "click_count": "Vous avez cliqué {{ count }} fois",
5 | "click_to_inc": "Cliquez pour incrémenter le compteur",
6 | "go_home": "Accueil",
7 | "go_counter": "Compteur"
8 | }
9 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "routing_ssr",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to use routing with SSR",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/routing_ssr/public/favicon.ico
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/src/fileserv.rs:
--------------------------------------------------------------------------------
1 | use crate::app::App;
2 | use axum::response::Response as AxumResponse;
3 | use axum::{
4 | body::Body,
5 | extract::State,
6 | http::{Request, Response, StatusCode, Uri},
7 | response::IntoResponse,
8 | };
9 | use leptos::prelude::*;
10 | use tower::ServiceExt;
11 | use tower_http::services::{fs::ServeFileSystemResponseBody, ServeDir};
12 |
13 | pub async fn file_and_error_handler(
14 | uri: Uri,
15 | State(options): State,
16 | req: Request,
17 | ) -> AxumResponse {
18 | let root = options.site_root.clone();
19 | let res = get_static_file(uri.clone(), &root).await.unwrap();
20 |
21 | if res.status() == StatusCode::OK {
22 | res.into_response()
23 | } else {
24 | let handler = leptos_axum::render_app_to_stream(App);
25 | handler(req).await.into_response()
26 | }
27 | }
28 |
29 | async fn get_static_file(
30 | uri: Uri,
31 | root: &str,
32 | ) -> Result, (StatusCode, String)> {
33 | let req = Request::builder()
34 | .uri(uri.clone())
35 | .body(Body::empty())
36 | .unwrap();
37 | // `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
38 | // This path is relative to the cargo root
39 | ServeDir::new(root).oneshot(req).await.map_err(|err| {
40 | (
41 | StatusCode::INTERNAL_SERVER_ERROR,
42 | format!("Something went wrong: {err}"),
43 | )
44 | })
45 | }
46 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/src/lib.rs:
--------------------------------------------------------------------------------
1 | // #![deny(warnings)]
2 |
3 | pub mod app;
4 | #[cfg(feature = "ssr")]
5 | pub mod fileserv;
6 | leptos_i18n::load_locales!();
7 |
8 | #[cfg(feature = "hydrate")]
9 | #[wasm_bindgen::prelude::wasm_bindgen]
10 | pub fn hydrate() {
11 | use app::App;
12 | console_error_panic_hook::set_once();
13 | leptos::mount::hydrate_body(|| leptos::view! { });
14 | }
15 |
--------------------------------------------------------------------------------
/examples/ssr/routing_ssr/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/routing_ssr/style/main.scss
--------------------------------------------------------------------------------
/examples/ssr/workspace/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
4 |
5 | node_modules/
6 | /test-results/
7 | /playwright-report/
8 | /blob-report/
9 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/ssr/workspace/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/examples/ssr/workspace/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "counter/locales"
4 | }
--------------------------------------------------------------------------------
/examples/ssr/workspace/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "2"
3 | members = ["client", "server"]
4 |
5 | [workspace.dependencies]
6 | leptos_i18n = { path = "../../../leptos_i18n" }
7 |
8 | [[workspace.metadata.leptos]]
9 | name = "counter"
10 | bin-package = "server"
11 |
12 | lib-package = "client"
13 | lib-features = ["hydrate"]
14 |
15 | reload-port = 3001
16 |
17 | # [Optional] Command to use when running end2end tests. It will run in the end2end dir.
18 | end2end-cmd = "npx playwright test"
19 | end2end-dir = "e2e"
20 |
21 | # watch changes on the locales folder
22 | watch-additional-files = ["client/locales"]
23 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/README.md:
--------------------------------------------------------------------------------
1 | # Counter Example
2 |
3 | This example showcase one way to setup the library in a workspace environment.
4 |
5 | ## How to run
6 |
7 | Simply use `cargo_leptos` to run it:
8 |
9 | ```sh
10 | cargo leptos watch
11 | ```
12 |
13 | and to build:
14 |
15 | ```sh
16 | cargo leptos build --release
17 | ```
18 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "client"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | crate-type = ["cdylib", "rlib"]
8 |
9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10 |
11 | [dependencies]
12 | actix-web = { version = "4.4", optional = true, features = ["macros"] }
13 | leptos = { version = "0.7.0" }
14 | leptos_meta = { version = "0.7.0" }
15 | leptos_actix = { version = "0.7.0", optional = true }
16 | leptos_i18n = { workspace = true, features = ["track_locale_files"] }
17 | serde = { version = "1", features = ["derive"] }
18 | console_error_panic_hook = { version = "0.1", optional = true }
19 | wasm-bindgen = "0.2"
20 |
21 | [features]
22 | default = ["hydrate", "ssr"]
23 | hydrate = [
24 | "dep:console_error_panic_hook",
25 | "leptos/hydrate",
26 | "leptos_i18n/hydrate",
27 | ]
28 | ssr = [
29 | "dep:actix-web",
30 | "dep:leptos_actix",
31 | "leptos/ssr",
32 | "leptos_meta/ssr",
33 | "leptos_i18n/actix",
34 | ]
35 |
36 | [package.metadata.leptos-i18n]
37 | default = "en"
38 | locales = ["en", "fr"]
39 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Click to change language",
3 | "click_count": "You clicked {{ count }} times",
4 | "click_to_inc": "Click to increment the counter"
5 | }
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Cliquez pour changez de langue",
3 | "click_count": "Vous avez cliqué {{ count }} fois",
4 | "click_to_inc": "Cliquez pour incrémenter le compteur"
5 | }
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/workspace/client/public/favicon.ico
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/src/app.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use leptos::prelude::*;
3 |
4 | #[component]
5 | #[allow(non_snake_case)]
6 | pub fn App() -> impl IntoView {
7 | leptos_meta::provide_meta_context();
8 |
9 | view! {
10 |
11 |
12 |
13 |
14 | }
15 | }
16 |
17 | #[component]
18 | #[allow(non_snake_case)]
19 | pub fn SwitchLang() -> impl IntoView {
20 | let i18n = use_i18n();
21 |
22 | let on_switch = move |_| {
23 | let new_lang = match i18n.get_locale() {
24 | Locale::en => Locale::fr,
25 | Locale::fr => Locale::en,
26 | };
27 | i18n.set_locale(new_lang);
28 | };
29 |
30 | view! {
31 | {t!(i18n, click_to_change_lang)}
32 | }
33 | }
34 |
35 | #[component]
36 | #[allow(non_snake_case)]
37 | fn Counter() -> impl IntoView {
38 | let i18n = use_i18n();
39 |
40 | let (counter, set_counter) = signal(0);
41 |
42 | let inc = move |_| set_counter.update(|count| *count += 1);
43 |
44 | let count = move || counter.get();
45 |
46 | view! {
47 | {t!(i18n, click_count, count)}
48 | {t!(i18n, click_to_inc)}
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | pub mod app;
4 | leptos_i18n::load_locales!();
5 |
6 | #[cfg(feature = "hydrate")]
7 | #[wasm_bindgen::prelude::wasm_bindgen]
8 | pub fn hydrate() {
9 | use app::App;
10 | console_error_panic_hook::set_once();
11 | leptos::mount::hydrate_body(App);
12 | }
13 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/client/style/main.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Baptistemontan/leptos_i18n/d82366f1ca4a8ae91f3ba107047768b01622625f/examples/ssr/workspace/client/style/main.scss
--------------------------------------------------------------------------------
/examples/ssr/workspace/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worspace",
3 | "version": "1.0.0",
4 | "description": "This example showcase how to setup leptos_i18n in a worspace environment",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cargo leptos build",
8 | "start": "cargo leptos serve",
9 | "test": "npx playwright test",
10 | "prestart": "npm run build",
11 | "pretest": "npm run build"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@playwright/test": "^1.45.3",
18 | "@types/node": "^20.14.12"
19 | },
20 | "imports": {
21 | "#locales/*": "./client/locales/*"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/ssr/workspace/server/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
--------------------------------------------------------------------------------
/examples/ssr/workspace/server/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "server"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | actix-files = "0.6"
10 | actix-web = { version = "4.4", features = ["macros"] }
11 | leptos = { version = "0.7.0", features = ["ssr"] }
12 | leptos_meta = { version = "0.7.0", features = ["ssr"] }
13 | leptos_actix = { version = "0.7.0" }
14 | serde = { version = "1", features = ["derive"] }
15 | client = { path = "../client", default-features = false, features = ["ssr"] }
16 |
--------------------------------------------------------------------------------
/examples/utils/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
--------------------------------------------------------------------------------
/examples/utils/README.md:
--------------------------------------------------------------------------------
1 | # e2e utils package
2 |
3 | This package is utils for developping the e2e tests of the examples
4 |
--------------------------------------------------------------------------------
/examples/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "utils",
3 | "version": "1.0.0",
4 | "description": "This package is utils for developping the e2e tests of the examples",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "postinstall": "npm run build",
9 | "build": "npx tsc"
10 | },
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "@playwright/test": "^1.45.3",
15 | "@types/node": "^20.14.12",
16 | "typescript": "^5.5.4"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es2019",
5 | "declaration": true,
6 | "outDir": "./dist"
7 | },
8 | "include": [
9 | "src/**/*"
10 | ]
11 | }
--------------------------------------------------------------------------------
/leptos_i18n/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /Cargo.lock
3 |
--------------------------------------------------------------------------------
/leptos_i18n/src/macro_helpers/interpol_args.rs:
--------------------------------------------------------------------------------
1 | use leptos::IntoView;
2 |
3 | /// Marker trait for a type that can be used as an interpolation variable.
4 | pub trait InterpolateVar: IntoView + Clone + 'static + Send + Sync {}
5 |
6 | impl InterpolateVar for T {}
7 |
8 | /// Marker trait for a type that can be used as an interpolation component.
9 | pub trait InterpolateComp:
10 | Fn(leptos::children::ChildrenFn) -> O + Clone + 'static + Send + Sync
11 | {
12 | }
13 |
14 | impl<
15 | O: IntoView + 'static,
16 | T: Fn(leptos::children::ChildrenFn) -> O + Clone + 'static + Send + Sync,
17 | > InterpolateComp for T
18 | {
19 | }
20 |
21 | /// Marker trait for a type that can be used to produce a count for a range key.
22 | pub trait InterpolateRangeCount: Fn() -> T + Clone + 'static + Send + Sync {}
23 |
24 | impl T + Clone + 'static + Send + Sync> InterpolateRangeCount for F {}
25 |
26 | /// Marker trait for a type that can produce a `icu::plurals::PluralOperands`
27 | #[cfg(feature = "plurals")]
28 | pub trait InterpolatePluralCount: Fn() -> Self::Count + Clone + 'static + Send + Sync {
29 | /// The returned value that can be turned into a `icu::plurals::PluralOperands`
30 | type Count: Into;
31 | }
32 |
33 | #[cfg(feature = "plurals")]
34 | impl, F: Fn() -> T + Clone + 'static + Send + Sync>
35 | InterpolatePluralCount for F
36 | {
37 | type Count = T;
38 | }
39 |
--------------------------------------------------------------------------------
/leptos_i18n/src/macro_helpers/scope.rs:
--------------------------------------------------------------------------------
1 | use crate::{scopes::ScopedLocale, ConstScope, I18nContext, Locale, Scope};
2 |
3 | #[doc(hidden)]
4 | pub const fn scope_ctx_util, NS: Scope>(
5 | ctx: I18nContext,
6 | map_fn: fn(OS) -> NS,
7 | ) -> I18nContext {
8 | let old_scope = ConstScope::::new();
9 | let new_scope = old_scope.map(map_fn);
10 | ctx.scope(new_scope)
11 | }
12 |
13 | #[doc(hidden)]
14 | pub fn scope_locale_util, NS: Scope>(
15 | locale: L,
16 | map_fn: fn(>::Keys) -> NS,
17 | ) -> ScopedLocale {
18 | let _ = map_fn;
19 | ScopedLocale::new(locale.to_base_locale())
20 | }
21 |
--------------------------------------------------------------------------------
/leptos_i18n_build/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /Cargo.lock
3 |
--------------------------------------------------------------------------------
/leptos_i18n_build/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "leptos_i18n_build"
3 | version = { workspace = true }
4 | edition = "2021"
5 | authors = ["Baptiste de Montangon"]
6 | license = "MIT"
7 | repository = "https://github.com/Baptistemontan/leptos_i18n"
8 | description = "build.rs utilities for the leptos_i18n crate"
9 | readme = "../README.md"
10 |
11 | [dependencies]
12 | leptos_i18n_parser = { workspace = true }
13 | icu_datagen = { workspace = true, features = ["experimental_components"] }
14 | icu_provider = { workspace = true }
15 | icu_locid = { workspace = true }
16 |
17 | [features]
18 | default = ["json_files"]
19 | json_files = ["leptos_i18n_parser/json_files"]
20 | yaml_files = ["leptos_i18n_parser/yaml_files"]
21 | json5_files = ["leptos_i18n_parser/json5_files"]
22 |
--------------------------------------------------------------------------------
/leptos_i18n_macro/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /Cargo.lock
3 |
--------------------------------------------------------------------------------
/leptos_i18n_macro/src/load_locales/locale.rs:
--------------------------------------------------------------------------------
1 | use quote::{quote, ToTokens};
2 |
3 | #[derive(Debug, Clone, Copy, PartialEq, Eq)]
4 | pub enum LiteralType {
5 | String,
6 | Bool,
7 | Signed,
8 | Unsigned,
9 | Float,
10 | }
11 |
12 | impl From for LiteralType {
13 | fn from(value: leptos_i18n_parser::parse_locales::locale::LiteralType) -> Self {
14 | match value {
15 | leptos_i18n_parser::parse_locales::locale::LiteralType::String => Self::String,
16 | leptos_i18n_parser::parse_locales::locale::LiteralType::Bool => Self::Bool,
17 | leptos_i18n_parser::parse_locales::locale::LiteralType::Signed => Self::Signed,
18 | leptos_i18n_parser::parse_locales::locale::LiteralType::Unsigned => Self::Unsigned,
19 | leptos_i18n_parser::parse_locales::locale::LiteralType::Float => Self::Float,
20 | }
21 | }
22 | }
23 |
24 | impl ToTokens for LiteralType {
25 | fn to_token_stream(&self) -> proc_macro2::TokenStream {
26 | match self {
27 | LiteralType::String => quote!(&'static str),
28 | LiteralType::Bool => quote!(bool),
29 | LiteralType::Signed => quote!(i64),
30 | LiteralType::Unsigned => quote!(u64),
31 | LiteralType::Float => quote!(f64),
32 | }
33 | }
34 |
35 | fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
36 | tokens.extend(self.to_token_stream());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/leptos_i18n_macro/src/load_locales/tracking.rs:
--------------------------------------------------------------------------------
1 | pub fn generate_file_tracking(tracked_files: Option>) -> proc_macro2::TokenStream {
2 | if cfg!(all(
3 | not(feature = "track_locale_files"),
4 | not(feature = "nightly")
5 | )) {
6 | return proc_macro2::TokenStream::new();
7 | }
8 |
9 | let Some(paths) = tracked_files else {
10 | return proc_macro2::TokenStream::new();
11 | };
12 |
13 | if cfg!(all(
14 | feature = "track_locale_files",
15 | not(feature = "nightly")
16 | )) {
17 | quote::quote!(#(const _: &[u8] = include_bytes!(#paths);)*)
18 | } else {
19 | #[cfg(feature = "nightly")]
20 | for path in paths {
21 | proc_macro::tracked_path::path(path);
22 | }
23 |
24 | proc_macro2::TokenStream::new()
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/leptos_i18n_macro/src/load_locales/warning.rs:
--------------------------------------------------------------------------------
1 | use leptos_i18n_parser::parse_locales::warning::{Warning, Warnings};
2 | use proc_macro2::TokenStream;
3 | use quote::{format_ident, quote};
4 |
5 | fn warning_fn((index, warning): (usize, &Warning)) -> TokenStream {
6 | let msg = warning.to_string();
7 | let fn_name = format_ident!("w{}", index);
8 | quote! {
9 | #[deprecated(note = #msg)]
10 | fn #fn_name() {
11 | unimplemented!()
12 | }
13 | }
14 | }
15 |
16 | fn emit_warning(warning: &Warning) {
17 | let _ = warning;
18 | #[cfg(feature = "nightly")]
19 | {
20 | use proc_macro::Diagnostic;
21 |
22 | Diagnostic::new(proc_macro::Level::Warning, warning.to_string()).emit();
23 | }
24 | }
25 |
26 | fn generate_warnings_inner(warnings: &[Warning]) -> TokenStream {
27 | let warning_fns = warnings.iter().enumerate().map(warning_fn);
28 |
29 | let fn_calls = (0..warnings.len()).map(|i| {
30 | let fn_name = format_ident!("w{}", i);
31 | quote!(#fn_name();)
32 | });
33 |
34 | quote! {
35 | #[allow(unused)]
36 | fn warnings() {
37 | #(
38 | #warning_fns
39 | )*
40 |
41 | #(
42 | #fn_calls
43 | )*
44 | }
45 | }
46 | }
47 |
48 | pub fn generate_warnings(warnings: Warnings) -> Option {
49 | let ws = warnings.into_inner();
50 |
51 | if cfg!(not(feature = "nightly")) {
52 | if ws.is_empty() {
53 | None
54 | } else {
55 | Some(generate_warnings_inner(&ws))
56 | }
57 | } else {
58 | for warning in &ws {
59 | emit_warning(warning)
60 | }
61 | None
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/leptos_i18n_macro/src/t_macro/parsed_input.rs:
--------------------------------------------------------------------------------
1 | use syn::{token::Comma, Expr};
2 |
3 | use crate::utils::Keys;
4 |
5 | use super::interpolate::InterpolatedValue;
6 |
7 | pub struct ParsedInput {
8 | pub context: Expr,
9 | pub keys: Keys,
10 | pub interpolations: Option>,
11 | }
12 |
13 | impl syn::parse::Parse for ParsedInput {
14 | fn parse(input: syn::parse::ParseStream) -> syn::Result {
15 | let context = input.parse()?;
16 | input.parse::()?;
17 | let keys = input.parse()?;
18 | let comma = input.parse::();
19 | let interpolations = match comma {
20 | Ok(_) => {
21 | let interpolations = input
22 | .parse_terminated(InterpolatedValue::parse, Comma)?
23 | .into_iter()
24 | .collect();
25 | Some(interpolations)
26 | }
27 | Err(_) if input.is_empty() => None,
28 | Err(err) => return Err(err),
29 | };
30 | Ok(ParsedInput {
31 | context,
32 | keys,
33 | interpolations,
34 | })
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/leptos_i18n_macro/src/utils/scoped.rs:
--------------------------------------------------------------------------------
1 | use proc_macro2::TokenStream;
2 | use quote::quote;
3 | use syn::parse_macro_input;
4 |
5 | use super::Keys;
6 |
7 | struct ScopeParsedInput {
8 | pub context: syn::Expr,
9 | pub keys: Keys,
10 | }
11 |
12 | impl syn::parse::Parse for ScopeParsedInput {
13 | fn parse(input: syn::parse::ParseStream) -> syn::Result {
14 | let context = input.parse()?;
15 | input.parse::()?;
16 | let keys = input.parse()?;
17 | Ok(ScopeParsedInput { context, keys })
18 | }
19 | }
20 |
21 | pub fn scope_i18n(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
22 | let input = parse_macro_input!(tokens as ScopeParsedInput);
23 | scope_i18n_inner(input).into()
24 | }
25 |
26 | fn scope_i18n_inner(input: ScopeParsedInput) -> TokenStream {
27 | let ScopeParsedInput { context, keys } = input;
28 | quote! {{
29 | leptos_i18n::__private::scope_ctx_util(#context, |_k| _k.#keys())
30 | }}
31 | }
32 |
33 | pub fn use_i18n_scoped(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
34 | let input = parse_macro_input!(tokens as Keys);
35 | use_i18n_scoped_inner(input).into()
36 | }
37 |
38 | fn use_i18n_scoped_inner(keys: Keys) -> TokenStream {
39 | quote! {{
40 | leptos_i18n::__private::scope_ctx_util(use_i18n(), |_k| _k.#keys())
41 | }}
42 | }
43 |
44 | pub fn scope_locale(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
45 | let input = parse_macro_input!(tokens as ScopeParsedInput);
46 | scope_locale_inner(input).into()
47 | }
48 |
49 | fn scope_locale_inner(input: ScopeParsedInput) -> TokenStream {
50 | let ScopeParsedInput {
51 | context: locale,
52 | keys,
53 | } = input;
54 | quote! {{ leptos_i18n::__private::scope_locale_util(#locale, |_k| _k.#keys()) }}
55 | }
56 |
--------------------------------------------------------------------------------
/leptos_i18n_parser/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /Cargo.lock
3 |
--------------------------------------------------------------------------------
/leptos_i18n_parser/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "leptos_i18n_parser"
3 | version = { workspace = true }
4 | edition = "2021"
5 | authors = ["Baptiste de Montangon"]
6 | license = "MIT"
7 | repository = "https://github.com/Baptistemontan/leptos_i18n"
8 | description = "parser for the leptos_i18n crate"
9 | readme = "../README.md"
10 |
11 | [dependencies]
12 | icu_locid = { workspace = true }
13 | icu_plurals = { workspace = true, features = ["compiled_data"] }
14 | serde = { version = "1", features = ["rc"] }
15 | serde_json = { version = "1" }
16 | serde_yaml = { version = "0.9" }
17 | toml = "0.8"
18 | fixed_decimal = { workspace = true, features = ["ryu"] }
19 | json5 = { version = "0.4" }
20 | quote = { version = "1", optional = true }
21 | syn = { version = "2.0", optional = true }
22 | proc-macro2 = { version = "1", optional = true }
23 | tinystr = { workspace = true }
24 |
25 | [features]
26 | default = ["json_files"]
27 | quote = ["dep:quote", "dep:syn", "dep:proc-macro2"]
28 | json_files = []
29 | yaml_files = []
30 | json5_files = []
31 | plurals = []
32 | format_datetime = []
33 | format_list = []
34 | format_nums = []
35 | format_currency = ["format_nums"]
36 | suppress_key_warnings = []
37 |
--------------------------------------------------------------------------------
/leptos_i18n_parser/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![forbid(unsafe_code)]
2 | #![deny(warnings)]
3 |
4 | pub mod parse_locales;
5 | pub mod utils;
6 |
--------------------------------------------------------------------------------
/leptos_i18n_parser/src/utils/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod formatter;
2 | pub mod key;
3 |
4 | use std::fmt::Debug;
5 |
6 | pub use key::{Key, KeyPath};
7 |
8 | /// We should avoid to panic as much as possible, and return the Error enum instead,
9 | /// but there is cases where unwrap *should* be good, like when accessing a value in a Map where the keys are already known
10 | /// This trait serves as a easy unwrap where the code position can be given.
11 | pub trait UnwrapAt {
12 | type Value;
13 |
14 | fn unwrap_at(self, location: &str) -> Self::Value;
15 | }
16 |
17 | impl UnwrapAt for Option {
18 | type Value = T;
19 |
20 | #[track_caller]
21 | fn unwrap_at(self, location: &str) -> Self::Value {
22 | let msg = format!("Unexpected None value at {}. If you got this error please open an issue on the leptos_i18n github repo.", location);
23 | self.expect(&msg)
24 | }
25 | }
26 |
27 | impl UnwrapAt for Result {
28 | type Value = T;
29 |
30 | #[track_caller]
31 | fn unwrap_at(self, location: &str) -> Self::Value {
32 | let msg = format!("Unexpected Err value at {}. If you got this error please open an issue on the leptos_i18n github repo.", location);
33 | self.expect(&msg)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/leptos_i18n_router/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /Cargo.lock
3 |
--------------------------------------------------------------------------------
/leptos_i18n_router/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "leptos_i18n_router"
3 | version = { workspace = true }
4 | edition = "2021"
5 | authors = ["Baptiste de Montangon"]
6 | license = "MIT"
7 | repository = "https://github.com/Baptistemontan/leptos_i18n"
8 | description = "Translations integration helper for the Leptos web framework"
9 | readme = "../README.md"
10 |
11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12 |
13 | [dependencies]
14 | leptos_i18n = { workspace = true }
15 | leptos = { workspace = true }
16 | leptos_router = { workspace = true }
17 |
18 | [features]
19 | ssr = ["leptos/ssr", "leptos_router/ssr", "leptos_i18n/ssr"]
20 |
21 |
22 | [package.metadata.cargo-all-features]
23 | denylist = []
24 | skip_feature_sets = []
25 | always_include_features = []
26 |
--------------------------------------------------------------------------------
/leptos_i18n_router/src/components.rs:
--------------------------------------------------------------------------------
1 | use std::marker::PhantomData;
2 |
3 | use leptos::component;
4 | use leptos_i18n::Locale;
5 | use leptos_router::{components::RouteChildren, ChooseView, MatchNestedRoutes, SsrMode};
6 |
7 | #[component(transparent)]
8 | pub fn I18nRoute(
9 | /// The base path of this application.
10 | /// If you setup your i18n route such that the path is `/foo/:locale/bar`,
11 | /// the expected base path is `"foo"`, `"/foo"`, `"foo/"` or `"/foo/"`.
12 | /// Defaults to `"/"`.
13 | #[prop(default = "/")]
14 | base_path: &'static str,
15 | /// The view that should be shown when this route is matched. This can be any function
16 | /// that returns a type that implements [`IntoView`] (like `|| view! { "Show this"
})`
17 | /// or `|| view! { ` } or even, for a component with no props, `MyComponent`).
18 | /// If you use nested routes you can just set it to `view=Outlet`
19 | view: View,
20 | /// The mode that this route prefers during server-side rendering. Defaults to out-of-order streaming
21 | #[prop(optional)]
22 | ssr: SsrMode,
23 | /// `children` may be empty or include nested routes.
24 | children: RouteChildren,
25 | #[prop(optional)] _marker: PhantomData,
26 | ) -> impl MatchNestedRoutes + 'static + Send + Sync + Clone
27 | where
28 | View: ChooseView + 'static + Send + Sync,
29 | Chil: MatchNestedRoutes + 'static + Send + Sync + Clone,
30 | L: Locale,
31 | {
32 | crate::routing::i18n_routing::(base_path, children, ssr, view)
33 | }
34 |
--------------------------------------------------------------------------------
/leptos_i18n_router/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(missing_docs)]
2 | #![forbid(unsafe_code)]
3 | #![deny(warnings)]
4 | //! This crate contain anything related to routing for the `leptos_i18n` crate.
5 |
6 | mod components;
7 | mod routing;
8 |
9 | pub use components::I18nRoute;
10 |
11 | /// Create a route segment that is possible to define based on a locale.
12 | ///
13 | /// ```rust, ignore
14 | ///
15 | /// ```
16 | #[macro_export]
17 | macro_rules! i18n_path {
18 | ($t:ty, $func:expr) => {{
19 | $crate::__private::make_i18n_segment::<$t, _>($func)
20 | }};
21 | }
22 |
23 | #[doc(hidden)]
24 | pub mod __private {
25 | pub use crate::routing::make_i18n_segment;
26 | }
27 |
--------------------------------------------------------------------------------
/tests/common/Cargo.toml:
--------------------------------------------------------------------------------
1 |
2 | [package]
3 | name = "tests_common"
4 | version = "0.1.0"
5 | edition = "2021"
6 |
7 | [lib]
8 | crate-type = ["cdylib", "rlib"]
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [dependencies]
13 | leptos = { workspace = true }
14 |
--------------------------------------------------------------------------------
/tests/json/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
--------------------------------------------------------------------------------
/tests/json/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/tests/json/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/tests/json/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/tests/json/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "json"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | crate-type = ["cdylib", "rlib"]
8 |
9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10 |
11 | [dependencies]
12 | leptos = { workspace = true, features = ["ssr"] }
13 | tests_common = { workspace = true }
14 |
15 | [dependencies.leptos_i18n]
16 | workspace = true
17 | features = [
18 | "json_files",
19 | "icu_compiled_data",
20 | "interpolate_display",
21 | "track_locale_files",
22 | "plurals",
23 | "format_datetime",
24 | "format_nums",
25 | "format_list",
26 | "format_currency",
27 | ]
28 |
29 |
30 | [package.metadata.leptos-i18n]
31 | default = "en"
32 | locales = ["en", "fr"]
33 |
--------------------------------------------------------------------------------
/tests/json/README.md:
--------------------------------------------------------------------------------
1 | # JSON files format tests
2 |
3 | Test 2 things:
4 |
5 | - Everything compile fine
6 | - Check if the output is correct
7 |
--------------------------------------------------------------------------------
/tests/json/src/defaulted.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use tests_common::*;
3 |
4 | #[test]
5 | fn defaulted_string() {
6 | let en = td!(Locale::en, defaulted_string);
7 | assert_eq_rendered!(en, "this string is declared in locale en");
8 | let fr = td!(Locale::fr, defaulted_string);
9 | assert_eq_rendered!(fr, "this string is declared in locale en");
10 | }
11 |
12 | #[test]
13 | fn defaulted_interpolation() {
14 | let en = td!(Locale::en, defaulted_interpolation, locale = "en");
15 | assert_eq_rendered!(en, "this interpolation is declared in locale en");
16 | let fr = td!(Locale::fr, defaulted_interpolation, locale = "en");
17 | assert_eq_rendered!(fr, "this interpolation is declared in locale en");
18 | }
19 |
20 | #[test]
21 | fn defaulted_ranges() {
22 | let count = || 0;
23 | let en = td!(Locale::en, defaulted_ranges, locale = "en", count);
24 | assert_eq_rendered!(en, "zero");
25 | let fr = td!(Locale::fr, defaulted_ranges, locale = "en", count);
26 | assert_eq_rendered!(fr, "zero");
27 |
28 | for i in [-3, 5, 12] {
29 | let count = move || i;
30 | let en = td!(Locale::en, defaulted_ranges, locale = "en", count);
31 | assert_eq_rendered!(en, "this range is declared in locale en");
32 | let fr = td!(Locale::fr, defaulted_ranges, locale = "en", count);
33 | assert_eq_rendered!(fr, "this range is declared in locale en");
34 | }
35 | }
36 |
37 | #[test]
38 | fn defaulted_foreign_key() {
39 | let en = td!(Locale::en, defaulted_foreign_key);
40 | assert_eq_rendered!(en, "before Click to increment the counter after");
41 | let fr = td!(Locale::fr, defaulted_foreign_key);
42 | assert_eq_rendered!(fr, "before Click to increment the counter after");
43 | }
44 |
45 | #[test]
46 | fn defaulted_subkeys() {
47 | let en = td!(Locale::en, defaulted_subkeys.subkey);
48 | assert_eq_rendered!(en, "some string");
49 | let fr = td!(Locale::fr, defaulted_subkeys.subkey);
50 | assert_eq_rendered!(fr, "some string");
51 | }
52 |
--------------------------------------------------------------------------------
/tests/json/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 |
3 | leptos_i18n::load_locales!();
4 |
5 | #[cfg(test)]
6 | mod defaulted;
7 | #[cfg(test)]
8 | mod foreign;
9 | #[cfg(test)]
10 | mod formatting;
11 | #[cfg(test)]
12 | mod plurals;
13 | #[cfg(test)]
14 | mod ranges;
15 | #[cfg(test)]
16 | mod scoped;
17 | #[cfg(test)]
18 | mod subkeys;
19 | #[cfg(test)]
20 | mod tests;
21 |
22 | #[cfg(test)]
23 | mod t_format;
24 | #[cfg(test)]
25 | mod t_plural;
26 |
--------------------------------------------------------------------------------
/tests/json/src/scoped.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use tests_common::*;
3 |
4 | #[test]
5 | fn subkey_3() {
6 | let en_scope = scope_locale!(Locale::en, subkeys);
7 | let fr_scope = scope_locale!(Locale::fr, subkeys);
8 |
9 | let count = || 0;
10 | let en = td!(en_scope, subkey_3, count);
11 | assert_eq_rendered!(en, "zero");
12 | let fr = td!(fr_scope, subkey_3, count);
13 | assert_eq_rendered!(fr, "0");
14 | let count = || 1;
15 | let en = td!(en_scope, subkey_3, count);
16 | assert_eq_rendered!(en, "one");
17 | let fr = td!(fr_scope, subkey_3, count);
18 | assert_eq_rendered!(fr, "1");
19 | let count = || 3;
20 | let en = td!(en_scope, subkey_3, count);
21 | assert_eq_rendered!(en, "3");
22 | let fr = td!(fr_scope, subkey_3, count);
23 | assert_eq_rendered!(fr, "3");
24 | }
25 |
--------------------------------------------------------------------------------
/tests/json5/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
--------------------------------------------------------------------------------
/tests/json5/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/tests/json5/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/tests/json5/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/tests/json5/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "json5"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | crate-type = ["cdylib", "rlib"]
8 |
9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10 |
11 | [dependencies]
12 | leptos = { version = "0.7.0", features = ["ssr"] }
13 | tests_common = { path = "../common" }
14 | leptos_i18n = { path = "../../leptos_i18n", default-features = false, features = [
15 | "json5_files",
16 | "icu_compiled_data",
17 | "track_locale_files",
18 | ] }
19 |
20 |
21 | [package.metadata.leptos-i18n]
22 | default = "en"
23 | locales = ["en", "fr"]
24 |
--------------------------------------------------------------------------------
/tests/json5/README.md:
--------------------------------------------------------------------------------
1 | # YAML files format tests
2 |
3 | Test 2 things:
4 |
5 | - Everything compile fine
6 | - Check if the output is correct
7 |
8 | Disclaimer: the yaml files are slightly tweaked "JSON to YAML" outputs, if it looks ugly it's because it's only 3.14% hand made.
9 |
--------------------------------------------------------------------------------
/tests/json5/locales/en.json5:
--------------------------------------------------------------------------------
1 | {
2 | click_to_change_lang: "Click to change language",
3 | click_count: "You clicked {{ count }} times",
4 | click_to_inc: "Click to increment the counter",
5 | f32_range: [
6 | "f32",
7 | ["You are broke", 0.0],
8 | ["You owe money", "..0.0"],
9 | ["You have {{ count }}€"],
10 | ],
11 | u32_range: ["u32", [0, 0], ["1..", "1.."]],
12 | OR_range: [
13 | "u8",
14 | ["0 or 5", "0", 5],
15 | ["1..5 | 6..10", "1..5", "6..10"],
16 | ["10..15 | 20", "10..15", 20],
17 | ["fallback with no count"],
18 | ],
19 | f32_OR_range: [
20 | "f32",
21 | ["0 or 5", 0, 5],
22 | ["1..5 | 6..10", "1..5", "6..10"],
23 | ["10..15 | 20", "10..15", 20],
24 | ["fallback with no count"],
25 | ],
26 | subkeys: {
27 | subkey_1: "subkey_1",
28 | subkey_2: "subkey_2 ",
29 | subkey_3: [
30 | ["zero", 0],
31 | ["one", 1],
32 | ["{{ count }}", "_"],
33 | ],
34 | },
35 | defaulted_string: "this string is declared in locale en",
36 | defaulted_interpolation: "this interpolation is declared in locale {{ locale }}",
37 | defaulted_ranges: [
38 | ["zero", 0],
39 | ["this range is declared in locale {{ locale }}"],
40 | ],
41 | }
42 |
--------------------------------------------------------------------------------
/tests/json5/locales/fr.json5:
--------------------------------------------------------------------------------
1 | {
2 | click_to_change_lang: "Cliquez pour changez de langue",
3 | click_count: "Vous avez cliqué {{ count }} fois",
4 | click_to_inc: "Cliquez pour incrémenter le compteur",
5 | f32_range: [
6 | "f32",
7 | ["Vous êtes pauvre", 0.0],
8 | ["Vous devez de l'argent", "..0.0"],
9 | ["Vous avez {{ count }}€"],
10 | ],
11 | u32_range: ["u32", [0, 0], ["1..", "1.."]],
12 | OR_range: [
13 | "u8",
14 | ["0 or 5", "0", 5],
15 | ["1..5 | 6..10", "1..5", "6..10"],
16 | ["10..15 | 20", "10..15", 20],
17 | ["fallback sans count"],
18 | ],
19 | f32_OR_range: [
20 | "f32",
21 | ["0 or 5", 0, 5],
22 | ["1..5 | 6..10", "1..5", "6..10"],
23 | ["10..15 | 20", "10..15", 20],
24 | ["fallback avec tuple vide", []],
25 | ],
26 | subkeys: {
27 | subkey_1: "subkey_1",
28 | subkey_2: "subkey_2 ",
29 | subkey_3: [
30 | ["0", 0],
31 | ["{{ count }}", "_"],
32 | ],
33 | },
34 | defaulted_string: null,
35 | defaulted_interpolation: null,
36 | defaulted_ranges: null,
37 | }
38 |
--------------------------------------------------------------------------------
/tests/json5/src/defaulted.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use tests_common::*;
3 |
4 | #[test]
5 | fn defaulted_string() {
6 | let en = td!(Locale::en, defaulted_string);
7 | assert_eq_rendered!(en, "this string is declared in locale en");
8 | let fr = td!(Locale::fr, defaulted_string);
9 | assert_eq_rendered!(fr, "this string is declared in locale en");
10 | }
11 |
12 | #[test]
13 | fn defaulted_interpolation() {
14 | let en = td!(Locale::en, defaulted_interpolation, locale = "en");
15 | assert_eq_rendered!(en, "this interpolation is declared in locale en");
16 | let fr = td!(Locale::fr, defaulted_interpolation, locale = "en");
17 | assert_eq_rendered!(fr, "this interpolation is declared in locale en");
18 | }
19 |
20 | #[test]
21 | fn defaulted_ranges() {
22 | let count = || 0;
23 | let en = td!(Locale::en, defaulted_ranges, locale = "en", count = count);
24 | assert_eq_rendered!(en, "zero");
25 | let fr = td!(Locale::fr, defaulted_ranges, locale = "en", count = count);
26 | assert_eq_rendered!(fr, "zero");
27 |
28 | for i in [-3, 5, 12] {
29 | let count = move || i;
30 | let en = td!(Locale::en, defaulted_ranges, locale = "en", count = count);
31 | assert_eq_rendered!(en, "this range is declared in locale en");
32 | let fr = td!(Locale::fr, defaulted_ranges, locale = "en", count = count);
33 | assert_eq_rendered!(fr, "this range is declared in locale en");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/json5/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 | leptos_i18n::load_locales!();
3 |
4 | #[cfg(test)]
5 | mod ranges;
6 |
7 | #[cfg(test)]
8 | mod subkeys;
9 |
10 | #[cfg(test)]
11 | mod tests;
12 |
13 | #[cfg(test)]
14 | mod defaulted;
15 |
--------------------------------------------------------------------------------
/tests/json5/src/subkeys.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use tests_common::*;
3 |
4 | #[test]
5 | fn subkey_1() {
6 | let en = td!(Locale::en, subkeys.subkey_1);
7 | assert_eq_rendered!(en, "subkey_1");
8 | let fr = td!(Locale::fr, subkeys.subkey_1);
9 | assert_eq_rendered!(fr, "subkey_1");
10 | }
11 |
12 | #[test]
13 | fn subkey_2() {
14 | let b = |children: ChildrenFn| view! { {move || children()} };
15 | let en = td!(Locale::en, subkeys.subkey_2, );
16 | assert_eq_rendered!(en, "subkey_2 ");
17 | let fr = td!(Locale::fr, subkeys.subkey_2, );
18 | assert_eq_rendered!(fr, "subkey_2 ");
19 |
20 | let b = |children: ChildrenFn| view! { "before "{move || children()}" after"
};
21 | let en = td!(Locale::en, subkeys.subkey_2, );
22 | assert_eq_rendered!(en, " before subkey_2 after
");
23 | let fr = td!(Locale::fr, subkeys.subkey_2, );
24 | assert_eq_rendered!(fr, " before subkey_2 after
");
25 | }
26 |
27 | #[test]
28 | fn subkey_3() {
29 | let count = || 0;
30 | let en = td!(Locale::en, subkeys.subkey_3, count = count);
31 | assert_eq_rendered!(en, "zero");
32 | let fr = td!(Locale::fr, subkeys.subkey_3, count = count);
33 | assert_eq_rendered!(fr, "0");
34 | let count = || 1;
35 | let en = td!(Locale::en, subkeys.subkey_3, count = count);
36 | assert_eq_rendered!(en, "one");
37 | let fr = td!(Locale::fr, subkeys.subkey_3, count = count);
38 | assert_eq_rendered!(fr, "1");
39 | let count = || 3;
40 | let en = td!(Locale::en, subkeys.subkey_3, count = count);
41 | assert_eq_rendered!(en, "3");
42 | let fr = td!(Locale::fr, subkeys.subkey_3, count = count);
43 | assert_eq_rendered!(fr, "3");
44 | }
45 |
--------------------------------------------------------------------------------
/tests/namespaces/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
--------------------------------------------------------------------------------
/tests/namespaces/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/tests/namespaces/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/tests/namespaces/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales",
4 | "i18n-ally.namespace": true
5 | }
--------------------------------------------------------------------------------
/tests/namespaces/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "namespaces"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | crate-type = ["cdylib", "rlib"]
8 |
9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10 |
11 | [dependencies]
12 | leptos = { workspace = true, features = ["ssr"] }
13 | tests_common = { workspace = true }
14 |
15 | [dependencies.leptos_i18n]
16 | workspace = true
17 | features = [
18 | "json_files",
19 | "icu_compiled_data",
20 | "interpolate_display",
21 | "track_locale_files",
22 | ]
23 |
24 |
25 | [package.metadata.leptos-i18n]
26 | default = "en"
27 | locales = ["en", "fr"]
28 | namespaces = ["first_namespace", "second_namespace"]
29 |
--------------------------------------------------------------------------------
/tests/namespaces/README.md:
--------------------------------------------------------------------------------
1 | # Namespaces test
2 |
3 | Test 2 things:
4 |
5 | - Everything compile fine
6 | - Check if the output is correct
7 |
--------------------------------------------------------------------------------
/tests/namespaces/locales/en/first_namespace.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Click to change language",
3 | "common_key": "first namespace",
4 | "range_only_en": [
5 | {
6 | "count": 0,
7 | "value": "exact"
8 | },
9 | {
10 | "count": "..0",
11 | "value": "unbounded start"
12 | },
13 | {
14 | "count": "99..",
15 | "value": "unbounded end"
16 | },
17 | {
18 | "count": "1..3",
19 | "value": "excluded end"
20 | },
21 | {
22 | "count": "3..=8",
23 | "value": "included end"
24 | },
25 | {
26 | "count": "_",
27 | "value": "fallback"
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/tests/namespaces/locales/en/second_namespace.json:
--------------------------------------------------------------------------------
1 | {
2 | "common_key": "second namespace",
3 | "click_count": "You clicked {{ count }} times",
4 | "click_to_inc": "Click to increment the counter",
5 | "subkeys": {
6 | "subkey_1": "subkey_1",
7 | "subkey_2": "subkey_2 ",
8 | "subkey_3": [
9 | ["zero", "0"],
10 | ["one", 1],
11 | ["{{ count }}", "_"]
12 | ]
13 | },
14 | "foreign_key_to_same_namespace": "before $t(second_namespace:common_key) after",
15 | "foreign_key_to_another_namespace": "before $t(first_namespace:common_key) after"
16 | }
17 |
--------------------------------------------------------------------------------
/tests/namespaces/locales/fr/first_namespace.json:
--------------------------------------------------------------------------------
1 | {
2 | "click_to_change_lang": "Cliquez pour changez de langue",
3 | "common_key": "premier namespace",
4 | "range_only_en": "pas de ranges en français"
5 | }
6 |
--------------------------------------------------------------------------------
/tests/namespaces/locales/fr/second_namespace.json:
--------------------------------------------------------------------------------
1 | {
2 | "common_key": "deuxième namespace",
3 | "click_count": "Vous avez cliqué {{ count }} fois",
4 | "click_to_inc": "Cliquez pour incrémenter le compteur",
5 | "subkeys": {
6 | "subkey_1": "subkey_1",
7 | "subkey_2": "subkey_2 ",
8 | "subkey_3": [
9 | ["zero", 0],
10 | ["{{ count }}", "_"]
11 | ]
12 | },
13 | "foreign_key_to_same_namespace": "before $t(second_namespace:common_key) after",
14 | "foreign_key_to_another_namespace": "before $t(first_namespace:common_key) after"
15 | }
16 |
--------------------------------------------------------------------------------
/tests/namespaces/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 | leptos_i18n::load_locales!();
3 |
4 | #[cfg(test)]
5 | mod first_ns;
6 | #[cfg(test)]
7 | mod scoped;
8 | #[cfg(test)]
9 | mod second_ns;
10 |
--------------------------------------------------------------------------------
/tests/yaml/.gitignore:
--------------------------------------------------------------------------------
1 | Cargo.lock
2 | target
3 | !.vscode
--------------------------------------------------------------------------------
/tests/yaml/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "lokalise.i18n-ally",
4 | ]
5 | }
--------------------------------------------------------------------------------
/tests/yaml/.vscode/i18n-ally-custom-framework.yml:
--------------------------------------------------------------------------------
1 | languageIds:
2 | - rust
3 |
4 | usageMatchRegex:
5 | - "[^\\w\\d]t!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
6 | - "[^\\w\\d]td!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
7 | - "[^\\w\\d]td_string!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
8 | - "[^\\w\\d]td_display!\\(\\s*[\\w.:]*,\\s*([\\w.]*)"
9 |
10 | monopoly: true
11 |
--------------------------------------------------------------------------------
/tests/yaml/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "i18n-ally.keystyle": "nested",
3 | "i18n-ally.localesPaths": "locales"
4 | }
--------------------------------------------------------------------------------
/tests/yaml/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "yaml"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [lib]
7 | crate-type = ["cdylib", "rlib"]
8 |
9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
10 |
11 | [dependencies]
12 | leptos = { version = "0.7.0", features = ["ssr"] }
13 | tests_common = { path = "../common" }
14 | leptos_i18n = { path = "../../leptos_i18n", default-features = false, features = [
15 | "yaml_files",
16 | "icu_compiled_data",
17 | "track_locale_files",
18 | ] }
19 |
20 |
21 | [package.metadata.leptos-i18n]
22 | default = "en"
23 | locales = ["en", "fr"]
24 |
--------------------------------------------------------------------------------
/tests/yaml/README.md:
--------------------------------------------------------------------------------
1 | # YAML files format tests
2 |
3 | Test 2 things:
4 |
5 | - Everything compile fine
6 | - Check if the output is correct
7 |
8 | Disclaimer: the yaml files are slightly tweaked "JSON to YAML" outputs, if it looks ugly it's because it's only 3.14% hand made.
9 |
--------------------------------------------------------------------------------
/tests/yaml/locales/en.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | click_to_change_lang: Click to change language
3 | click_count: You clicked {{ count }} times
4 | click_to_inc: Click to increment the counter
5 | f32_range:
6 | - f32
7 | - count: "0.0"
8 | value: You are broke
9 | - count: "..0.0"
10 | value: You owe money
11 | - ["You have {{ count }}€", _]
12 | u32_range:
13 | - u32
14 | - count: 0
15 | value: "0"
16 | - count: 1..
17 | value: 1..
18 | OR_range:
19 | - u8
20 | - [0 or 5, "0", 5]
21 | - count: 1..5 | 6..10
22 | value: 1..5 | 6..10
23 | - count:
24 | - 10..15
25 | - "20"
26 | value: 10..15 | 20
27 | - value: fallback with no count
28 | f32_OR_range:
29 | - f32
30 | - count: 0 | 5
31 | value: 0 or 5
32 | - count:
33 | - 1..5
34 | - 6..10
35 | value: 1..5 | 6..10
36 | - count:
37 | - 10..15 | 20
38 | value: 10..15 | 20
39 | - - fallback with no count
40 | subkeys:
41 | subkey_1: subkey_1
42 | subkey_2: "subkey_2 "
43 | subkey_3:
44 | - [zero, 0]
45 | - [one, 1]
46 | - ["{{ count }}", _]
47 | defaulted_string: this string is declared in locale en
48 | defaulted_interpolation: this interpolation is declared in locale {{ locale }}
49 | defaulted_ranges:
50 | - [zero, 0]
51 | - - this range is declared in locale {{ locale }}
52 |
--------------------------------------------------------------------------------
/tests/yaml/locales/fr.yml:
--------------------------------------------------------------------------------
1 | click_to_change_lang: Cliquez pour changez de langue
2 | click_count: Vous avez cliqué {{ count }} fois
3 | click_to_inc: Cliquez pour incrémenter le compteur
4 | f32_range:
5 | - f32
6 | - count: 0
7 | value: Vous êtes pauvre
8 | - count: ..0.0
9 | value: Vous devez de l'argent
10 | - count: _
11 | value: Vous avez {{ count }}€
12 | u32_range:
13 | - u32
14 | - count: 0
15 | value: "0"
16 | - count: 1..
17 | value: 1..
18 | OR_range:
19 | - u8
20 | - count: 0 | 5
21 | value: 0 or 5
22 | - count: 1..5 | 6..10
23 | value: 1..5 | 6..10
24 | - count:
25 | - 10..15
26 | - 20
27 | value: 10..15 | 20
28 | - value: fallback sans count
29 | f32_OR_range:
30 | - f32
31 | - ["0 or 5", [0, "5"]]
32 | - count:
33 | - 1..5
34 | - 6..10
35 | value: 1..5 | 6..10
36 | - count:
37 | - 10..15 | 20
38 | value: 10..15 | 20
39 | - count: []
40 | value: fallback avec tuple vide
41 | subkeys:
42 | subkey_1: subkey_1
43 | subkey_2: subkey_2
44 | subkey_3:
45 | - ["0", 0]
46 | - ["{{ count }}", _]
47 | defaulted_string:
48 | defaulted_interpolation: ~
49 | defaulted_ranges: null
50 |
--------------------------------------------------------------------------------
/tests/yaml/src/defaulted.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use tests_common::*;
3 |
4 | #[test]
5 | fn defaulted_string() {
6 | let en = td!(Locale::en, defaulted_string);
7 | assert_eq_rendered!(en, "this string is declared in locale en");
8 | let fr = td!(Locale::fr, defaulted_string);
9 | assert_eq_rendered!(fr, "this string is declared in locale en");
10 | }
11 |
12 | #[test]
13 | fn defaulted_interpolation() {
14 | let en = td!(Locale::en, defaulted_interpolation, locale = "en");
15 | assert_eq_rendered!(en, "this interpolation is declared in locale en");
16 | let fr = td!(Locale::fr, defaulted_interpolation, locale = "en");
17 | assert_eq_rendered!(fr, "this interpolation is declared in locale en");
18 | }
19 |
20 | #[test]
21 | fn defaulted_ranges() {
22 | let count = || 0;
23 | let en = td!(Locale::en, defaulted_ranges, locale = "en", count = count);
24 | assert_eq_rendered!(en, "zero");
25 | let fr = td!(Locale::fr, defaulted_ranges, locale = "en", count = count);
26 | assert_eq_rendered!(fr, "zero");
27 |
28 | for i in [-3, 5, 12] {
29 | let count = move || i;
30 | let en = td!(Locale::en, defaulted_ranges, locale = "en", count = count);
31 | assert_eq_rendered!(en, "this range is declared in locale en");
32 | let fr = td!(Locale::fr, defaulted_ranges, locale = "en", count = count);
33 | assert_eq_rendered!(fr, "this range is declared in locale en");
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/yaml/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![deny(warnings)]
2 | leptos_i18n::load_locales!();
3 |
4 | #[cfg(test)]
5 | mod ranges;
6 |
7 | #[cfg(test)]
8 | mod subkeys;
9 |
10 | #[cfg(test)]
11 | mod tests;
12 |
13 | #[cfg(test)]
14 | mod defaulted;
15 |
--------------------------------------------------------------------------------
/tests/yaml/src/subkeys.rs:
--------------------------------------------------------------------------------
1 | use crate::i18n::*;
2 | use tests_common::*;
3 |
4 | #[test]
5 | fn subkey_1() {
6 | let en = td!(Locale::en, subkeys.subkey_1);
7 | assert_eq_rendered!(en, "subkey_1");
8 | let fr = td!(Locale::fr, subkeys.subkey_1);
9 | assert_eq_rendered!(fr, "subkey_1");
10 | }
11 |
12 | #[test]
13 | fn subkey_2() {
14 | let b = |children: ChildrenFn| view! { {move || children()} };
15 | let en = td!(Locale::en, subkeys.subkey_2, );
16 | assert_eq_rendered!(en, "subkey_2 ");
17 | let fr = td!(Locale::fr, subkeys.subkey_2, );
18 | assert_eq_rendered!(fr, "subkey_2 ");
19 |
20 | let b = |children: ChildrenFn| view! { "before "{move || children()}" after"
};
21 | let en = td!(Locale::en, subkeys.subkey_2, );
22 | assert_eq_rendered!(en, " before subkey_2 after
");
23 | let fr = td!(Locale::fr, subkeys.subkey_2, );
24 | assert_eq_rendered!(fr, " before subkey_2 after
");
25 | }
26 |
27 | #[test]
28 | fn subkey_3() {
29 | let count = || 0;
30 | let en = td!(Locale::en, subkeys.subkey_3, count = count);
31 | assert_eq_rendered!(en, "zero");
32 | let fr = td!(Locale::fr, subkeys.subkey_3, count = count);
33 | assert_eq_rendered!(fr, "0");
34 | let count = || 1;
35 | let en = td!(Locale::en, subkeys.subkey_3, count = count);
36 | assert_eq_rendered!(en, "one");
37 | let fr = td!(Locale::fr, subkeys.subkey_3, count = count);
38 | assert_eq_rendered!(fr, "1");
39 | let count = || 3;
40 | let en = td!(Locale::en, subkeys.subkey_3, count = count);
41 | assert_eq_rendered!(en, "3");
42 | let fr = td!(Locale::fr, subkeys.subkey_3, count = count);
43 | assert_eq_rendered!(fr, "3");
44 | }
45 |
--------------------------------------------------------------------------------