source

vue-i18n 번역의 html 태그 베스트 프랙티스

manysource 2023. 1. 17. 21:21

vue-i18n 번역의 html 태그 베스트 프랙티스

사용하고 있다vue-i18n그리고 중간에 앵커태그가 있는 문장을 번역해야 합니다.물론 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

제가 생각해낼 수 있는 유일한 해결책은 다음과 같습니다.

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

컴포넌트 템플릿에 추가한다.

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

우아하진 않지만...

편집: 테스트해 본 결과, 실제로 동작하지 않기 때문에(html을 파라메스에 넣을 수 없습니다) 아이디어가 없어졌습니다.

링크에 대한 간단한 마크업을 생각해 내고 다음과 같은 작은 변환 함수를 작성할 수 있습니다.

//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/

와 함께vue-i18n다음과 같이 표시됩니다(물론 심플하게 할 수 있습니다).

<p v-html="transformLinks($t('example'))"></p>

HTML을 표시된 DOM의 일부가 아닌 요소에 삽입한 후 추출할 수 있습니다.textContent다만, 이것은 실제로 하려고 하는 일에는 적합하지 않을 수 있습니다.나는 건지 모르겠네.

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>

저도 같은 상황에 처해 있는 적이 있기 때문에 Vue-i18n 슬롯을 사용하는 것이 좋습니다.

저는 html 에러메시지가 있는 JSON i18n 파일을 가지고 있습니다.이러한 파일은 정상적으로 표시되지만 vue 템플릿으로 컴파일되지 않으며 바인딩을 포함할 수 없습니다.사용자가 특정 오류 메시지에서 링크를 클릭하면 온클릭 기능을 호출합니다.

이 예에서는 몇 가지 상태 메시지가 있는 cake-state json이 있습니다.

// cake_state.json, where I want links in error messages to call a function when clicked
{
  "state":{
        "stage": {
            "mixing": "Cake is being mixed. The current time is {time}",
            "resting": "Cake is resting. The current time is {time}",
            "oven": "Cake is cooking. The current time is {time}"
            },
        "error": {
            "ovenIssue": "Oven of brand is malfunctioning. Click {email_support_link} to get help",
            "chefIssue": "Chef is down. Click {email_support_link} to get help",
            "leakIssue": "There is a leak"
            },
  }
}
                  

Vue SFC가 있는 경우 템플릿은 다음과 같습니다.

<template>
   <div>
     <i18n :path="getMessage">
        <!-- enter various i18n slots -->
        <template #time>
          <span>{{ getTime }}</span>
        </template>
        
        <template #email_support_link>
          <!-- binding now works because it is not v-html -->
          <a href="" @click.prevent="getRightSupportDepartment">here</span>
        </template>
       </i18n>
    </div>
</template>

...

// js
computed: {
    getTime(): string { //implementation ...},
    getRightSupportDepartment(): string { //implementation ...},
    
    //return strings that are keys to cake_state.json messages
    getMessage(): string {
        ...
        switch (this.cakeState) {
          case Failure.Overheat:
            return "state.error.ovenIssue";
          case Failure.ChefIdle:
            return "state.error.chefIssue";
          case Failure.LeakSensor:
            return "state.error.leakIssue";

여기서 볼 수 있는 것은 다음과 같습니다.

  1. getMessage함수는 i18n JSON의 메시지에 대한 키를 제공합니다.이것은 에 전달됩니다.i18n요소
  2. <template #XXX>의 슬롯i18n컴포넌트의 스코프가 함수에서 이 키와 함께 제공되며, 이 키는 해당 메시지를 수신하고,
  3. 관련 메시지에 키워드 중 하나가 포함되어 있는 경우 해당 메시지는 대응하는 템플릿에서 삽입됩니다.

다시 말씀드리면 i18n json에서 raw html로 제공되는html 요소에 대한 vue 바인딩을 하는 방법을 제공합니다.

예를 들어, "Oven of brand가 오작동하고 있습니다.여기를 클릭하여 도움말을 참조해 주세요.사용자가 '여기'를 클릭하면 클릭 기능을 실행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/42649866/best-practice-for-html-tags-in-vue-i18n-translations