Skip to content

Commit

Permalink
feat: added i18n support
Browse files Browse the repository at this point in the history
We use a system independent of Perseus because using Perseus' requires
inserting custom locales from a file, which is impossible in the browser
without modifying the `index.html` file.
  • Loading branch information
arctic-hen7 committed Dec 28, 2021
1 parent cd0e309 commit 03b505d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
1 change: 1 addition & 0 deletions examples/multilingual.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
languages:
en-US: basic.yml
default_language: en-US
13 changes: 11 additions & 2 deletions packages/tribble-app/src/templates/workflow/get_build_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,25 @@ pub async fn get_build_paths() -> RenderFnResult<Vec<String>> {
env::var("TRIBBLE_CONF").unwrap_or_else(|_| "../../../examples/basic.yml".to_string());
let root_cfg = Config::new(&root_cfg_file_path)?;
match root_cfg {
Config::Root { languages } => {
Config::Root { languages, .. } => {
// We use a custom i18n system to avoid having to inject locales into the root `index.html` file (I spent two hours on that...)
// We just generate a page for each language/workflow combination
// We assume workflows are the same for all languages, so we can choose a random one
match languages.keys().collect::<Vec<&String>>().get(0) {
Some(key) => {
let language_cfg_path = languages.get(&key.to_string()).unwrap(); // We selected a random key, it certainly should have an entry!
let language_cfg = Config::new(language_cfg_path)?;
match language_cfg {
Config::Language { workflows, .. } => {
// Loop through those workflows and create a new page for each locale/workflow combination
let mut pages = Vec::new();
for workflow_name in workflows.keys() {
for lang in languages.keys() {
pages.push(format!("{}/{}", lang, workflow_name));
}
}
// For each workflow, generate a separate page
Ok(workflows.keys().cloned().collect::<Vec<String>>())
Ok(pages)
}
// If a root file links to another root file, that's an invalid structure
Config::Root { .. } => Err(ParserError::RootLinksToRoot {
Expand Down
18 changes: 13 additions & 5 deletions packages/tribble-app/src/templates/workflow/get_build_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,26 @@ pub struct WorkflowProps {
#[perseus::autoserde(build_state)]
pub async fn get_build_state(
path: String,
locale: String,
_locale: String, // We use our own purpose-built i18n system
) -> RenderFnResultWithCause<WorkflowProps> {
// Strip off the `workflow/` section of the path (guaranteed to be there by Perseus)
let path = path.strip_prefix("workflow/").unwrap();

let root_cfg_path =
env::var("TRIBBLE_CONF").unwrap_or_else(|_| "../../../tribble.yml".to_string());
let root_cfg = Config::new(&root_cfg_path)?;
let input_err_msg;
// This will be a different part of the path depending on whether or not we're using i18n
let workflow_name;
// Get the workflows for the appropriate locale (if applicable)
let workflows = match root_cfg {
Config::Root { languages } => {
let path_vec: Vec<&str> = path.split('/').collect();
// These two parts are guaranteed by the `get_build_paths` code
let locale = path_vec[0];
workflow_name = path_vec[1];
// We want the language file for the current locale
let lang_cfg_path = match languages.get(&locale) {
let lang_cfg_path = match languages.get(locale) {
Some(path) => path,
// A language mismatch between Perseus and Tribble shouldn't be possible, because Tribble configures Perseus' locale settings
None => unreachable!(),
Expand Down Expand Up @@ -55,14 +64,13 @@ pub async fn get_build_state(
workflows,
input_err_msg: input_err_msg_l,
} => {
workflow_name = path;
input_err_msg = input_err_msg_l;
workflows
}
};
// Strip off the `workflow/` section of the path (Perseus guarantees that it will start with this)
let path = path.strip_prefix("workflow/").unwrap();
// Each workflow should match exactly to a page path (the pages are generated from the keys of the `workflows` map)
let workflow = match workflows.get(path) {
let workflow = match workflows.get(workflow_name) {
Some(workflow) => workflow,
None => unreachable!(),
};
Expand Down
8 changes: 7 additions & 1 deletion packages/tribble/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ async fn core(dir: PathBuf) -> Result<i32, Error> {
.map_err(|err| ServeError::ParserError { source: err })?;
if let Config::Root { languages } = cfg {
for (_, lang_file_cfg_path) in languages {
dbg!(lang_file_cfg_path);
watcher
.watch(&lang_file_cfg_path, RecursiveMode::Recursive)
.map_err(|err| ServeError::WatchFileFailed {
filename: lang_file_cfg_path,
source: err,
})?
}
}

Expand All @@ -125,6 +130,7 @@ async fn core(dir: PathBuf) -> Result<i32, Error> {
break Ok(build_exit_code);
}
}
// TODO Reload the browser automatically
}
Err(err) => break Err(ServeError::WatcherError { source: err }.into()),
}
Expand Down

0 comments on commit 03b505d

Please sign in to comment.