Skip to content

Instantly share code, notes, and snippets.

@jbgutierrez
Created June 16, 2017 09:40
Show Gist options
  • Select an option

  • Save jbgutierrez/41bdfadaf92693f28c9e67a15d0044fc to your computer and use it in GitHub Desktop.

Select an option

Save jbgutierrez/41bdfadaf92693f28c9e67a15d0044fc to your computer and use it in GitHub Desktop.

Revisions

  1. jbgutierrez created this gist Jun 16, 2017.
    40 changes: 40 additions & 0 deletions Dict.coffee
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    class Dict
    constructor: (@g, @dict) ->
    @missings = []

    resolve: (content, showErrors=true, json=false, englishFallback=true) ->
    fail = false
    RE = if json then /"\{([^}^\s]+)\}"/g else /\{([^}^\s]+)\}/g
    content = content.replace RE, (m, n) =>
    replacement = @t n, showErrors, true, englishFallback
    fail or= not replacement?
    replacement = "\"#{replacement}\"" if json and replacement
    replacement
    content = undefined if fail
    content
    t: (key, showErrors=true, nestedInterpolations=true, englishFallback=true) =>
    fallbacks = [ @g.locale, @g.countryCode, @g.langCode ]
    fallbacks.push "en" if englishFallback
    result = @lookup key, fallbacks...
    result = @resolve result, showErrors, false, englishFallback if typeof result is 'string' and nestedInterpolations
    if showErrors and not result?
    @missings.push key
    result = "**" + key + "**"
    result

    lookup: (key, locales...) ->
    for locale in locales
    value = @dict[locale]?[key]
    return value if value?
    toJSON: (locale) ->
    return @dict unless locale
    json = {}
    json[key] = @t(key, false) for key in @keys()
    json
    keys: ->
    return @_keys if @_keys
    keys = (Object.keys(values) for _locale, values of @dict)
    @_keys = _.uniq _.flatten keys
    @_keys

    module.exports = Dict
    132 changes: 132 additions & 0 deletions source-compilation.coffee
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,132 @@
    # compilation
    code = coffee.compile @snippet, bare: true
    script = new vm.Script code

    # dictionaries setup
    dicts = {}
    contents = _.pluck @dictionaries, 'content'
    while _dict = contents.pop()
    for locale, values of _dict
    dict = dicts[locale] ?= {}
    _.extend dict, values

    meta =
    errors: undefined
    warnings: undefined
    type: @type
    count: 0
    content = {}

    sandbox =
    _: _
    at: (predicates...) ->
    includes = []
    excludes = []
    for predicate in predicates
    if /!/.test predicate
    excludes.push predicate.substring(1)
    else
    includes.push predicate

    location = document?.documentElement.id || 'unknown'
    for predicate in excludes
    return false if ~[sandbox.countryCode, sandbox.locale, sandbox.langCode].indexOf(predicate)

    for predicate in includes
    return true if ~[sandbox.countryCode, sandbox.locale, sandbox.langCode].indexOf(predicate)

    !!excludes.length
    ejs: (key) ->
    template = dict.t key
    throw Error "#{key} ejs template not found" unless template
    json: (key) ->
    json = dict.t key, false
    throw Error "#{key} json template not found" unless json
    _content = JSON.stringify json
    _content = dict.resolve _content, true, true
    JSON.parse _content
    languages: sails.config.languages
    stores: sails.config.stores
    formatPrice: (price) ->
    return price unless sandbox.store and sandbox.language and price and typeof price is 'number'
    formatPrice price, sandbox.store, sandbox.language
    formatDate: (strdate) ->
    format = dict.t 'shortDateFormat', false
    return strdate unless format and /\d\d\/\d\d\/20\d\d/.test strdate
    tokens = strdate.split('/')
    replacements =
    d: tokens[0]
    m: tokens[1]
    Y: tokens[2]
    format.replace(/%[admY]/g, (t) -> replacements[t[1]])

    # setup dict module
    dict = new Dict sandbox, dicts
    _.extend sandbox,
    t: (key, showErrors, nestedInterpolations) =>
    dict.t key, showErrors, nestedInterpolations, @englishFallback
    ctx: (key, showErrors, nestedInterpolations) =>
    dict.t key, showErrors, nestedInterpolations, @englishFallback

    project = ->
    try
    dict.missings = []
    result = script.runInNewContext sandbox
    return unless result?

    switch
    when sandbox.key then content[sandbox.key] = result
    when typeof result is 'string' then content.en = result
    else content = result

    if dict.missings.length
    meta.warnings ?= {}
    meta.warnings[sandbox.key] = 'missing-keys': dict.missings
    catch e
    meta.errors ?= {}
    meta.errors[sandbox.key] = e.message

    switch
    when @type is 'generic'
    sandbox.dict = dict.toJSON()
    project sandbox
    when @type is 'languages'
    for _langCode, language of sails.config.languages
    sandbox.language = language
    sandbox.langCode = language.code
    sandbox.key = language.code
    sandbox.dict = dict.toJSON sandbox.key
    project sandbox
    when @type is 'stores'
    for _storeCode, store of sails.config.stores
    continue if store.isHidden and not @includeHidden
    continue if not store.isOpenForSale and not @includeClosed
    sandbox.store = store
    sandbox.countryCode = store.countryCode
    sandbox.language = store.supportedLanguages[0]
    sandbox.langCode = store.supportedLanguages[0].code
    sandbox.locale = "#{sandbox.langCode}-#{sandbox.countryCode}"
    sandbox.key = sandbox.countryCode
    sandbox.dict = dict.toJSON sandbox.key
    project sandbox
    when @type is 'localizations'
    for _storeCode, store of sails.config.stores
    continue if store.isHidden and not @includeHidden
    continue if not store.isOpenForSale and not @includeClosed
    sandbox.store = store
    sandbox.countryCode = store.countryCode
    for language in store.supportedLanguages
    sandbox.language = language
    sandbox.langCode = language.code
    sandbox.locale = "#{sandbox.langCode}-#{sandbox.countryCode}"
    sandbox.key = sandbox.locale
    sandbox.dict = dict.toJSON sandbox.key
    project sandbox
    else
    throw Error "Projection type #{@type} not implemented!"

    try
    content = ejs.compile template, {}
    catch e
    console.error e
    throw e