Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for html tags in vue-i18n translations?

I am using vue-i18n and I need to translate a sentence with an anchor tag in the middle. Obviously I want to keep the html specific markup out of my translations, but how best to handle this?

Consider the following example:

This is a test sentence which cannot 
<a href="https://example.com" class="test-class test-another-class">be split</a> 
or it will not make sense

The only solution I can come up with is:

{
    "en": {
        "example": "This is a test sentence which cannot {linkOpen}be split{linkClose} or it will not make sense"
    }
}

and then in the component template

<p v-html="$t('example', { 
    'linkOpen': `<a href="https://example/com" class="test-class test-another-class">`,
    'linkClose: '</a>'
    }) 
"></p>

Not exactly elegant however...

Edit: I've tested this and it doesn't actually work (can't put html in params) so now I'm really out of ideas!

like image 809
Titan Avatar asked Oct 18 '22 16:10

Titan


2 Answers

You can come up with some simple markup for links and write a small transformation function, for example:

//In this example links are structured as follows [[url | text]]

var text = `This is a test sentence which 
cannot [[https://example.com | be split]] or it will not make sense`

var linkExpr = /\[\[(.*?)\]\]/gi;
var linkValueExpr = /(\s+\|\s+)/;

var transformLinks = (string) => {
  return text.replace(linkExpr, (expr, value) => {
    var parts = value.split(linkValueExpr);
    var link = `<a href="${parts[0]}">${parts[2]}</a>`;

    return link;
  });
}

alert(transformLinks(text));

JSFiddle: https://jsfiddle.net/ru5smdy3/

With vue-i18n it will look like this (which of course you can simplify):

<p v-html="transformLinks($t('example'))"></p>
like image 196
euvl Avatar answered Oct 27 '22 09:10

euvl


You can put the HTML into an element that is not part of the displayed DOM and then extract its textContent. This may not work for what you're actually trying to do, though. I can't tell.

new Vue({
  el: '#app',
  data: {
    html: `This is a test sentence which cannot 
<a href="https://example.com" class="test-class test-another-class">be split</a> 
or it will not make sense`,
    utilityEl: document.createElement('div')
  },
  methods: {
    htmlToText: function (html) {
      this.utilityEl.innerHTML = html;
      return this.utilityEl.textContent;
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script>
<div id="app">
  <p v-html="html"></p>
  <p>{{htmlToText(html)}}</p>
</div>
like image 23
Roy J Avatar answered Oct 27 '22 09:10

Roy J