Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@doodle/i18n / dist / README.md
Size: Mime:

How to add internationalization to your project

Greenkeeper badge

There are several factors to adding internationalization capabilities to a project.

You might have to create a project in OneSky to store the translations that belong to your project. You might have to consume translations that are global to all Doodle projects too.

In any case, it's good to present an overview of what parts are involved in these processes before running any command so that you can grasp what things are running in the background and where/what to look for if something goes wrong.

OneSky administration (website part)

In order to log into OneSky, you need to get the credentials from somewhere (lastpass). Once this is done, you'll need to create a new project:

  • Select Regular Web App as a project type

  • Select English as base language

  • Later, you'll have to manually input one key in order to be able to continue creating the project. Just add one random key value pair that you will remove immediately after project creation.

  • In the multiple select translate to: select the following:

de, en, en_GB, es, fr, it

  • Click Create project

And voilà, your new project is live!

OneSky administration (local project part)

Now, you need to set up your project to communicate with OneSky properly.

Your project needs a couple of files:

  • .oneskyrc at the top level folder which contains something like:

    {
      "projectId": "141403",
      "fileName": "translations.json",
      "format": "HIERARCHICAL_JSON",
      "keepStrings": true,
      "dependentProjectIds": ["141403", "140993"]
    }
    

    NOTE: when moving keys from one parent to another set "keepStrings": "false", to remove deleted keys

    Where:

    • projectId is the value used to determine what project to upload translations to.
    • dependentProjectIds is the value used to determine what projects to download translations from. Example: @doodle/common-messages: 141403 and @doodle/users-api-connector: 140993
  • .env at the top level folder which contains something like:

    MY_OTHER_ENVIRONMENT_VARIABLE=bacon
    ONESKY_PUBLIC_KEY=lalalallelelelolololululu
    ONESKY_SECRET_KEY=20349bdcjkdh238edsfuisnd2
    

    These two keys (ONESKY_PUBLIC_KEY, ONESKY_SECRET_KEY) are necessary in order to both upload AND download translations.

    In your gulpfile.js:

    // eslint-disable-next-line global-require
    require('dotenv').config(); //required for using credentials from .env
    const onesky = require("@doodle/i18n/src/onesky");
    
    /**
     * Upload messages to Onesky for default language.
    
     * @description: This task will recursively search your project source and look for react-intl#defineMessages() calls.
     * It will then take the messages it finds in the defineMessages object and wrap them up in a way that OneSky can process. 
     * The generated file that is sent to OneSky will only be in your base language, which is probably set to `en`. This task
     * will also create (or overwrite the existing) i18n/en.json file. 
     */
    gulp.task("i18n:upload", async () => {
      onesky.uploadBaseMessagesFromSource();
    });
    
    /**
     * Upload messages to Onesky for all languages.
     *
     * @description: This task will read all of the json files that exist in the i18n directory, and upload them to replace/overwrite
     * the cooresponding translation file on OneSky. So, for example, if you have three files in your i18n directory named de-DE.json, en.json
     * and fr.json, then these files will get uploaded to OneSky and replace the existing OneSky translations for German (de-DE), English (en)
     * and French (fr). Question: Will this task interupt any on-going work on the keys for these translations on OneSky?
     */
    gulp.task("i18n:upload:all", async () => {
      onesky.uploadAllTranslations();
    });
    
    /**
     * Upload messages to Onesky
     *
     * @description: you would use this command if you have made local updates to any .json file you have in the i18n directory, and you want these 
     * local changes to be sent to OneSky. This task will take every .json file you have in your i18n directory and attempt to sync your updates to the 
     * translation files on OneSky. If you have includeValues set to `true` in the options parameter, then this task will run a diff against your local i18n/*.json
     * files and add new keys, update changed keys, remove deleted keys, and rename any renamed keys so that OneSky's keys are in sync with your local keys.
     * Question: What is a use-case where you would want to run this command with includeValues: false?
     */
    gulp.task("i18n:update", async () => {
      onesky.updateTranslations({ includeValues: true });
    });
    
    /**
     * Download messages from Onesky from project merged with messages from dependentProjectIds
     *
     * @description: This task will fetch the merged translations (of all the target languages in OneSky), and generate a single .json 
     * file that makes up all the support languages in your project. This is the file that you will want to bundle with your app for production use.
     * It is important to note that any projects you have included in the `dependentProjectIds` of your .oneskyrc file will also be included in this
     * merged file, BUT, even if your dependentProjectIds array is empty, your project's translations will be be included in this bundle. So you will
     * always want to run this task to prepare for your production builds, regardless if you have specified dependentProjectIds. 
     */
    gulp.task("i18n:download:merged", async () => {
      const result = await onesky.downloadAllTranslations({
        i18nPath: "./i18n/merged"
      });
    });
    
    /**
     * Download messages from Onesky from single project.
     *
     * @description: This task is useful only for keeping your project's i18n/*.json files in sync with OneSky. This lets you keep your 
     * translated files from OneSky under version control, so if you ever accidently mess up your translations, you have files in your i18n directory
     * which can be used to revery your OneSky translations to a backup. It is recomended that you always use this command during local development, and
     * then use the `i18n:download:merged` task when you are ready to bundle for production.
     */
    gulp.task("i18n:download", async () => {
      onesky.downloadAllTranslations({ dependentProjectIds: [] });
    });
    
  • This module can also work with @doodle/vault instead of the ONESKY_SECRET_KEY and ONESKY_PUBLIC_KEY environment variables.

    vault login -method github
    # Enter your GitHub developer access token with `read:org` permissions
    yarn add @doodle/i18n @doodle/vault
    

    In your gulpfile.js:

    const { Vault, getToken } = require("@doodle/vault");
    const onesky = require("@doodle/i18n/src/onesky");
    
    const getOneSkyCredentials = async () => {
      const token = await getToken({});
      const vault = Vault({ token });
      const { data: credentials } = await vault.read(
        "secret/doodle/staging/onesky/credentials"
      );
      return credentials;
    };
    
    /**
     * Upload messages to Onesky for default language
     */
    gulp.task("i18n:upload", async () => {
      const credentials = await getOneSkyCredentials();
      onesky.uploadBaseMessagesFromSource({ credentials });
    });
    
    /**
     * Upload messages to Onesky for all languages
     */
    gulp.task("i18n:upload:all", async () => {
      const credentials = await getOneSkyCredentials();
      onesky.uploadAllTranslations({ credentials });
    });
    
    /**
     * Upload messages to Onesky
     */
    gulp.task("i18n:update", async () => {
      const credentials = await getOneSkyCredentials();
      onesky.updateTranslations({ credentials, includeValues: true });
    });
    
    /**
     * Download messages from Onesky from project merged with messages from dependentProjectIds
     */
    gulp.task("i18n:download:merged", async () => {
      const credentials = await getOneSkyCredentials();
      await onesky.downloadAllTranslations({
        credentials,
        i18nPath: "./i18n/merged"
      });
    });
    
    /**
     * Download messages from Onesky from single project
     */
    gulp.task("i18n:download", async () => {
      const credentials = await getOneSkyCredentials();
      onesky.downloadAllTranslations({ credentials, dependentProjectIds: [] });
    });
    

Keys that are local to your project

Create a messages.js file per component you want to translate and put it in the component's folder.

It will look like something like this:

import { defineMessages } from 'react-intl';

export default defineMessages({
  createADoodle: {
    id: 'contentProxy.components.SiteHeader.createADoodle',
    defaultMessage: 'Create a Doodle',
  },
});

Upload them to OneSky with the gulp task:

gulp i18n:upload

Keys that are global for all Doodle projects

Download them from OneSky with the gulp task:

gulp i18n:download

How to publish

After merging your PR go to master, pull the changes and update the version in package.json. Push the new commit.

Build and publish from the root project directory:

yarn; yarn build; npm publish ./