Skip to content

Translations of app messages#138

Merged
jhelvy merged 13 commits intosurveydown-dev:mainfrom
StefanMunnes:add_translations
Nov 22, 2024
Merged

Translations of app messages#138
jhelvy merged 13 commits intosurveydown-dev:mainfrom
StefanMunnes:add_translations

Conversation

@StefanMunnes
Copy link
Copy Markdown
Contributor

@StefanMunnes StefanMunnes commented Nov 12, 2024

I have finally managed it and am very happy with the implementation!

  1. there is a new translations.R file in the package, which contains all text elements and various translations as a list.
  2. the sd_server() function now contains an option that allows the selection of the language (pre-predefined: "en", "de", "es", "fr" or "it").
  3. a help file is prepared in the config() function, which saves the text elements ultimately used as translations.yml in _survey.
  4. all text output that could be visible to the respondents is taken from this file:

4.1 in server.R are:

  • warning required questions
  • rating of survey
  • cancel, submit, and exit buttons

4.2 in ui.R these are:

  • next, exit, buttons
  • label for select input "choose and option"
  • date input language (months, week days)
  • redirect elements

I have decided to make the translations available in ui.R as well. On the one hand, there are settings that the user cannot access themselves (e.g. date input, redirect elements). On the other hand, it saves effort for the user and is in the same workflow now. I have written the labels for the Next and Exit buttons so that they are only overwritten if it is not in English and the default has not been changed. So if something is entered manually, this always applies.

There is also the option for users to provide a translations.yml file in the root folder and replace all or individual text elements for a specified language with it. This is then also imported and populated in the corresponding language. In the event of problems, it always falls back to English.
This approach allows users to systematically change individual text elements, which would otherwise not be possible or would require significantly more effort. Changing the accessible label in survey.qmd is still possible without any problems.

However, I was wondering whether it's really still about translations or whether we should call it text_elements, survey_labels, or something similar. After all, phrases can also be adapted in English in this way.

I think this approach is promising and now gives me a good feeling of how a questions.yml file provided by the user can be implemented.

@warnes
Copy link
Copy Markdown

warnes commented Nov 12, 2024

Hi Stefan, how are translations of the actual question and response text handled?

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 12, 2024

Hi Stefan, how are translations of the actual question and response text handled?

That's not what this PR is about. This is about being able to provide alternative labels for all the hard-coded messaging throughout the app, like the pop-up window that comes up if you have a required question that you didn't answer. Currently all of those messages are hard-coded in English and users have no way to modify it. This PR addresses that and lets the user specify alternative text to use.

If you wanted to have a different language version of a survey question, that is something you can already define as a user by just using different labels in sd_question(). It would be nice to have an ability to create a fully translated version, but I also think it might just be easier to make a copy and translate it. Since it's all plain text in the survey.qmd file, it should be pretty straightforward.

With this in mind, I don't think "translations" is the appropriate thing to call this whole idea, because (as @StefanMunnes mentioned) this could be used to change the messages / labels to anything, not just another language. It could remain in English, but you just may want to use different phrasing, etc. I think something like "system_text" or "app_text" to make it clear that this is not "labels", which is might be associated with "question labels". This is all the other text in the system / app.

@StefanMunnes
Copy link
Copy Markdown
Contributor Author

StefanMunnes commented Nov 12, 2024

Hi and yes, @jhelvy is absolutely right in describing what I did. It's not about the labelling of the questions and answers, it's about the integrated system and the navigation messages. To also give the user the option to have them in the language of respondents from other countries, like Germany in my case. That's where the idea of "translations" comes from, but as I wrote, I now also think it makes more sense to formulate this whole process and the files rather as app_text, survey_text, system_text, or similar.

And I also thought that was what I was asking for in the feature request ;)

@StefanMunnes StefanMunnes changed the title Add translations Translations of app messages Nov 12, 2024
@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 12, 2024

I need to find some time to look through this, but I think we're aligned on what the goal is here.

I think app_text may be the more appropriate name. It's short and more distinct from translations. With that in mind, I think we should discuss this as a way to provide custom app text, e.g. for a different language. That suggests moving away from using the word translation in the code. I also noticed that it looks like you put the translation.yml file in the target folder. I think it should just be in the root directory, just like the survey.qmd and app.R. This makes a distinction from an output (everything in the _survey folder) and an input (things in the root directory). If you want to provide some existing translations as a template, that is okay. But I would like to think of this yml file as a place for the user to define any custom app text they want. It could be keyed by a particular value, e.g. "de", "en", etc. for languages, but could also be just anything they want, like "custom". Does that make sense?

@StefanMunnes
Copy link
Copy Markdown
Contributor Author

StefanMunnes commented Nov 12, 2024

I would not completely throw the concept of translation overboard in the proposed PR for two reasons:

  1. the main reason for changing the app texts will certainly be to translate it into another language. I think most people are fine with the default redirect wording or don't even need it, but it should be available in the language of the respondent.
  2. the focus on language choice also affects options such as displaying the correct translated month and days of the week for the questions with date input. For these, nothing can be rephrased, only translated.

The fact that there is a translations.yml file in the _survey folder also has two reasons:

  1. it is a help/config file that is created during formatting, similar to head.rds, so that it can then be used in the ui.R functions.
  2. by selecting a language and combining it with text elements provided by the user, this file provides a definite list of the text elements used, which can be tracked here.

This means that there can be two translations.yml (or app_text.yml) files. Always one in the _survey folder, which is a process and output file as written. As well as a user-created file in the root directory that provides parts or all of the changes/translations for the text elements. This file can also contain translations for multiple languages and only the selected language is then used.

