Replace markers in a template
Swap named placeholders in a template for strings, computed values or generated components.
Rendered from
docs/how-to/replace-markers-in-a-template.md
in the generator repository — where a correction belongs, and where the
test suite runs every example on this page or states why it does not.
$$path$$ covers values that live in the model. For everything else—a
name computed at generate time, a whole block of generated code—pass
a replace map. It works on Fragment, Content and Copy.
The template is tpl/class.js:
export class CLASS_NAME {
// #Body
}
import { Jostraca, Project, File, Fragment, Content } from 'jostraca'
await Jostraca().generate({ folder: './out' }, () => {
Project({}, () => {
File({ name: 'widget.js' }, () => {
Fragment({
from: '../tpl/class.js',
replace: {
CLASS_NAME: 'Widget',
'#Body': () => Content(' return 1\n'),
},
})
})
})
})
The generated widget.js:
export class Widget {
return 1
}
Two different key forms did the work there, and the difference matters:
- A plain key is matched literally.
CLASS_NAMEreplaced the text wherever it appeared. - A key starting
#is a comment tag.'#Body'matched the whole line// #Body, indentation included, and replaced it. Writing#Bodybare in the template would not have matched.
A key wrapped in slashes is a regular expression: '/name_\\w+/'. A
function value receives the named capture groups, the whole match under
$&, and the current indent.
One asymmetry to know before you rely on it. A replacement that emits
a component lands in the right place inside a Fragment, which
streams its output, but is appended after the whole string inside a
Content, which joins first. Where position matters, use Fragment—or
return a string.
See also#
- Utilities reference for the
full
replacegrammar. - Fill a template file’s slots for regions big enough to deserve a name.