Lang.js icon indicating copy to clipboard operation
Lang.js copied to clipboard

Returning array

Open jonasgrosch opened this issue 6 years ago • 8 comments

It would be nice if defining an array as an translation value would be possible. It'S possible inside laravel itself and im using it for this purpose. If i define a value in Lang.js though it returns the key instead of the array.

jonasgrosch avatar Apr 05 '18 13:04 jonasgrosch

I had a short look in the source code. This should be the part where the changes need to be made:

Lang.prototype._getMessage = function(key, locale) {
        locale = locale || this.getLocale();
        key = this._parseKey(key, locale);

        // Ensure message source exists.
        if (this.messages[key.source] === undefined && this.messages[key.sourceFallback] === undefined) {
            return null;
        }

        // Get message from default locale.
        var message = this.messages[key.source];
        var entries = key.entries.slice();
        var subKey = '';
        while (entries.length && message !== undefined) {
            var subKey = !subKey ? entries.shift() : subKey.concat('.', entries.shift());
            if (message[subKey] !== undefined) {
                message = message[subKey]
                subKey = '';
            }
        }

        // Get message from fallback locale.
        if (typeof message !== 'string' && this.messages[key.sourceFallback]) {
            message = this.messages[key.sourceFallback];
            entries = key.entries.slice();
            subKey = '';
            while (entries.length && message !== undefined) {
                var subKey = !subKey ? entries.shift() : subKey.concat('.', entries.shift());
                if (message[subKey]) {
                    message = message[subKey]
                    subKey = '';
                }
            }
        }

        if (typeof message !== 'string') {
            return null;
        }

        return message;
    };

I guess it's enough to change the to typeof message conditionals with a simple !message

jonasgrosch avatar Apr 05 '18 14:04 jonasgrosch

@jonasgrosch I'm curious to know what would be the use case of having an array instead of string for a localization string?

rmariuzzo avatar Apr 05 '18 21:04 rmariuzzo

@rmariuzzo I use it for QA section for example. It makes it possible to have a different amount of questions/answers on different languages.

In general i try to avoid using any 'language' in my code and centralize all around my localization files, because some of my projects lead to a high amount of wording changes and it's just way more easy to apply them this way. This leads to some use cases for array returning.

jonasgrosch avatar Apr 07 '18 11:04 jonasgrosch

Changing typeof message !== 'string' to !message appears to be working for me. I use this for the same thing. A QA page. Copywriters can just add new QA's to the array and they will show up without me adding them to the code.

andredewaard avatar May 04 '18 08:05 andredewaard

@andre-dw I got some edge cases where this solution leads to problems. My current overwrite for the function is the following:

// Enable Array returning
Lang.prototype._getMessage = function (key, locale) {
  locale = locale || this.getLocale()
  key = this._parseKey(key, locale)

  // Ensure message source exists.
  if (this.messages[key.source] === undefined && this.messages[key.sourceFallback] === undefined) {
    return null
  }

  // Get message from default locale.
  let message = this.messages[key.source]
  let entries = key.entries.slice()
  let subKey = ''
  while (entries.length && message !== undefined) {
    subKey = !subKey ? entries.shift() : subKey.concat('.', entries.shift())
    if (message[subKey] !== undefined) {
      message = message[subKey]
      subKey = ''
    }
  }

  if (typeof message !== 'string' && !Array.isArray(message)) {
    return null
  }

  return message
}
```

jonasgrosch avatar May 05 '18 10:05 jonasgrosch

It's better verify if the message is an object:

if (typeof message !== 'string' && typeof message !== 'object') {
    return null;
}

In my case sometimes I use an object for a select, iterate it and make the options.

eossa avatar Nov 01 '18 14:11 eossa

Will this every be implemented?

andredewaard avatar Sep 19 '19 10:09 andredewaard

You can get an array in this way:

lang.messages[lang.locale + '.app'].myArray

dhi2 avatar Jun 18 '21 16:06 dhi2