Couchers-org / couchers

The next-generation couch surfing platform. Free forever. Community‑led. Non‑profit. Modern. Chuck us a star :)
https://couchers.org
MIT License
374 stars 78 forks source link

Replace all string constants with translation keys #4152

Open lucaslcode opened 2 years ago

lucaslcode commented 2 years ago

1. Translation keys

We need to replace all string constants with translation keys.

For example,

<HtmlMeta title={CONNECTIONS} />

should become

import { CONNECTIONS } from "i18n/namespaces";
...
const { t } = useTranslation(CONNECTIONS);
...
<HtmlMeta title={t("connections_page_title")} />

These translation keys with strings live in features/<featureName>/locales/en.json. However:

The translation keys should, as best as possible, describe the location or context of the string, not the text content. An example of a badly named key is "no_friends": "No friends available",. A well named key is "friends_list_empty": "No friends available",. If we wanted to change the text to "There aren't any friends here yet", no_friends would no longer make sense, but friends_list_empty does.

The features/auth folder is mostly complete, with good keys. Use this as a reference on how to implement translation keys.

react-i18next can handle interpolation, plurals and [formatting (https://www.i18next.com/translation-function/formatting) (click links for documentation). See this file for an example.

2. Use i18n abstracted import

We should also change all imports of react-i18next (or in our app, next-i18next) to use our abstracted i18n functions introduced in Couchers-org/couchers#2329. Simply change something like import { useTranslation } from "next-i18next"; to import { useTranslation } from "i18n";.

3. Use helper function for getStaticProps

Finally, the actual pages in the pages folder include their translations by exporting getStaticProps with the translation data. Couchers-org/couchers#2329 also introduced a helper function to make this much cleaner, turning this:

export const getStaticProps: GetStaticProps = async ({ locale }) => ({
  props: {
    ...(await serverSideTranslations(
      locale ?? "en",
      ["global", "profile"],
      nextI18nextConfig
    )),
  },
});

into this:

export const getStaticProps = translationStaticProps([GLOBAL, PROFILE]);

So all getStaticProps which only include translations (maybe that's all of them?) should use this with the relevant namespaces.

Separation of work

Comment below with what feature you would like to work on:

lucaslcode commented 2 years ago

Before starting, Couchers-org/couchers#2329 should be merged, and I will also do globals (as every feature may use globals).

papeldeorigami commented 2 years ago

I will continue working on the communities screens. Since it is a big feature, I started with communities/events - see Issue 2226 I still have to adjust to this new import pattern.

hint for this translation task it is important to run yarn test-ci after changes because some eslint errors are not checked with yarn test. For instance, references to deleted constants in other feature folders.

darrenvong commented 2 years ago

Yeah I think I will check auth and donations since I've done those. After that, I can pick up messages as well.

alesdvorakcz commented 2 years ago

I will start with Connections and then anything else what will be unassigned

dieterpankratz commented 2 years ago

I will take Profile.

lucaslcode commented 2 years ago

Just note, as you can see in Couchers-org/couchers#2394 there are loads of keys in the global namespace which shouldn't be there, particularly for profiles and communities

darrenvong commented 2 years ago

One more thing worth mentioning is that in some of the older UI code, there are still some stragglers which aren't extracted to constants! So if any of you see a hardcoded string in the area you are working in, they should also be extracted into the JSON following the guidelines in this issue.

papeldeorigami commented 2 years ago

FYI I will abort the branch I was working with. After trying to rebase it, I decided it is better to start from scratch. I will create one focused communities/events only and try to merge it as soon as possible. If the merge is successful, I will proceed with other communities' features.

papeldeorigami commented 2 years ago

Communities feature is now ready for merge, so I will proceed with Donations. I think I got to speed with these refactoring tasks, so if someone wants me to prioritize some specific domain, please let me know.