dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Multiple i18n concatenation

Open ThomasCartier opened this issue 1 year ago • 1 comments

Feature Request

Hi, I think it would be nice to have a way to concatenate multiple translation files in an easy API. Currently this is what I have:

#[macro_export]

macro_rules! local_concatenate_language {
        ( $upper_case: ident) => {{

                #[derive(Debug, Clone, Default, Deserialize, Serialize)]

                struct LanguageLocal {
                        id:    LanguageIdentifier,
                        texts: Text
                }

                let mut concatenated_json1: LanguageLocal = serde_json::from_str($upper_case).unwrap();

                let concatenated_json_2: LanguageLocal = serde_json::from_str(your_crate_path::$upper_case).unwrap();

                let concatenated_json_3: LanguageLocal = serde_json::from_str(your_crate_path2::$upper_case).unwrap();

                let json_1 = match &mut concatenated_json1.texts {
                        Text::Value(_) => unreachable!(),
                        Text::Texts(e) => e
                };

                let json_2 = match concatenated_json2.texts {
                        Text::Value(_) => unreachable!(),
                        Text::Texts(e) => e
                };

                let json_3 = match concatenated_json3.texts {
                        Text::Value(_) => unreachable!(),
                        Text::Texts(e) => e
                };

                json_1.extend(json_2);

                json_1.extend(json_3);

                let out_str = serde_json::to_string(&concatenated_json).unwrap();

                Language::from_str(&out_str).unwrap();

        }};
}

#[macro_export]

macro_rules! concatenate_all_languages {
        () => {{

                let mut languages: Vec<Language> = vec![];

                languages.push(local_concatenate_language!(EN_US));

                languages.push(local_concatenate_language!(FR_FR));

                use_init_i18n("fr-FR".parse().unwrap(), "en-US".parse().unwrap(), || languages);
        }};
}

I decided against recursive macros because:

  1. I am not good at it
  2. complicated to debug (see point 1)

But obviously, it doesn't scale. add a language or a i18n path and you are up for a change in that macro. maybe having dioxus looking for a certain file name in crates would help.

For example, if the spec says that files named dioxus_translations.rs are to be considered as i18n sources, then dioxus should concatenate them.

Then the i18n structure should be:

pub static FR_FR: &str = r#"{
        "id": "fr-FR",
        "texts": {
            "crate_name_unique_id_given_by_the_dev":{
                  "your_anchor": {
                      ...
                  }
           }
       }
    }"#;

any issue with the file structure should be a hard compile time error explaining why. That way we should not have overlapping rules. This should be the dev responsibility to add a unique crate name so that it doesn't occur.

All in all, it would be nice to just have to write use_init_i18n("fr-FR".parse().unwrap(), "en-US".parse().unwrap()) and be done with it.

I currently build a large fullstack website with dashboards and all using Dioxus and this is my only gripe so far. Because I made multiple components and crates and a single translation file in one place doesn't make sense. They are spread out in each crate to keep the components logically separated.

what's your opinion?

ThomasCartier avatar Jun 01 '24 15:06 ThomasCartier

..or translation files in the asset folder, since it is watched for changes, or a specific directory "translations" that dioxus cli would create..

ThomasCartier avatar Jun 01 '24 15:06 ThomasCartier