Code Monkey home page Code Monkey logo

Comments (16)

dcshiman avatar dcshiman commented on May 24, 2024 7

You can use v-html to html elements as follows

<span v-html="$t('term', {
    'link': `<a href='/link.html'>${$t('link')}</a>`
  })" 
/>

from vuex-i18n.

Gvade avatar Gvade commented on May 24, 2024 2

I've made a quick solution to this problem. It's forked here.
The example: doc.
It assumes that you're using { and } as the identifiers (I didn't manage to access plugin config value from the external file in order to pick the actual ones).

from vuex-i18n.

infinite-dao avatar infinite-dao commented on May 24, 2024 1

One quick work around I could find was to use v-html directive of Vue.js but it is not safe, messages like this:

en: {
  info: 'You can {action} until {limit} minutes from departure.',
  change: 'change your flight'
}

… can be coded as:

<p v-html="$t(
  'info', {
    'action': 'html composed string',
    'limit': 'html composed string'
  })">
</p>

from vuex-i18n.

mnedoszytko avatar mnedoszytko commented on May 24, 2024 1

bump on that. I need to translate a text with an inside, like this

<li>{{ $t('schedules.set_interesting_options', { icon: 'fa-gear'}) }}</li>
translate source:

{ 'en: { 'set_interesting_options' => 'Set some interesting options <i class="fa fa-icon :icon"></i>, ... more text' }}

currently it doesnt even render the translate output and outs $t( in the html

from vuex-i18n.

tikiatua avatar tikiatua commented on May 24, 2024 1

Hi everyone,

I will look into this again as I am preparing a presentation of the vuex-i18n library for a vue meet up in Switzerland in November. It will probably boil down to using a custom component that will take component functions as props.

from vuex-i18n.

BlakeHancock avatar BlakeHancock commented on May 24, 2024 1

I liked how @Gvade's solution worked, but it wasn't very practical for doing simple things like bolding a word in a sentence.

I expanded on it by having it check if the translation key + '__html' exists in the JSON translation file and then compiling it as HTML instead of text, but otherwise working the same way. The only caveat is you can't use slot arguments in attributes, but regular arguments work.

Gist of the component can be found here

Note that I have my translation files grouped by modules so there are a few extra component props to handle that.

There is also a whitelist of elements and attributes at the top as well as a way to specify what vuex-i18n identifiers you want to use. (Currently '{{' and '}}')

from vuex-i18n.

tikiatua avatar tikiatua commented on May 24, 2024

Hi @infinite-dao,

I have seen this functionality in vue-i18n and think it is an important use case. Unfortunately, vuex-i18n does currently not support this. In my opinion, the solution of vue-i18n might also have some room for improvement.

For now, we are using the locale detection with $i18n.locale() and render different components based on the respective locale.

from vuex-i18n.

tqwewe avatar tqwewe commented on May 24, 2024

Bump! This is a must have feature for us.

from vuex-i18n.

tikiatua avatar tikiatua commented on May 24, 2024

I will try to look into this sometime during the next two weeks.

from vuex-i18n.

awakash avatar awakash commented on May 24, 2024

Bump, same here, thanks!

from vuex-i18n.

eliranmal avatar eliranmal commented on May 24, 2024

an issue on the i18next-node repository points at a similar problem (albeit from another point of view, and at a lower level).
Jan Mühlemann, a core member, offered to use post-processing of markdown content, which IMHO suits here pretty well.

the idea is to add a markdown plugin (though you can also write your own), so you wouldn't have to parse HTML (it's not a regular language!), but only markdown. the template output would still be HTML, after the i18next post-processor had done its job.

any thoughts?

@tikiatua @infinite-dao @acidic9 @mnedoszytko @awakash @dcshiman

from vuex-i18n.

eliranmal avatar eliranmal commented on May 24, 2024

@dcshiman, note that the v-html solution may shadow issues with input validation, increasing the chances of missing potential XSS vulnerabilities in the code (as hinted by @infinite-dao in the above comment).

from vuex-i18n.

tikiatua avatar tikiatua commented on May 24, 2024

Hi @eliranmal

Thank you for your input. I am finally getting around to tackle some of the harder problems with this library. Interpolation of html and components is definitely on the list.

I was thinking that interpolation could be achieved on an opt-in basis. Where the developer defines, which tags are allowed to be used for interpolation and all others are automatically stripped (with a warning in debug mode).

This could probably look something like this

<div>
   {{ $t(
      'lookupIdentifierForMessage', {
       // components to make available in the translation
       components: {
         //  strings can be used to interpolate html elements
         title: 'h1',
         // custom components can be used with a different tag
         bold: MyBoldComponent,
         // or with the default tag, i.e. <blinking>..</blinking> 
         Blinking
       },
      // data to make available in the translation
       data: {
            what: 'something like this'
       }
    ) }}
</div>

And in the translation, one would be allowed to use only the specified tags.

const translations = {
  'lookupIdentifierForMessage': '<title>this is important</title>\nWe should <bold>not</bold>forget the security implications of <blinking>{what}</blinking>!'
}

from vuex-i18n.

eliranmal avatar eliranmal commented on May 24, 2024

@tikiatua, thanx, it's great to hear that you're on it!

the imperative API is well done - it's both very expressive and flexible.
i agree that the white-list approach is preferable when mitigating XSS-related issues, however, choosing which tags to render is not the whole solution; should we now check for element attributes as well?

IMHO, introducing markup inside translation values would unnecessarily complicate the code, as it will include new responsibilities to bare (sanitizing the HTML).
we can solve it by delegating the job of rendering tags to the API consumer (e.g. the UI framework layer). my suggestion is to leave hook functions in the chain for that purpose, something like:

$t(
  'lookupIdentifierForMessage', {
    plugins: {
      beforeRender(translation) {
        // a chance to use an external library for keeping all the XSS shenanigans out
        return HtmlCleaner.sanitize(translation);
      }
    },
    // ...
  }
)

or maybe just incorporate the above implementation (a general sanitizing library) into vuex-i18n, as long as only placeholders are used, not tags.

i hope that makes sense in the context of this issue; i'm not very familiar with vuex-i18n, and i only swept through the code.

from vuex-i18n.

tikiatua avatar tikiatua commented on May 24, 2024

Good point. My idea was, that element attributes would be limited to props of the respective components. In addition, we would not actually evaluate the html, but parse the content and build a custom render function to create the respective virtual dom.

Something like this:

message: '<h1>This is my <blinking cadence="10">title</blinking></h1>'

// is complied to
render: function(createElement){
    return createElement('h1', [
       "This is my",
       createElement(MyBlinkingComponent, {
           props: { cadence: 10 }
       }, "title" )
    ])
}

from vuex-i18n.

eliranmal avatar eliranmal commented on May 24, 2024

@tikiatua, that sounds like a great idea - if we don't evaluate any markup, we lower the risk of injections.

also, if the code eventually prepares a render function, we do delegate the job to a higher level, and we can still leave hooks for user intervention (enabling points of integration to actually evaluate the markup).

the added complexity is presumably still there - we'd have to keep so the parsing and keep a whitelist of tags, but if all attributes are just derived from the component's props, the task becomes a lot easier; i love that idea.

by the way - it's worth investigating how does vue itself interprets templates to generate imperative instructions for building the virtual dom - you may be able reuse that code for your purposes (will probably be found in some auxilary code, like vue-template-loader?).

from vuex-i18n.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.