Properly support multiple languages
This commit is contained in:
parent
811c06f5f8
commit
1256fef318
@ -38,16 +38,10 @@ async fn main() -> eyre::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn say_hello(Path((_lang, name)): Path<(String, String)>) -> impl IntoResponse {
|
||||
// TODO This should be translated with Fluent!
|
||||
|
||||
//let template = templates.prepare("say_hello", None, Params::default().set("name", name));
|
||||
|
||||
Rendered(render_template_string!(TEMPLATING, say_hello, "en-GB", {
|
||||
async fn say_hello(Path((lang, name)): Path<(String, String)>) -> impl IntoResponse {
|
||||
Rendered(render_template_string!(TEMPLATING, say_hello, lang, {
|
||||
name: name
|
||||
}))
|
||||
|
||||
// HtmlTemplate(template)
|
||||
}
|
||||
|
||||
struct Rendered(Result<String, hornbeam::TemplateError>);
|
||||
|
1
demo_hornbeam_project/translations/fr-FR/say_hello.ftl
Normal file
1
demo_hornbeam_project/translations/fr-FR/say_hello.ftl
Normal file
@ -0,0 +1 @@
|
||||
hello = Bonjour { $name } !
|
@ -10,7 +10,6 @@ use hornbeam_interpreter::localisation::fluent::{
|
||||
FluentLocalisationError, FluentLocalisationSystem,
|
||||
};
|
||||
use hornbeam_interpreter::{InterpreterError, LoadedTemplates};
|
||||
use notify::Watcher;
|
||||
use std::convert::Infallible;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
@ -23,7 +22,6 @@ pub use hornbeam_interpreter::Params;
|
||||
|
||||
use crate::interpreted::hot_reload::start_hot_reloader;
|
||||
pub use lazy_static::lazy_static;
|
||||
use tokio::io;
|
||||
|
||||
#[cfg(feature = "hot_reload")]
|
||||
pub mod hot_reload;
|
||||
@ -174,7 +172,7 @@ macro_rules! render_template_string {
|
||||
// TODO LOCALE
|
||||
{
|
||||
let manager = $manager.load();
|
||||
let prepared = manager.prepare(stringify!($template_name), None, $crate::interpreter_params!{ $($params)* });
|
||||
let prepared = manager.prepare(stringify!($template_name), None, $crate::interpreter_params!{ $($params)* }, $locale);
|
||||
let finished_string = prepared.render_to_string();
|
||||
if $crate::is_hot_reload_enabled() {
|
||||
// Hacky, but inject the auto-hot-reloader into the page :P
|
||||
|
@ -28,6 +28,7 @@ pub(crate) struct Interpreter<'a, O, LS> {
|
||||
pub(crate) program: &'a BTreeMap<String, Arc<Vec<Step>>>,
|
||||
pub(crate) output: O,
|
||||
pub(crate) localisation: Arc<LS>,
|
||||
pub(crate) locale: String,
|
||||
pub(crate) scopes: Vec<Scope<'a>>,
|
||||
}
|
||||
|
||||
@ -577,7 +578,7 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
|
||||
|
||||
let localised_text = self
|
||||
.localisation
|
||||
.lookup(trans_key, ¶meters_evaluated)
|
||||
.lookup(trans_key, ¶meters_evaluated, &self.locale)
|
||||
.map_err(|underlying| InterpreterError::Localisation {
|
||||
underlying,
|
||||
trans_key: (trans_key as &str).to_owned(),
|
||||
|
@ -24,6 +24,7 @@ pub trait LocalisationSystem {
|
||||
&self,
|
||||
trans_key: &str,
|
||||
params: &BTreeMap<&str, Value>,
|
||||
locale: &str,
|
||||
) -> Result<Cow<str>, Self::Error>;
|
||||
}
|
||||
|
||||
@ -148,6 +149,7 @@ impl<'a, LS> LoadedTemplates<LS> {
|
||||
template_name: &str,
|
||||
fragment_name: Option<&str>,
|
||||
params: Params,
|
||||
locale: String,
|
||||
) -> PreparedTemplate<LS> {
|
||||
PreparedTemplate {
|
||||
all_instructions: Arc::new(self.template_functions.clone()),
|
||||
@ -158,6 +160,7 @@ impl<'a, LS> LoadedTemplates<LS> {
|
||||
},
|
||||
variables: params,
|
||||
localisation: self.localisation.clone(),
|
||||
locale,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,6 +170,7 @@ pub struct PreparedTemplate<LS> {
|
||||
pub(crate) entrypoint: String,
|
||||
pub(crate) variables: Params,
|
||||
pub(crate) localisation: Arc<LS>,
|
||||
pub(crate) locale: String,
|
||||
}
|
||||
|
||||
impl<LS: LocalisationSystem + Sync + Send> PreparedTemplate<LS> {
|
||||
@ -179,6 +183,7 @@ impl<LS: LocalisationSystem + Sync + Send> PreparedTemplate<LS> {
|
||||
program: &self.all_instructions,
|
||||
output,
|
||||
localisation: self.localisation,
|
||||
locale: self.locale,
|
||||
scopes: vec![Scope {
|
||||
variables: self.variables.params,
|
||||
slots: Default::default(),
|
||||
|
@ -18,6 +18,7 @@ impl LocalisationSystem for NoLocalisation {
|
||||
&self,
|
||||
_trans_key: &str,
|
||||
_params: &BTreeMap<&str, Value>,
|
||||
_locale: &str,
|
||||
) -> Result<Cow<str>, Self::Error> {
|
||||
Err("No localisation support available.")
|
||||
}
|
||||
@ -34,6 +35,7 @@ impl LocalisationSystem for DebugLocalisationSystem {
|
||||
&self,
|
||||
trans_key: &str,
|
||||
params: &BTreeMap<&str, Value>,
|
||||
_locale: &str,
|
||||
) -> Result<Cow<str>, Self::Error> {
|
||||
Ok(Cow::from(format!("@{trans_key}{{{params:?}}}")))
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ use crate::engine::Value;
|
||||
use crate::interface::LocalisationSystem;
|
||||
use fluent_templates::fluent_bundle::types::FluentNumber;
|
||||
use fluent_templates::fluent_bundle::FluentValue;
|
||||
use fluent_templates::loader::langid;
|
||||
use fluent_templates::{ArcLoader, LanguageIdentifier, Loader};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
@ -60,6 +59,9 @@ pub enum FluentLocalisationError {
|
||||
#[error("no translation found for {trans_key} in {lang_id}")]
|
||||
NoTranslation { trans_key: String, lang_id: String },
|
||||
|
||||
#[error("bad language ID {lang_id:?}")]
|
||||
BadLocale { lang_id: String },
|
||||
|
||||
#[error("can't convert param {param_name} of type {param_type} to a fluent type")]
|
||||
IncompatibleValue {
|
||||
param_name: String,
|
||||
@ -74,8 +76,14 @@ impl LocalisationSystem for FluentLocalisationSystem {
|
||||
&self,
|
||||
trans_key: &str,
|
||||
params: &BTreeMap<&str, Value>,
|
||||
locale: &str,
|
||||
) -> Result<Cow<str>, Self::Error> {
|
||||
let li: LanguageIdentifier = langid!("en-GB"); // TODO get the language tag from somewhere
|
||||
let li: LanguageIdentifier =
|
||||
LanguageIdentifier::from_bytes(locale.as_bytes()).map_err(|_| {
|
||||
FluentLocalisationError::BadLocale {
|
||||
lang_id: locale.to_owned(),
|
||||
}
|
||||
})?;
|
||||
let mut mapped_params = HashMap::with_capacity(params.len());
|
||||
for (&k, v) in params {
|
||||
if let Some(mapped_val) = interpreter_value_to_fluent_value(v) {
|
||||
|
Loading…
Reference in New Issue
Block a user