arrow-left arrow-right brightness-2 chevron-left chevron-right circle-half-full dots-horizontal facebook-box facebook loader magnify menu-down rss-box star twitter-box twitter white-balance-sunny window-close
How to manage app translations with low-code
5 min read

How to manage app translations with low-code

Low-code solution to manage all your app translations! It can solve the pain of maintaining multiple languages and translations in your websites and apps.
How to manage app translations with low-code

We all know the pain of maintaining multiple languages and translations in your websites and apps. There are new features that need to be deployed; on the other side, numerous translators are working with your translations. The complexity is growing exponentially with the number of languages your app needs to support.

This article demonstrates a quick and dirty low-code solution enabling you to manage all the translations in google sheets, share the file with multiple people, and easily create exportable JSONs.

The end result demo

The script was originally published in the medium article by Factory.hr. If you are interested in knowing the details of the implementation, I recommend you read the original article.

Create a google sheet file

Firstly, you will need to organise your translation similar to the one in the screenshot. The first column stores the translation keys and every other column stores corresponding translations.

Create Apps scripts

You will need to create an Apps Script: Open the sheet and navigate to Tools -> Script editor

Create two files in the Apps Script editor : one script file (let's call it Code.gs), one HTML file (let's call it Sidebar.html)

Code.gs file

Just copy-paste the contents below in the Code.gs file, and don't forget to save the results.

// Per: https://medium.com/@factoryhr/google-sheets-add-on-tutorial-exporting-key-value-column-pairs-to-json-56107e82b4ca
/**
 * Apps Script trigger. Runs when the add-on is installed.
 */
function onInstall(e) {
    /**
     * The document is already open, so after installation is complete
     * the Λ™onOpen()` trigger must be called manually in order for the
     * add-on to execute.
     */
    onOpen(e);
}
/**
 * Apps Script trigger. Runs when an editable document is opened.
 */
function onOpen(e) {
    /**
     * Create the Google Sheets add-on menu item in the navigation bar, and have it
     * call `showSidebar()` when clicked.
     */
    SpreadsheetApp.getUi()
        .createAddonMenu()
        .addItem('Export to JSON', 'showSidebar')
        .addToUi();
}
/**
 * Creates a new UI element from `Sidebar.html` and shows it.
 */
function showSidebar() {
    /**
     * Create UI from `Sidebar.html` and set the sidebar title.
     */
    var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
        .setTitle('Export to JSON');
    /**
     * Show UI as part of the application sidebar.
     */
    SpreadsheetApp.getUi()
        .showSidebar(ui);
}
/**
 * Stores active range value under provided `key`.
 *
 * @param {String} key β€” Property key
 */
function storeRange(key) {
    /**
     * Get active range from sheet.
     */
    var range = SpreadsheetApp.getActiveRange()
    /**
     * If the range is blank or undefined throw an error.
     */
    if (!range || range.isBlank()) {
        throw "Select a range!"
    }
    /**
     * Store the active range among document properties,
     * in A1 (R1:C1) notation.
     */
    PropertiesService.getDocumentProperties()
        .setProperty(key, range.getA1Notation())
}
/**
 * Retrieves range value assigned to provided `key`.
 *
 * @param {String} key β€” Property key
 */
function retrieveRange(key) {
    /**
     * Retrieve property from document properties.
     */
    var property = PropertiesService.getDocumentProperties()
        .getProperty(key)
    /**
     * If property is undefined throw an error.
     */
    if (!property) {
        throw "No value assigned to " + key + "!"
    }
    /**
     * Return range of cells.
     */
    return SpreadsheetApp.getActiveSpreadsheet()
        .getRange(property)
}
/**
 * Exports keys-value column pairs to JSON string.
 */
