@pfeiferio/string-interpolate
v1.0.0
Published
Lightweight string interpolation with named placeholders and filter pipelines
Maintainers
Readme
@pfeiferio/string-interpolate
Lightweight string interpolation with named placeholders and filter pipelines.
- ✅ No dependencies
- ✅ No template engine
- ✅ No expressions, no loops
- ✅ Built-in and custom filters
- ✅ Safe, test-driven parser
Installation
npm install @pfeiferio/string-interpolateBasic Usage
import { interpolate } from '@pfeiferio/string-interpolate'
interpolate(
'Hello {{ user.name }}',
{ user: { name: 'Pascal' } }
)
// → "Hello Pascal"Nested Placeholders (Dot Notation)
interpolate(
'ID: {{ order.customer.id }}',
{
order: {
customer: { id: 42 }
}
}
)
// → "ID: 42"Selective Removal of Missing Placeholders
By default, unresolved placeholders are kept when keep=true.
With the remove option, you can explicitly remove selected placeholders when their value is missing, while keeping all others unchanged.
interpolate(
'Hello {{ user.name }} {{ user.email }}',
{
user: { name: 'Pascal' }
},
{
keep: true,
remove: ['user.email']
}
)
// → "Hello Pascal "Behavior
removeentries act as prefix paths- All placeholders under the given pathare removed if their value is
undefined - Existing values are never removed
removeoverrideskeepfor the specified paths
interpolate(
'Hello {{ user.email }}',
{},
{
keep: true,
remove: ['user.email']
}
)
// → "Hello "Partial matches do apply:
interpolate(
'Hello {{ user.email }}',
{},
{
keep: true,
remove: ['user']
}
)
// → "Hello "Options Reference
interpolate(
template: string,
replacements: Record<string, unknown>,
options?: {
keep?: boolean
remove?: string[]
customFilters?: Record<string, FilterFunction>
}
): stringFilters
Filters are applied using a pipe syntax.
interpolate(
'{{ name | uppercase }}',
{ name: 'pascal' }
)
// → "PASCAL"Multiple filters are applied left to right:
interpolate(
'{{ name | uppercase | truncate length=3 }}',
{ name: 'pascal' }
)
// → "PAS..."Filter Arguments
Filters receive named arguments using key=value syntax.
interpolate(
'{{ text | truncate length=4 ending="..." }}',
{ text: 'abcdef' }
)
// → "abcd..."Argument Rules
Arguments are key-value based
Values may be:
- numbers (
length=10) - booleans (
pretty=true) - strings (
suffix=!!!) - quoted strings with spaces (
ending="...")
- numbers (
No escaping inside quoted strings
Whitespace is used as argument separator
Filter Composition
Interpolation is single-pass. If a placeholder resolves to another placeholder expression, filters are not executed immediately. Instead, they are appended to the resulting placeholder expression.
Built-in Filters
| Filter | Description |
| ------------ | ------------------------------- |
| uppercase | Convert string to upper case |
| lowercase | Convert string to lower case |
| capitalize | Capitalize first character |
| append | Append a suffix |
| concat | Concatenate text |
| replace | Replace all occurrences |
| ltrim | Trim characters from start |
| rtrim | Trim characters from end |
| trim | Trim characters from both sides |
| truncate | Shorten string |
| default | Fallback for undefined |
| padStart | Left-pad string |
| padEnd | Right-pad string |
| json | JSON stringify |
Example:
interpolate(
'{{ value | replace search=" " replace="_" }}',
{ value: 'hello world' }
)
// → "hello_world"Custom Filters
You can provide custom filters via the options object.
interpolate(
'{{ name | reverse }}',
{ name: 'abc' },
{
customFilters: {
reverse: (value) =>
typeof value === 'string'
? value.split('').reverse().join('')
: value
}
}
)
// → "cba"Custom filters override built-in filters with the same name.
Function Values
If a replacement value is a function, it will be executed:
interpolate(
'Now: {{ now }}',
{
now: () => new Date().toISOString()
}
)API
interpolate(template, replacements, options?)
interpolate(
template: string,
replacements: Record<string, unknown>,
options?: {
keep?: boolean,
customFilters?: Record<string, FilterFunction>
}
): stringDesign Goals
- Explicit syntax
- Predictable behavior
- No hidden magic
- Easy to extend
- Safe defaults
This package is not intended to be a full template engine.
License
MIT
