rmariuzzo/Lang.js

Returning array

Opened this issue ยท 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.

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 I'm curious to know what would be the use case of having an array instead of string for a localization string?

@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.

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.

@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
}
```
eossa commented

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.

Will this every be implemented?

dhi2 commented

You can get an array in this way:

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