svelte-runtime-template
v1.0.6
Published
A lightweight Svelte component for handling tempolates at runtime with curly brace subsitutions in text content.
Maintainers
Readme
Svelte Runtime Template
A lightweight Svelte component for handling tempolates at runtime with curly brace subsitutions in text content.
This is useful if you have user generated templates that you want to use, e.g., for e-mail sending or html rendering using Svelte components.
Demo
Check out the live demo to see the component in action.
Installation
npm install svelte-runtime-templateUsage
<script>
import { TemplateRenderer } from 'svelte-runtime-template'
const schema = {planet: {}}
const template = 'hello {planet}!'
const values = {planet: 'world'}
</script>
<TemplateRenderer {template} {schema} {values} />The TemplateRenderer component allows you to render text content with curly brace expressions, similar to Svelte's native template syntax (however, no real javascript expressions within the curly braces, just tokens that get replaced by values). It's useful when you need to handle dynamic text content that includes curly brace expressions.
API
Props
template(string) - Required. The text content containing curly brace expressions.schema(array of replacer definitions) - Requires. Defines the llowed tokens and their semantics.errorSnippet(Snippet) - Optional. A snippeterrorSnippet(message: string)used to display parsing errors in the template.textSnippet(Snippet) - Optional. A snippettextSnippet(text: string)used to display text outside the placeholders and replacers without a custom snippet.
Other functions
templateToString
Interpolates a template into a string. Useful to build a plain text representation of the template for the plain text part of an e-mail.
Parameters
template(string): string templateschema(Schema): the schema defintionvalues(T): values with replacments for the template tokensdelimiter = '\n'
Returns
- (string): The formatted string with variables replaced by their values
validateTemplate
Interpolates a template into a string. Useful to build a plain text representation of the template for the plain text part of an e-mail.
Parameters
template(string): string templateschema(Schema): the schema defintion
Returns
- (ValidationError[]): Arry of validation errors in the template w.r.t. the schema
Examples
Basic Usage
<script lang="ts">
import { TemplateRenderer } from 'svelte-runtime-template'
type MyValues = {
name: string
date: Date
link: { url: string }
}
// snippets are not referenced here because we export the schema; normally, you would
// define snippets directly here
const schema: Schema<MyValues> = {
name: {
// no snippet, will use text property
},
date: {
snippet: localizedDate,
transform(value: MyValues) {
return value.date instanceof Date ? value.date.toDateString() : 'invalid date'
}
},
link: {
snippet: ExternalLink,
transform(value: MyValues) {
return value.link.url
}
}
}
const template = `Hello {name}, today is {date}. Here is a missing tag: {missingTag}.
This is a new line and a tag with an argument string: {date until}
And here is a link: {link click here}
`
</script>
<!-- Basic usage -->
<!-- Custom replacers -->
{#snippet localizedDate(tag: string, argument: string | undefined, values: Record<string, any>)}
<span style="color:green" class="date"></span>{values?.date && values?.date instanceof Date
? (argument ?? '' + ' ' + values.date.toLocaleDateString())
: ''}
{/snippet}
{#snippet ExternalLink(tag: string, argument: string | undefined, values: Record<string, any>)}
<a href={values?.url} target="_blank" rel="noopener noreferrer">{argument ?? values?.url}</a>
{/snippet}
<TemplateRenderer {template} {schema} />
<!-- custom error snippet -->
{#snippet errorSnippet(message: string)}
<span style="color:orange"> custom parse error: {message} </span>
{/snippet}
<TemplateRenderer {template} {replacers} {errorSnippet} />
<!-- custom text snippet -->
<h2>Custom Text Snippet</h2>
{#snippet textSnippet(text: string | undefined)}
<span style="color:blue">{text}</span>
{/snippet}
<TemplateRenderer {template} {replacers} {textSnippet} />
<Bracer template="Count: {count}" />
Server-side rendering (e.g., for e-mails)
From the example page.server.ts:
import { templateToString } from '$lib/parser.js'
import type { Actions } from '@sveltejs/kit'
import Sample, { schema, type MyValues } from './Sample.svelte'
import { render } from 'svelte/server'
export const actions: Actions = {
default: async ({ request }) => {
const formData = await request.formData()
const template = formData.get('template') as string
const values = JSON.parse(formData.get('values') as string) as MyValues
// Convert date string to Date object
values.date = new Date(values.date)
const text = templateToString(template as string, schema, values)
const renderResult = render(Sample, { props: { template, values } })
const html = `<html><head>${renderResult.head}</head><body>${renderResult.body}</body></html>`
return { text, html, success: true }
}
}