Open adrai opened 2 years ago
why would you want this? just curious.
why would you want this? just curious.
How would you interpolate a text like the one in my example?
i.e. english like this:
<div>
Hi from <a href="https://www.i18next.com" target="_blank" rel="noopener">i18next</a> 👋
</div>
i.e. german like this:
<div>
Ein freundliches 👋 "Hallo" von <a href="https://www.i18next.com" target="_blank" rel="noopener">i18next</a>
</div>
i.e. italian like this:
<div>
<a href="https://www.i18next.com" target="_blank" rel="noopener">i18next</a> ti saluta 👋
</div>
Yes please I'm in the need for the same thing in Svelte trying to add links to translations 🙏
I concur. Running into this issue with HTML and a on:click in the middle of the string. Not sure how to address this right now
I've come up with a quick solution to be improved
Translation component: (loc is the translation store)
<script lang="ts">
import { derived, readable } from 'svelte/store';
import { loc } from './store';
import { isString } from 'lodash-es';
import type { ComponentType, ComponentProps } from 'svelte';
export let key: string;
export let parts: Array<[ComponentType, ComponentProps, string]> = [];
const content = key
? derived(loc, (loc) => {
const result = loc.t(key);
const final = result && result !== key ? result : null;
if (!final) {
console.warn('No translation found for ' + key + ' - ');
}
return final ?? '';
})
: readable('');
const contentParts = derived(content, content => {
if (!isString(content)) {
return [];
}
if (!content?.trim()) {
return [];
}
const regex = /(?<=@@\d+)|(?=@@\d+)/;
const split = content.split(regex);
const prefix = '@@';
const replaced = split.map(part => {
if (part.startsWith(prefix)) {
const index = Number(part.replace(prefix, ''));
if (isNaN(index)) {
return part;
}
return parts[index];
}
return part;
});
return replaced.length > 0 ? replaced : [ content ];
});
</script>
{#if $contentParts.length}
{#each $contentParts as part}
{#if isString(part)}
{part}
{:else}
<svelte:component this={part[0]} { ...part[1] }>{part[2]}</svelte:component>
{/if}
{/each}
{:else}
<slot />
{/if}
Translation file
{
"home.contact": "Contact us on @@0 or @@1.",
}
Then in one template
<I18n key="home.contact"
html={true}
parts={[
[ Link, { href: discordUrl, target: '_blank' }, 'Discord' ],
[ Link, { href: facebookUrl, target: '_blank' }, 'Discord' ],
]}
>
Contact us on [[<Link href={discordUrl} target="_blank">Discord</Link>]] or [[<Link href={facebookUrl} target="_blank">Facebook</Link>]].
</I18n>
It would be awesome to have also something like a Trans component, like in react-i18next.
That would help to interpolate components/html elements...