mirror of
https://github.com/unraid/api.git
synced 2025-12-31 13:39:52 -06:00
fix(web): escaping html-encoded symbols like apostrophes in translations (#1002)
e.g. end user would see `'` from translations
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import en_US from '~/locales/en_US.json';
|
||||
import { provide } from 'vue';
|
||||
import { createI18n, I18nInjectionKey } from 'vue-i18n';
|
||||
import { createHtmlEntityDecoder } from '~/helpers/i18n-utils';
|
||||
|
||||
import en_US from '~/locales/en_US.json';
|
||||
// import ja from '~/locales/ja.json';
|
||||
|
||||
const defaultLocale = 'en_US'; // ja, en_US
|
||||
@@ -34,7 +35,9 @@ const i18n = createI18n<false>({
|
||||
en_US,
|
||||
// ja,
|
||||
...(nonDefaultLocale ? parsedMessages : {}),
|
||||
}
|
||||
},
|
||||
/** safely decodes html-encoded symbols like & and ' */
|
||||
postTranslation: createHtmlEntityDecoder(),
|
||||
});
|
||||
|
||||
provide(I18nInjectionKey, i18n);
|
||||
|
||||
26
web/helpers/i18n-utils.ts
Normal file
26
web/helpers/i18n-utils.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Creates a post-translation function that decodes HTML entities in translated strings.
|
||||
* This function is typically used with createI18n to handle HTML-encoded translations.
|
||||
*
|
||||
* @returns A function that takes a translated value and decodes any HTML entities if it's a string.
|
||||
* If the input is not a string, it returns the original value unchanged.
|
||||
*
|
||||
* @example
|
||||
* const decode = createHtmlEntityDecoder();
|
||||
* decode("&"); // Returns "&"
|
||||
* decode(123); // Returns 123
|
||||
* const i18n = createI18n({
|
||||
* // ... other options
|
||||
* postTranslation(translated) {
|
||||
* return decode(translated);
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export const createHtmlEntityDecoder = () => {
|
||||
const parser = new DOMParser();
|
||||
return <T>(translated: T) => {
|
||||
if (typeof translated !== 'string') return translated;
|
||||
const decoded = parser.parseFromString(translated, 'text/html').documentElement.textContent;
|
||||
return decoded ?? translated;
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createI18n } from 'vue-i18n';
|
||||
|
||||
import en_US from '@/locales/en_US.json';
|
||||
import en_US from '@/locales/en_US.json';
|
||||
import { createHtmlEntityDecoder } from '~/helpers/i18n-utils';
|
||||
|
||||
export default defineNuxtPlugin(({ vueApp }) => {
|
||||
const i18n = createI18n({
|
||||
@@ -11,6 +12,7 @@ export default defineNuxtPlugin(({ vueApp }) => {
|
||||
messages: {
|
||||
en_US,
|
||||
},
|
||||
postTranslation: createHtmlEntityDecoder(),
|
||||
});
|
||||
|
||||
vueApp.use(i18n);
|
||||
|
||||
Reference in New Issue
Block a user