vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

In-messages default values for interpolations

Open pyncz opened this issue 1 year ago • 1 comments

Clear and concise description of the problem

Would be more safe (in context of unwanted empty strings) and nice if there was an option to set default value for Named and List interpolations. A couple of usage examples below:

Default values

Let's say, we have a translation that is used with a specific interpolation value most of the time, but sometimes it's needed to pass another argument.

We have to pass that most-often-used value every time. Moreover, nest the translations to reach a desired behaviour.

# messages
posts: posts
search: Look for {object}
<search-input :placeholder="$t('search', { object: $t('posts') })" />

Obviously, it works, but looks kinda heavy. Just compare how it could be with default interpolations' values:

<search-input :placeholder="$t('search')" />

Optional values

Another example is about optional fields used as interpolations' values.

# messages
greeting: Hello {to}!
<!-- let's assume user.username is optional -->
<p>{{ $t('greeting', { to: user.username }) }}</p>

In this case we get Hello, ! as the output, so we have to add some fallback conditions:

<p>{{ $t('greeting', { to: user.username ?? $t('someFallbackValueYouHaveToUseEveryTime') }) }}</p>

Suggested solution

Add syntax for applying default values for Named / List interpolations.

Would be nice to have something like this:

hello: Hello {msg=world}
hiFirst: Hi {0=human}

Maybe even using linked tokens:

defaultAppeal: dear
greeting: Hello, {username='@:defaultAppeal'}!

Alternative

Leave things as they are and set values only from script.

Additional context

Probably, I will be able to implement it by myself. But need to figure out what is going on in the parser / transformer modules first, so I'm not sure yet.

Also, sorry if this feature is already implemented or a corresponding feature request is already opened 😬 Haven't noticed it in docs / backlog.

Validations

pyncz avatar Nov 23 '22 22:11 pyncz

Oh, I searched the docs and even the code for this feature but it's not a thing ?

The suggested solution is good, but I have slight changes I would make and some ideas I would add:

  • using string literals for the default values (I would prefer to use : because its closer to bash variables and js object definitions but = might be easier to implement as it is a new character in the syntax)
const messages = {
  en: {
    message: {
      helloA: "{msg='Hello'} world",
      helloB: "{0='Hi'} world",
      address: "{account}{'@'}{domain='gmail.com'}",
      missingHomeAddress: "Please provide @.lower:{field='Home Adress'}"
    }
  }
}
const messages = {
  en: {
    message: {
      person: 'John',
      hi: "Hi {name=@:message.person}",
      hello: "Hello {[email protected]:message.person}",
      // The documentation doesn't talk much about modifiers with named interpolation. This is just bonus:
      wanted: "searching for {[email protected]:{lastName='John Doe'}}", // excessive but possible?
      warrant: "looking for {fullName=lastName=firstName}" // very excessive
    }
  }
}
  • what I would consider errors
const messages = {
  en: {
    message: {
      directions: "north {'|'=','} west {'|'=','} south", // Syntax Error: literals can't have default values
      helloAll: "Hello {0} {1='john'} {2}", // Syntax Error: avoid ambiguous interpolation
      helloAll2: "Hello {0} {1='john'} {2='jane'}" // Correct
    }
  }
}

I haven't dived a lot in custom modifiers but I suppose It would be possible to create a @.default modifier with minimal changes to avoid a new syntax. I may be wrong.

vaidd4 avatar Apr 10 '24 21:04 vaidd4