К содержимому

Форматированный текст

Ссылка внутри переведённого предложения — классическая головная боль в i18n: разбей строку на три ключа, и переводчик потеряет порядок слов. В MF2 для этого есть разметка, а компонент Rich рендерит её через snippet-ы — имя разметки в сообщении решает, какой snippet обернёт текст.

Попробуйте #

И ссылка, и её адрес живут в переводе, а не в компоненте:

Прочитайте документацию, прежде чем публиковать

{ "cta": "Read {#link to=|/docs|}the docs{/link} before you ship" }
<script lang="ts">
	import { Rich } from 'svelte-dialect';
	import { formatParts } from '#lib/i18n.js';

	// options come from the translation: let only a path on this site through
	const internal = (to: unknown) => (/^\/(?![/\\])/.test(String(to)) ? String(to) : undefined);
</script>

<Rich parts={formatParts('home:cta')}>
	{#snippet link(children, options)}<a href={internal(options.to)}>{@render children()}</a>{/snippet}
</Rich>

Опции и вложенность #

Snippet получает snippet для содержимого разметки и её MF2-опции — {#link to=|/x|} превращается в { to: '/x' } — так что перевод может нести атрибуты, специфичные для локали. Это такие же входные данные, как любые другие, поэтому проверяйте их, прежде чем отдавать в атрибут: snippet'ы на этой странице пропускают только путь на этом сайте. Вложенность работает на любую глубину, каждый уровень проходит через свой snippet:

жирный текст с ссылкой внутри

Отсутствующий snippet не ломает страницу #

Разметка без подходящего snippet-а всё равно рендерит своё содержимое — так устаревший перевод или перевод, написанный до появления snippet-а, деградирует мягко, а не исчезает:

В этом предложении есть неподключённая разметка посередине

Под капотом Rich #

formatParts(key, params) — примитив, лежащий в основе: он возвращает части text / open / close / standalone. Используйте его напрямую, если хотите рендерить разметку собственной механикой.

Имена разметки #

Имена разметки становятся именами snippet-ов, так что держите их валидными идентификаторами — для {#my-link} нет подходящего snippet-а.