This repository was archived by the owner on Mar 11, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 210
I18n #700
Closed
Closed
I18n #700
Changes from all commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
f8af562
added language files for tests
AndromedaCLI e9b1be5
added htmls files to test translation
AndromedaCLI 9877915
added tests
AndromedaCLI 2eb0fdf
added parser for localize(foo, bar: baz)
AndromedaCLI 7d11fd2
added tests for the localize parser
AndromedaCLI 8336929
added visit_localize, arm: Expr::Localize, field:localized_messages
AndromedaCLI 72dda5e
added extraction for the locale field and localizer field
AndromedaCLI 858ea69
added locale attribute
AndromedaCLI 465483d
corrected locale attribute
AndromedaCLI 39a1370
added feature localization
AndromedaCLI 47cbb51
added #[cfg(feature = "localization")]
AndromedaCLI 1874729
Fixed errors and added comment
AndromedaCLI 98ff019
fix cargo files
AndromedaCLI 07db0e7
fix test: test_parse_nested_localize
AndromedaCLI 8bd252e
added #![cfg(feature = "localization")] to i18n tests
AndromedaCLI c96ada6
added askama::Local struct with impl
AndromedaCLI d1a46fe
changed tests to use askama::Local
AndromedaCLI cdbc7d0
removed init_translation macro since its not needed anymore
AndromedaCLI 4c7300c
refactored no args test adn its template
AndromedaCLI 7e1f5e6
Merge branch 'main' of https://github.com/11Tuvork28/askama into i18n
AndromedaCLI 17f95e7
removed last todos
AndromedaCLI 2c827f2
Added test for invalid tags with no fallack language
AndromedaCLI c3f5684
fixed lint error from Lint workflow
AndromedaCLI 2658da3
Fixed typo th -> the
AndromedaCLI 7b89872
fixed test I messed up
AndromedaCLI 5ce38a3
Added fn quoted_ident to support only localize("foo", bar:baz) and
AndromedaCLI 7a11db6
Updated test templates -> quoted all messages
AndromedaCLI 355163a
Added cut() to localze function
AndromedaCLI 62027c8
Revert "Added cut() to localze function" because expr_any uses alt wh…
AndromedaCLI bbe5991
HashMap<String, ...> to HashMap<&str, ...>
AndromedaCLI f3ec8c7
removed .to_string()
AndromedaCLI cc01d9b
removed "dep:" from toml files and removed println
AndromedaCLI afbc64f
A bunch of changes
Kijewski b3714f4
Merge pull request #1 from Kijewski/i18n
AndromedaCLI 569a79b
Remove unnecessary feature guard
AndromedaCLI db5c3e2
Corrected comment
AndromedaCLI 129786d
Validate localization at compile time
Kijewski ba50d10
Merge pull request #2 from Kijewski/br-i18n-with-compile-time-checks
AndromedaCLI ca2ca74
Fixed various Clippy complaints
AndromedaCLI da0319b
added feature guards to make the compiler happy and fix errors
AndromedaCLI da9f506
changed forbid(unsafe) to forbid(unsafe_code)
AndromedaCLI 96c63c5
Created typ alias PathResources for Vec<(PathBuf, Resource<String>
AndromedaCLI 7663bf8
Fix "all" the clippy warnings
Kijewski 03b4979
Merge pull request #3 from Kijewski/br-i18n-with-compile-time-checks
AndromedaCLI 08d34bd
Merge branch 'djc:main' into i18n
AndromedaCLI 39b0c4a
Merge branch 'main' into i18n
AndromedaCLI 6872a72
Fix lint job
AndromedaCLI 92fadc9
fix: Remove commented out i18n tests
LeoniePhiline 98a4777
fix: Add trailing newline to i18n test templates
LeoniePhiline 63ed5c9
fix: `cargo fmt`, remove trailing whitespace
LeoniePhiline 073e92a
fix: Rename feature `localization` to `i18n`
LeoniePhiline f944c86
opinionated: Rename initialization macro `localization!` to `i18n_load!`
LeoniePhiline c32b22d
style: Change wording "have to" to "need to"
LeoniePhiline 426575e
refactor: Confine i18n code inside i18n modules
LeoniePhiline 81cce1a
fix: Hide dependency `fluent_templates` from library users
LeoniePhiline 1c315d6
fix(deps): Update dependency `fluent-templates` to `0.8.0`
LeoniePhiline 6384ae2
docs: Add initial i18n module documentation
LeoniePhiline 7f82494
Merge pull request #4 from LeoniePhiline/i18n
AndromedaCLI 3f002ef
docs: Rename example template struct
LeoniePhiline 925d1b5
Merge branch 'djc:main' into i18n
AndromedaCLI 8f30ba5
Merge pull request #5 from LeoniePhiline/i18n
AndromedaCLI b52aaf3
fix: Implement missing recursive `is_cachable()` for `Expr::Localize`
LeoniePhiline 9909c36
fix(style): Name localization message identifier as in Fluent Project
LeoniePhiline 6cda9f5
fix(style): Normalize test names, prefix all with `test_`
LeoniePhiline 9e1f326
Merge pull request #6 from LeoniePhiline/i18n
AndromedaCLI 7c15904
fix: Add missing trailing newline
LeoniePhiline 5c35e12
Merge branch '11Tuvork28:i18n' into i18n
LeoniePhiline 2bbba70
fix: Compilation without feature `i18n` failed
LeoniePhiline b5dda4c
Merge pull request #7 from LeoniePhiline/i18n
AndromedaCLI f9dfa60
Merge branch 'djc:main' into i18n
AndromedaCLI File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| //! Module for compile time checked localization | ||
| //! | ||
| //! # Example: | ||
| //! | ||
| //! [Fluent Translation List](https://projectfluent.org/) resource file `i18n/es-MX/basic.ftl`: | ||
| //! | ||
| //! ```ftl | ||
| //! greeting = ¡Hola, { $name }! | ||
| //! ``` | ||
| //! | ||
| //! Askama HTML template `templates/example.html`: | ||
| //! | ||
| //! ```html | ||
| //! <h1>{{ localize("greeting", name: name) }}</h1> | ||
| //! ``` | ||
| //! | ||
| //! Rust usage: | ||
| //! ```ignore | ||
| //! use askama::i18n::{langid, Locale}; | ||
| //! use askama::Template; | ||
| //! | ||
| //! askama::i18n::load!(LOCALES); | ||
| //! | ||
| //! #[derive(Template)] | ||
| //! #[template(path = "example.html")] | ||
| //! struct ExampleTemplate<'a> { | ||
| //! #[locale] | ||
| //! loc: Locale<'a>, | ||
| //! name: &'a str, | ||
| //! } | ||
| //! | ||
| //! let template = ExampleTemplate { | ||
| //! loc: Locale::new(langid!("es-MX"), &LOCALES), | ||
| //! name: "Hilda", | ||
| //! }; | ||
| //! | ||
| //! // "<h1>¡Hola, Hilda!</h1>" | ||
| //! template.render().unwrap(); | ||
| //! ``` | ||
|
|
||
| use std::collections::HashMap; | ||
| use std::iter::FromIterator; | ||
|
|
||
| // Re-export conventiently as `askama::i18n::load!()`. | ||
| // Proc-macro crates can only export macros from their root namespace. | ||
| /// Load locales at compile time. See example above for usage. | ||
| pub use askama_derive::i18n_load as load; | ||
|
|
||
| pub use fluent_templates::{self, fluent_bundle::FluentValue, fs::langid, LanguageIdentifier}; | ||
| use fluent_templates::{Loader, StaticLoader}; | ||
| use parking_lot::const_mutex; | ||
|
|
||
| pub struct Locale<'a> { | ||
| loader: &'a StaticLoader, | ||
| language: LanguageIdentifier, | ||
| } | ||
|
|
||
| impl Locale<'_> { | ||
| pub fn new(language: LanguageIdentifier, loader: &'static StaticLoader) -> Self { | ||
| Self { loader, language } | ||
| } | ||
|
|
||
| pub fn translate<'a>( | ||
| &self, | ||
| msg_id: &str, | ||
| args: impl IntoIterator<Item = (&'a str, FluentValue<'a>)>, | ||
| ) -> Option<String> { | ||
| let args = HashMap::<&str, FluentValue<'_>>::from_iter(args); | ||
| let args = match args.is_empty() { | ||
| true => None, | ||
| false => Some(&args), | ||
| }; | ||
| self.loader.lookup_complete(&self.language, msg_id, args) | ||
| } | ||
| } | ||
|
|
||
| /// Similar to OnceCell, but it has an additional take() function, which can only be used once, | ||
| /// and only if the instance was never dereferenced. | ||
| /// | ||
| /// The struct is only meant to be used by the [`i18n_load!()`] macro. | ||
| /// Concurrent access will deliberately panic. | ||
| /// | ||
| /// Rationale: StaticLoader cannot be cloned. | ||
| #[doc(hidden)] | ||
| pub struct Unlazy<T>(parking_lot::Mutex<UnlazyEnum<T>>); | ||
|
|
||
| enum UnlazyEnum<T> { | ||
| Generator(Option<fn() -> T>), | ||
| Value(Box<T>), | ||
| } | ||
|
|
||
| impl<T> Unlazy<T> { | ||
| pub const fn new(f: fn() -> T) -> Self { | ||
| Self(const_mutex(UnlazyEnum::Generator(Some(f)))) | ||
| } | ||
|
|
||
| pub fn take(&self) -> T { | ||
| let f = match &mut *self.0.try_lock().unwrap() { | ||
| UnlazyEnum::Generator(f) => f.take(), | ||
| _ => None, | ||
| }; | ||
| f.unwrap()() | ||
| } | ||
| } | ||
|
|
||
| impl<T> std::ops::Deref for Unlazy<T> | ||
| where | ||
| Self: 'static, | ||
| { | ||
| type Target = T; | ||
|
|
||
| fn deref(&self) -> &Self::Target { | ||
| let data = &mut *self.0.try_lock().unwrap(); | ||
| let value: &T = match data { | ||
| UnlazyEnum::Generator(f) => { | ||
| *data = UnlazyEnum::Value(Box::new(f.take().unwrap()())); | ||
| match data { | ||
| UnlazyEnum::Value(value) => value, | ||
| _ => unreachable!(), | ||
| } | ||
| } | ||
| UnlazyEnum::Value(value) => value, | ||
| }; | ||
|
|
||
| // SAFETY: This transmutation is safe because once a value is assigned, | ||
| // it won't be unassigned again, and Self has static lifetime. | ||
| unsafe { std::mem::transmute(value) } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a bunch of dark magic. Why do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kijewski is the author of this section. I am sure they can tell you the details.
All I can tell is that this is an adjustment / workaround to an implementation of
fluent_templates::static_loader!, which is used to include the localization data into the compiled binary, and to validate all calls to thelocalize()template expr at compile time.