Merge pull request #132 from batisteo/i18n

i18n basic configuration and trans Tera tag
This commit is contained in:
Vincent Prouillet 2018-01-16 13:42:32 +01:00 committed by GitHub
commit 7a2c26a71f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 5 deletions

View file

@ -1,7 +1,7 @@
#[macro_use] #[macro_use]
extern crate clap; extern crate clap;
use clap::Shell; // use clap::Shell;
include!("src/cli.rs"); include!("src/cli.rs");

View file

@ -38,7 +38,7 @@ pub struct Config {
/// Description of the site /// Description of the site
pub description: Option<String>, pub description: Option<String>,
/// The language used in the site. Defaults to "en" /// The language used in the site. Defaults to "en"
pub language_code: Option<String>, pub default_language: Option<String>,
/// Whether to generate RSS. Defaults to false /// Whether to generate RSS. Defaults to false
pub generate_rss: Option<bool>, pub generate_rss: Option<bool>,
/// The number of articles to include in the RSS feed. Defaults to unlimited /// The number of articles to include in the RSS feed. Defaults to unlimited
@ -50,6 +50,9 @@ pub struct Config {
/// Whether to compile the `sass` directory and output the css files into the static folder /// Whether to compile the `sass` directory and output the css files into the static folder
pub compile_sass: Option<bool>, pub compile_sass: Option<bool>,
/// Languages list and translated strings
pub translations: Option<HashMap<String, Toml>>,
/// All user params set in [extra] in the config /// All user params set in [extra] in the config
pub extra: Option<HashMap<String, Toml>>, pub extra: Option<HashMap<String, Toml>>,
@ -74,13 +77,14 @@ impl Config {
Err(e) => bail!(e) Err(e) => bail!(e)
}; };
set_default!(config.language_code, "en".to_string()); set_default!(config.default_language, "en".to_string());
set_default!(config.highlight_code, false); set_default!(config.highlight_code, false);
set_default!(config.generate_rss, false); set_default!(config.generate_rss, false);
set_default!(config.rss_limit, 20); set_default!(config.rss_limit, 20);
set_default!(config.generate_tags_pages, false); set_default!(config.generate_tags_pages, false);
set_default!(config.generate_categories_pages, false); set_default!(config.generate_categories_pages, false);
set_default!(config.compile_sass, false); set_default!(config.compile_sass, false);
set_default!(config.translations, HashMap::new());
set_default!(config.extra, HashMap::new()); set_default!(config.extra, HashMap::new());
match config.highlight_theme { match config.highlight_theme {
@ -166,12 +170,13 @@ impl Default for Config {
highlight_code: Some(true), highlight_code: Some(true),
highlight_theme: Some("base16-ocean-dark".to_string()), highlight_theme: Some("base16-ocean-dark".to_string()),
description: None, description: None,
language_code: Some("en".to_string()), default_language: Some("en".to_string()),
generate_rss: Some(false), generate_rss: Some(false),
rss_limit: Some(10_000), rss_limit: Some(10_000),
generate_tags_pages: Some(true), generate_tags_pages: Some(true),
generate_categories_pages: Some(true), generate_categories_pages: Some(true),
compile_sass: Some(false), compile_sass: Some(false),
translations: None,
extra: None, extra: None,
build_timestamp: Some(1), build_timestamp: Some(1),
} }
@ -302,4 +307,27 @@ a_value = 10
assert_eq!(extra["hello"].as_str().unwrap(), "world".to_string()); assert_eq!(extra["hello"].as_str().unwrap(), "world".to_string());
assert_eq!(extra["a_value"].as_integer().unwrap(), 10); assert_eq!(extra["a_value"].as_integer().unwrap(), 10);
} }
#[test]
fn can_use_language_configuration() {
let config = r#"
base_url = "https://remplace-par-ton-url.fr"
default_language = "fr"
[translations]
[translations.fr]
title = "Un titre"
[translations.en]
title = "A title"
"#;
let config = Config::parse(config);
assert!(config.is_ok());
let translations = config.unwrap().translations.unwrap();
assert_eq!(translations["fr"]["title"].as_str().unwrap(), "Un titre");
assert_eq!(translations["en"]["title"].as_str().unwrap(), "A title");
}
} }

View file

@ -259,6 +259,7 @@ impl Site {
} }
pub fn register_tera_global_fns(&mut self) { pub fn register_tera_global_fns(&mut self) {
self.tera.register_global_function("trans", global_fns::make_trans(self.config.clone()));
self.tera.register_global_function("get_page", global_fns::make_get_page(&self.pages)); self.tera.register_global_function("get_page", global_fns::make_get_page(&self.pages));
self.tera.register_global_function("get_section", global_fns::make_get_section(&self.sections)); self.tera.register_global_function("get_section", global_fns::make_get_section(&self.sections));
self.tera.register_global_function( self.tera.register_global_function(

View file

@ -21,6 +21,21 @@ macro_rules! required_string_arg {
}; };
} }
pub fn make_trans(config: Config) -> GlobalFn {
let translations_config = config.translations.unwrap();
let default_lang = to_value(config.default_language.unwrap()).unwrap();
Box::new(move |args| -> Result<Value> {
let key = required_string_arg!(args.get("key"), "`trans` requires a `key` argument.");
let lang_arg = args.get("lang").unwrap_or(&default_lang).clone();
let lang = from_value::<String>(lang_arg).unwrap();
let translations = &translations_config[lang.as_str()];
Ok(to_value(&translations[key.as_str()]).unwrap())
})
}
pub fn make_get_page(all_pages: &HashMap<PathBuf, Page>) -> GlobalFn { pub fn make_get_page(all_pages: &HashMap<PathBuf, Page>) -> GlobalFn {
let mut pages = HashMap::new(); let mut pages = HashMap::new();
for page in all_pages.values() { for page in all_pages.values() {
@ -111,7 +126,7 @@ pub fn make_get_taxonomy_url(tags: Option<Taxonomy>, categories: Option<Taxonomy
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{make_get_url, make_get_taxonomy_url}; use super::{make_get_url, make_get_taxonomy_url, make_trans};
use std::collections::HashMap; use std::collections::HashMap;
@ -186,4 +201,33 @@ mod tests {
args.insert("name".to_string(), to_value("random").unwrap()); args.insert("name".to_string(), to_value("random").unwrap());
assert!(static_fn(args).is_err()); assert!(static_fn(args).is_err());
} }
#[test]
fn can_translate_a_string() {
let trans_config = r#"
base_url = "https://remplace-par-ton-url.fr"
default_language = "fr"
[translations]
[translations.fr]
title = "Un titre"
[translations.en]
title = "A title"
"#;
let config = Config::parse(trans_config).unwrap();
let static_fn = make_trans(config);
let mut args = HashMap::new();
args.insert("key".to_string(), to_value("title").unwrap());
assert_eq!(static_fn(args.clone()).unwrap(), "Un titre");
args.insert("lang".to_string(), to_value("en").unwrap());
assert_eq!(static_fn(args.clone()).unwrap(), "A title");
args.insert("lang".to_string(), to_value("fr").unwrap());
assert_eq!(static_fn(args.clone()).unwrap(), "Un titre");
}
} }