Polyconseil / vue-gettext

Translate your Vue.js applications with gettext.
MIT License
278 stars 55 forks source link

Support for %s parameters #56

Open nkostadinov opened 7 years ago

nkostadinov commented 7 years ago

Currently I'm using translations from a PHP application to translate. All the strings there are defined in the format: 'You have %s unread article in %s feed". How can I provide an array of params to be replaces in this order in the translated strings.

kemar commented 7 years ago

Looks like this is not a vue-gettext issue.

nkostadinov commented 7 years ago

Well since its a recommended way to use gettext I think this should be handled by the component. A lot of sites and apps use this format, don't believe they will create new strings just to be compatible.

https://www.gnu.org/software/gettext/manual/html_node/Preparing-Strings.html

nkostadinov commented 7 years ago

BTW I wrote my own component (which relies on vue-gettext) that handles this and interpolation with Vue components. But is should be nice to be part of the extension.

kemar commented 7 years ago

Can I take a look at the code of your component?

nkostadinov commented 7 years ago

Sure :) . The components relies on the following markup to work:

<v-translate>
  For advanced filtering, please go to %s
  <a slot="s1" class="link" @click="$emit('navigate', 'SettingsRules')" v-translate>Rules</a>
</v-translate>

All the %s are replaced with the corresponding slots based on their index e.g. the first %s is replaces with slot "s1", the second "%s" is replaced with slot "s2" and so on. The base text string to be translated is taken from the Text node inside the component tag without the slot(s).

This is the code for the component. It is used only in this project and have not tested it thoroughly but seem to work ok.

<script>
  export default {
    name: 'v-translate',
    functional: true,
    render (createElement, data) {
      let slots = data.slots()
      let text = slots.default[0].text.trim()
      let translated = data.parent.$gettext(text)

      let tag = data.props.tag ? data.props.tag : 'span'
      let childs = []

      let i = 0
      let offset = 0
      translated.replace('%s', (str, idx) => {
        i++
        if(idx > 0) {
          let text = translated.substring(offset, idx)
          childs.push(data.parent._v(text))
        }
        childs.push(slots['s' + i][0])
      })

      return createElement(tag, childs)
    }
  }
</script>
kemar commented 7 years ago

Ok I may work on it when I have free time. But that's not guaranteed.