function exportToJson() {
    var properties = PropertiesService.getDocumentProperties()

    var keys = SpreadsheetApp.getActiveSheet()
        .getRange(properties.getProperty(PROPERTIES.KEYS))
        .getValues()

    console.log(keys);

    var values = SpreadsheetApp.getActiveSheet()
        .getRange(properties.getProperty(PROPERTIES.VALUES))
        .getValues()

    console.log(values);

    /**
     * Reduce keys and values into an object.
     */
    var result = keys.reduce(
        function(accumulator, current, index) {
            accumulator[current] = values[index][0]
            return accumulator
        }, {}
    )

    console.log(result);

    /**
     * Return stringified object.
     */
    return JSON.stringify(result)
}
/**
 * Constants for property names under which values are stored
 * in the document properties object.
 */
var PROPERTIES = {
    KEYS: 'KEYS',
    VALUES: 'VALUES',
}

function getKeysRange() {
    return retrieveRange(PROPERTIES.KEYS);
}

function getValuesRange() {
    return retrieveRange(PROPERTIES.VALUES);
}

function setKeysRange() {
    storeRange(PROPERTIES.KEYS)
}

function setValuesRange() {
    storeRange(PROPERTIES.VALUES)
}

Just copy-paste the contents below in the Sidebar.html file, and don't forget to save the results.

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
    <style>textarea { width: 100%; }</style>
  </head>
  <body>
    <div class="sidebar">
      <div class="block form-group">
        <button id="btn-set-keys">Set Keys</button>
        <button id="btn-set-values">Set Values</button>
      </div>
      <div class="block form-group">
        <button class="action" id="btn-export-to-json">Exsport to JSON</button>
      </div>
      <div class="block form-group">
        <label for="ta-result"><b>JSON Result</b></label>
        <textarea id="ta-result" rows="15"></textarea>
      </div>
      <div class="block">
        <span id="sp-status"></span>
        <span class="error" id="sp-error"></span>
      </div>
    </div>
    <script>
(function app() {

    function setKeys() {
        google.script.run
            .withSuccessHandler(
                function(element) {
                    spStatus.textContent = 'Keys set!'
                    spError.textContent = ''
                }
            )
            .withFailureHandler(
                function(message, element) {
                    spStatus.textContent = ''
                    spError.textContent = message
                }
            )
            .withUserObject(this)
            .setKeysRange()
    }

    function setValues() {
        google.script.run
            .withSuccessHandler(
                function(element) {
                    spStatus.textContent = 'Values set!'
                    spError.textContent = ''
                }
            )
            .withFailureHandler(
                function(message, element) {
                    spStatus.textContent = ''
                    spError.textContent = message
                }
            )
            .withUserObject(this)
            .setValuesRange()
    }

    function exportToJson() {
        google.script.run
            .withSuccessHandler(
                function(result, element) {
                    spStatus.textContent = 'Export successful!'
                    spError.textContent = ''
                    taResult.textContent = result
                }
            )
            .withFailureHandler(
                function(message, element) {
                    spStatus.textContent = ''
                    spError.textContent = message
                    taResult.textContent = ''
                }
            )
            .withUserObject(this)
            .exportToJson()
    }



    var btnSetKeys = document
        .getElementById('btn-set-keys')
        .addEventListener('click', setKeys)
    var btnSetValues = document
        .getElementById('btn-set-values')
        .addEventListener('click', setValues)
    var btnExporToJson = document
        .getElementById('btn-export-to-json')
        .addEventListener('click', exportToJson)
    var taResult = document
        .getElementById('ta-result')
    var spStatus = document
        .getElementById('sp-status')
    var spError = document
        .getElementById('sp-error')



})();
</script>
</body>
</html>

Reload the sheet

You only need to reload the sheet and launch the script here Add-ons -> Translations JSON generator -> Export to JSON

Voila

{
  "app.header": "PeakFlo - the AR automations",
  "app.login": "Login",
  "app.logout": "Log out",
  "app.hero.title": "Everyone wants their{linebreak}invoices paid faster"
}

Enjoying these posts? Subscribe for more

Subscribe now
Already have an account? Sign in
You've successfully subscribed to Untapped by Dmitry Vedenyapin.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.