I think this approach is a good template for the questions.yml files. We have already implemented the files in the _survey folder with all the questions that are actually used. Now you could also have a questions.yml file provided by the user in the root directory, which contains a collection of questions that could be used via the IDs in survey.qmd.

@StefanMunnes
Copy link
Copy Markdown
Contributor Author

StefanMunnes commented Nov 12, 2024

And besides the default English text elements, I provided four more translations users can use without manually providing a file: de, es, fr, and it. Of course, we can discuss which of them is necessary, but why not?

I would assume the usage as following:

60% use the default setting "en"
20% switch to another default language via the sd_server(language = "..") function
15% create a complete translation via the translations.yml file in the root folder because their language is not available
5% want to change the wording for only 2 or 3 text elements in one of the preset languages and create a reduced translations.yml file for this purpose

And the way I have implemented it, the list and the translations.yml files are defined via the language at the top level

translations <- list(
    'en' = list(
        "cancel" = 'Cancel',
       "confirm_exit" = 'Confirm Exit',
       ...
    )
)

To sum it up, I think the translation is the focal point in terms of logic and usage. What the files are called in the end is not important to me, but the documentation of the implementation should make that clear.

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 13, 2024

Okay, I think I understand. I still haven't had a chance to look through the code (probably won't for a few more days), but I just wanted to make sure I'm understanding what you did. I thought (perhaps incorrectly) that you were proposing users put a translations.yml file in the _survey folder to be used as an input to the app, which definitely felt wrong. It seems you are doing what I see as the correct approach - allow users to provide a translations.yml file in the root directory as an input, and also export a translations.yml file to the _survey folder just like how we do with questions.yml. That seems like a good UI.

So am I correct that users can set a language in sd_server() using one of the defaults you have already provided without providing a translations.yml in the root directory? Like, if they chose language = "fr" it would use French. But then if they chose language = "fr" and also provided a translations.yml file in the root that had some custom edits for "fr", those custom edits would be used, correct? If that is the intended UI, then I totally agree.

We'll have to do a good job writing up the documentation on the main website. I think maybe just add a new translations.qmd page in the main documentation section that explains how users can use this feature. I would also add a specific section noing that this can be used just to change the message text as well, even if it's in English.

@StefanMunnes
Copy link
Copy Markdown
Contributor Author

Correct, this is exactly how it works with my implementation.

I can try to prepare a page for the documentation, but you want to finally decide for a name of the two files?

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 13, 2024

I don't disagree with translation probably being the primary use case for this, but I'm concerned people might think this is for translating the entire survey (e.g., see the above comment by @warnes). It could easily be mis-interpreted.

A more precise description is it allows you to override the default text to all system messages in the survey. For that reason, I still lean towards calling the yml files something else, but we could still use a word related to "language". Maybe system_language.yml?

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 21, 2024

Okay I finally got a chance to go through this. I made some changes, hopefully you'll agree with them.

The biggest change is I did not like that you have a global translations list that is defined in the translation.R file. I strongly prefer that such a list be generated by a function and called locally inside functions that use it, that way there aren't globally objects created when the package is loaded. So I converted that into a function called get_translations_default(), which just returns the default translations list.

I then changed what you previously had as get_translations() in run_config() to set_translations(), because this function seems to be "setting" the translations (saving them to the _survey/translations.yml file). That allowed me to use the name get_translations() for a function defined in the translations.R file as a "safe" way to obtain the translations list. That function will return the parsed _survey/translations.yml file if it exists, and otherwise it will return the English as the default. I then used this get_translations() function inside each of the functions in ui.R as well as in sd_server() to obtain the translations list. This approach just prevents errors in case the _survey/translations.yml file doesn't yet exist. But as soon as you run app.R it will get created, so it will almost always return the proper translation from the _survey/translations.yml file.

I also added the language argument in the sd_server() roxygen (it was missing).

Also, in sd_server() where you previously had code like translations[[language]][["warning"]], I changed this so that we can now just use translations[["warning"]]. I just moved the translations[[language]] part up earlier when defining translations, so there are just fewer brackets now.

Finally, when I documented the package I got warning messages about the non-ASCII characters in the translation.R file. So I worked with Claude to encode those characters in unicode to avoid the warning.

Can you take a look at these changes and see if everything still seems to be working?

@StefanMunnes
Copy link
Copy Markdown
Contributor Author

StefanMunnes commented Nov 22, 2024

I like all the changes and agree with them.

The Unicode encoding also works (tested for German).

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 22, 2024

Awesome. I just fixed one more small bug I found. For matrix questions, the stored _survey/question.yml file didn't include the is_matrix logic for the matrix sub-questions, which caused an error if the matrix question was required (I didn't notice it until I made questions required). That is a left over bug from the previous PR, has nothing to do with the translations.

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 22, 2024

I'm going to run the documentation again on this then will merge this as v0.4.2.

@jhelvy
Copy link
Copy Markdown
Collaborator

jhelvy commented Nov 22, 2024

Okay a few more updates:

  • I added you to the DESCRIPTION file as a contributor (thanks!)
  • I added a get_valid_languages() function and a sd_create_translations() helper function, which will create a templated translations.yml file in the project root. This makes it easier for users to customize their own messages.

@jhelvy jhelvy merged commit 4baec85 into surveydown-dev:main Nov 22, 2024
@StefanMunnes StefanMunnes deleted the add_translations branch November 23, 2024 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants