I am new to Svelte. I'm trying to wrap a small wrapper around svelte-i18n to allow relative translation key.
This is how the library can be used:
<script>
import { _ } from 'svelte-i18n';
</script>
<p>{$_('absolute_key')}</p>
What I would like to achieve
<script>
import { tr } from "my_wrapper.js"
const _ = tr("base.path.relative");
</script>
<p>{$_('.relative_key')}</p>
Closest I was able to achieve is
// my_wrapper.js
import { _ } from 'svelte-i18n';
export const tr = (basePath) => (path, options = {}) => {
let returnVal;
if (path.startsWith(".")) {
_.subscribe((t) => returnVal = t(`${basePath}${path}`, options));
} else {
_.subscribe((t) => returnVal = t(path, options));
}
return returnVal;
}
It kinda work but I have to omit the $
sign in {$_('.relative_key')}
. Is there a way to keep its usage with a dollar sign as if I was using the default API?
I have implemented exactly that before, you just have to return a function from the store. Looks something like this:
// better name for _
import { format } from 'svelte-i18n';
export function section(path) {
const { subscribe } = derived(
format,
$format => (idOrMessage, options) => {
if (typeof idOrMessage == 'string')
return $format(`${path}.${idOrMessage}`, options);
return $format(
{
...idOrMessage,
id: `${path}.${idOrMessage.id}`
},
options,
);
},
);
return {
path,
subscribe,
// allows chaining
section: (subPath) => section(`${path}.${subPath}`),
}
}
Would recommend not including the joining .
anywhere except the internals, it's pretty ugly otherwise.
<script>
// ...
const s = section('section');
const sub = s.section('subSection');
// or
const sub2 = section('section.subSection');
</script>
Should be equivalent:
{$_('section.subSection.value')}
{$s('subSection.value')}
{$sub('value')}
{$sub2('value')}