Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v-translate don't work with Vue component's which wrapping <slot> #49

Open
tabun-matadorov opened this issue Sep 4, 2017 · 9 comments

Comments

@tabun-matadorov
Copy link
Contributor

tabun-matadorov commented Sep 4, 2017

Hi.
Having an issue with v-translate.
Let's say we have <ui-button> component which wrappping <slot> into some additional tags:

<template>
    <button :class="classes" @click="$emit('click', $event)">
        <span class="fx:cross:center">
            <slot />
        </span>
    </button>
</template>

and we are using it like

<ui-button theme="primary" size="big" v-translate>
    Create Account
</ui-button>

Awaited that data-msgid will be Create Account; instead it's
data-msgid="<span class="fx:cross:center"> <slot /> </span>"
But exported string will be Create Account, so translations here will not work;
The same problem will persist if we will use something like

<ui-button theme="primary" size="big" v-translate>
    Create <strong>Account</strong>
</ui-button>
@kemar
Copy link
Contributor

kemar commented Sep 5, 2017

Hi, I do not have a lot of time to help you since I have a lot of work.

If you want some help, please provide at least a link to a minimal reproduction of your problem.

It can be a JSFiddle / JSBin / CodePen or GitHub repo.

@tabun-matadorov
Copy link
Contributor Author

tabun-matadorov commented Sep 5, 2017

Minimal Reproduction: https://codepen.io/anon/pen/rzbeYL
But, actually, I don't need help with this issue because in our project we have solved this issue by forking your project and changing the way msgid extracted in directive.js:

const msgid = vnode.componentInstance
      && vnode.componentInstance.$slots.default.length === 1
      && typeof vnode.componentInstance.$slots.default[0].tag === 'undefined'
      ? el.textContent.trim()
      : el.innerHTML;

(if there is default slot with only one element in it and it's text element --- use textContent instead of innerHTML)
While this solution is unacceptable in main stream, in our project it will work well for us.
All I wanted is to warn that v-translate in some cases will not work with components; simple solution is to use <translate> in all those cases.

@kemar
Copy link
Contributor

kemar commented Sep 5, 2017

Thanx @tabun-matadorov I understand now. I'll take a look at this ASAP.

@kennyki
Copy link
Contributor

kennyki commented Oct 16, 2017

Hi there. Just out of curiosity, does this work for you?

<ui-button theme="primary" size="big">
    <span v-translate>
        Create <strong>Account</strong>
    </span>
</ui-button>

@tabun-matadorov
Copy link
Contributor Author

@kennyki Hi. Sure, this will work, because in your pen we translating a span instead of ui-button, so messages will be extracted & translated properly.

v-translate in some cases will not work with components

and span not a component :)

@kennyki
Copy link
Contributor

kennyki commented Oct 18, 2017

Cool, thanks. I think this behaviour of v-translate is expected, as its intention has always been to translate the HTML of the attached element.

@mitar
Copy link

mitar commented Mar 30, 2018

I am having exactly the same problem. The issue is that now it is really tricky to know when to use <translate> and when to use v-translate because it depends how the component is structured internally. But we do not want <translate> because it adds an extra span.

@kennyki
Copy link
Contributor

kennyki commented Apr 2, 2018

@mitar <translate> component is suitable when you have only plain texts to translate, i.e. <p><translate>Vue is awesome</translate></p> where v-translate directive is a must when you need to include HTML content, i.e. <p v-translate>Vue is <strong>awesome</strong></p>.

As for me, I have been consistently using only v-translate (even for plain texts) in my projects without any problems. Maybe you can try it that way.

Cheers

@mitar
Copy link

mitar commented Apr 2, 2018

I have always just a string internally. The issue is that if the outside component has internal DOM elements it becomes messy. So:

<custom-component-one v-translate>Foo</custom-component-one>
<custom-component-two v-translate>Foo</custom-component-two>

This might or might not work depending on how components are implemented. Maybe custom-component-one has internally a DOM element wrapping its <slot> in which case v-translate picks up the whole thing. And then it is not possible to match it against extracted strings, because extracted string does not have that extra DOM element around (and it also should not be there).

And as you said, it would be preferable to always use v-translate, but it does not work.

So using <translate> works here, but then this adds an extra tag/DOM element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants