app-framework icon indicating copy to clipboard operation
app-framework copied to clipboard

Script for I18n keys in pages

Open teddy-dubal opened this issue 8 years ago • 3 comments

Hi I made a script that crawl pages , in order to get translation keys in pages.

/*

  Purpose: Update app/lang/[locale].json file according language keys.

*/

'use strict'

// Include modules
let env = require('./env')
let alert = require('./alert')
let found = require('./found')
let fs = require('fs-extra')
let path = require('path')
let rec = require('recursive-readdir')
let sort = require('sort-keys-recursive')

/**
 * Load i18n reference file
 * @param {string} lang 
 */
function loadI18nFile(lang) {
  alert(`Loading keys in lang/${lang}.json file in progress ...`)
  return new Promise((resolve, reject) => {
    let file = path.resolve(env.app, `lang/${lang}.json`)
    if (found(file)) {
      fs.readJson(file, function (err, json) {
        if (err) {
          reject(`Keys loading failed. Please check the lang/${lang}.json file.`)
        } else {
          resolve(json)
        }
      })
    } else {
      reject('File not found')
    }
  })
}
/**
 * Scan pages , in order to find keys
 */
function scanPages() {
  alert('Scan project pages in progress ...')
  return new Promise((resolve, reject) => {
    let pagesFolder = path.resolve(env.app, 'pages')
    const regex = /\$lang\(['''|'"'](.*?)['''|'"']\)/g;
    rec(pagesFolder, function (err, pages) {
      if (err) {
        reject('Failed to read pages folder.')
      } else {
        let keys = []
        for (let p = 0; p < pages.length; p++) {
          let str = fs.readFileSync(pages[p], 'utf8')
          let m
          while ((m = regex.exec(str)) !== null) {
            if (m.index === regex.lastIndex) {
              regex.lastIndex++;
            }
            keys.push(m[1])
          }
        }
        resolve(keys)
      }
    })
  })
}

/**
 * 
 * @param {Object} storedKeys 
 * @param {array} newKeys 
 */
function diffKeys(storedKeys,newKeys) {
  alert('Finding new keys in progress ...')
  return new Promise((resolve, reject) => {
    let keys = newKeys.filter(k=> {
      return !storedKeys[k]
    })
    resolve(keys)
  })
}
/**
 * Save new keys in i18n file
 * 
 * @param {Object} storedKeys 
 * @param {array} diffKeys 
 * @param {Object} params 
 */
function saveKeys(storedKeys,diffKeys,params){
  let lang = params.lang || env.cfg.defaultLanguage
  let prefix = params.prefix || '__'
  return new Promise((resolve, reject) => {
    let ObjDiffKeys = {}
    diffKeys.forEach(key => {
      ObjDiffKeys[key] = `${prefix}${key}`
    })
    let keysToStore = Object.assign(storedKeys,ObjDiffKeys)
    let file = path.resolve(env.app, `lang/${lang}.json`)
    try {
      fs.writeJsonSync(file, sort(keysToStore), { spaces: 2 })
      resolve(true)
    } catch (error) {
      reject(`An error occure when saving ${lang}.json file`,)
    }
  })
}
// Run
let lang = env.arg.lang || env.cfg.defaultLanguage
let prefix = env.arg.prefix || '__'

//Step 1 : Load lang/[locale].json file
loadI18nFile(lang).then(storedKeys=>{
  alert(`Keys loading in file ${lang}.json done.`)
  //Step 2 : Scan project pages
  scanPages().then(newKeys=>{
    alert('Scanning done')
    //Step 3 : Find new Keys
    diffKeys(storedKeys,newKeys).then(diffKeys=>{
      //Keys to save
      alert(`${diffKeys.length} new keys to save`)
      //Step 4 : Save keys in [locale].json file
      saveKeys(storedKeys,diffKeys,{lang,prefix}).then(saved=>{
        alert(`I18n Keys saved in ${lang}.json`)
      },err=>{
        alert(err,'error')
      })
    },err=> {
      alert(err,'error')
    })
  },err => {
    alert(err,'error')
  })
},err=>{
alert(err,'error')
})

teddy-dubal avatar Nov 02 '17 19:11 teddy-dubal

@teddy-dubal - Cool, I will take a close look soon :-)

scriptPilot avatar Nov 03 '17 16:11 scriptPilot

What about the case the language pattern have parameters? Example: $lang('helloUser', {name: 'Tom'}). May you add that support in the regexp and make a pull request?

scriptPilot avatar Nov 03 '17 17:11 scriptPilot

Oups , i forgot this case. I solve the problem , and i make a pull request

teddy-dubal avatar Nov 04 '17 15:11 teddy-dubal