Replace template content
replace-template-contentReplaces the ENTIRE content of a draft template from an HTML string in a single destructive write.
Use this tool ONLY when:
You are authoring the initial content of an empty, freshly created template (e.g. after create-template-from-scratch), or
The user has explicitly asked to discard the current content and rewrite the whole template.
This is the right tool for laying down a large body of content at once (e.g. a whole NDA). It writes the whole template body in one go; there is no way to edit an individual node.
Do NOT use this tool to edit a template that already has content. Overwriting throws the existing content away. If the template already has content, this tool refuses to run unless you pass replace_existing_content=true to confirm the destructive overwrite. Read the current content with get-template-html first, so anything worth keeping can be carried over into the new HTML.
Overwriting an existing body cannot be undone, so ask the user to confirm it before passing replace_existing_content=true.
Only allowed on unpublished (draft) templates. Once a template is published its content can no longer be changed with this tool.
Use the same data-* attribute conventions as get-template-html. UUIDs present on nodes (e.g. data-uuid on a paragraph or heading) are preserved; nodes without a UUID are assigned one automatically. The returned HTML reflects the stored result, with every addressable node carrying a data-uuid you can use in subsequent operations.
Each data-uuid identifies exactly one node, so no two nodes may carry the same one. When you copy an existing node to build a similar one, drop its data-uuid (a fresh one is assigned on write) - reusing it is rejected and nothing is written at all. A cross-reference is the one exception: it carries the uuid of the clause it points at rather than one of its own, so that uuid appears twice by design.
Numbering follows the source. A block the source numbers becomes an ordered list node; a block it does not keeps the tag it had - an stays an , prose stays a . A source that numbers nothing gets no list node at all: a contract written entirely as headings and paragraphs is a correct result.
Headings go three levels deep, to . An or deeper is rejected and nothing is written, so carry a hierarchy past three levels with nested list nodes rather than with a deeper heading.
The numbers themselves are ALWAYS computed by fynk, never typed into the text. HTML whose text starts with a clause marker ("1. Confidentiality", "2)", "(a)", "iv.", "§ 5") is rejected and nothing is written. Where the source numbers a clause, wrap it in an ordered list node instead:
<div data-list data-kind="ordered" data-numbering-type="continue"><p>Confidentiality.</p></div>
<div data-list data-kind="ordered" data-numbering-type="continue"><p>Term.</p></div>Nest another such <div data-list> inside a clause to create sub-clauses (1.1, 1.2). fynk computes the
numbers (1., 2., 1.1., …) automatically and returns them as read-only data-number attributes, which are
ignored on input.
To cross-reference a clause, give that clause a data-uuid of your own - any uuid you generate, as long as it appears on exactly one node - and point the reference at it:
<div data-list data-kind="ordered" data-uuid="11111111-1111-4111-8111-111111111111">
<p>Confidentiality.</p></div>
…
<p>As set out in <span data-section-ref data-uuid="11111111-1111-4111-8111-111111111111"></span>,
notices are written.</p>which renders the clause's computed number ("1.") in place of the reference, following it wherever the clause moves rather than hardcoding it. Both go in the same call: there is no need to write the body first and read the uuids back. A cross-reference carrying no data-uuid points at nothing and is rejected, so drop the reference where you have no clause to name.
A list node decides how its own number is rendered, so any scheme a source document uses is computed rather than typed:
data-numbering-style: decimal (default), upper-roman, lower-roman, upper-alpha, lower-alpha.
data-delimiter-style: dot (default, "1."), parenthesis ("1)"), double-parenthesis ("(1)"), section-mark ("§ 1").
data-numbering-type: continue (default) carries on from the preceding list node, restart begins a new count at 1.
data-show-nested-order-representation: true (default) prefixes a nested clause with its parent's number ("10.1."), false numbers it on its own ("1.", "(a)"). Leave it on where the clause continues the parent's count (1.1., 1.2.), turn it off where the clause has a style of its own that reads wrong with the parent in front of it ("X.1.", "1.(a)").
A heading never carries a number, so a section the source numbers is a list node holding its clauses as nested list nodes - not an followed by clauses. One list node is one number: its own text is its first paragraph, so every clause of its own beside that paragraph needs its own nested :
<div data-list data-kind="ordered" data-numbering-style="upper-roman" data-numbering-type="restart">
<p>Subject of the lease</p>
<div data-list data-kind="ordered" data-numbering-type="restart" data-show-nested-order-representation="false"><p>The lessor lets the premises.</p></div>
<div data-list data-kind="ordered" data-numbering-type="continue" data-show-nested-order-representation="false"><p>The premises comprise.</p></div>
</div>which fynk numbers I., 1., 2., with the next such section continuing at II. Writing those two clauses as plain inside the section instead numbers the section I. and leaves both clauses with no number at all.
Where the source's section titles carry no number, the section stays an with its prose as plain beneath it. A list node placed beside such a heading numbers the prose rather than the section, so every section reads "1." and its title ends up written twice.
The opposite mistake numbers prose that has no number of its own. Text belonging to a clause stays a plain beside the list node's own first paragraph:
<div data-list data-kind="ordered" data-numbering-type="continue">
<p>Purpose</p>
<p>The parties wish to explore a potential business relationship. Each may disclose confidential
information to the other in the course of it.</p>
</div>which fynk numbers 1., with the prose under it unnumbered. Nesting that paragraph in a of its own numbers it as well, leaving the section with a clause that is only its own body text.
To insert a dynamic field (a fill-in placeholder), reference it inline by its ref_uuid:
<span data-dynamic-field data-ref-uuid="<dynamic field ref_uuid>"></span>Discover the available fields and their ref_uuids with get-template-info (include=["dynamic_fields"]), or create a new one with create-template-dynamic-field (which returns its ref_uuid). Referencing a ref_uuid that does not belong to the template is rejected.
Signatures are always placed as a signature container holding one or more signature blocks - even a single block needs one:
<div data-signatures data-align="left"><span data-signature-block data-ref-uuid="<signature block ref_uuid>"></span><span data-signature-block data-ref-uuid="<another ref_uuid>"></span></div>Each inside the container points at one signature block by its ref_uuid; data-align is optional on the container (left, center, right, or justify; default left). A block placed outside a container, as , is legacy: it is still accepted so existing content can be written back unchanged, but it is stored as a container holding that one block.
Discover signature blocks and their ref_uuids with get-template-info (include=["signature_blocks"]), or create one with create-template-signature-block (which returns its ref_uuid). Referencing a ref_uuid that does not belong to the template (in either form) is rejected.
To reference a contracting party, point at it by ref_uuid and choose what is rendered with data-format:
<span data-party data-ref-uuid="<party ref_uuid>" data-format="name"></span> (the party's entity/company name)
<span data-party data-ref-uuid="<party ref_uuid>" data-format="reference"></span> (the party's reference name)Other formats are "address" and "address:inline". A data-format is required and must be one of name/reference/address/address:inline. Discover parties and their ref_uuids with get-template-info, or create one with create-template-party. A ref_uuid not on the template, or a missing/invalid data-format, is rejected.
Images (<img data-image>), dynamic tables (<div data-dynamic-table>) and signing vote blocks
(<span data-signing-vote-block>) cannot be created here — there is no way to author one through this
tool. They can only be preserved: copy the tag exactly as get-template-html returned it, including its
data-uuid / data-ref-uuid / data-table-uuid, and the underlying image or table is kept. Omitting the tag
removes it from the template.
A block's layout cannot be authored here either. The margins, indent and line height a block is laid out with are kept per block and matched by data-uuid on a block of the same kind, so a block you copy over with the data-uuid it came with keeps the spacing it had. A block you write fresh is laid out the way the editor lays out a new block, and so is one you rewrite as a different kind of block - a paragraph turned heading. A style stating a margin, an indent or a line height is ignored; the text formatting inside the block - bold, colour, font, size, highlight - is not.
A block's alignment is authored here, as data-text-align on the paragraph, heading or list
node carrying it - left, center, right or justify:
<h1 data-text-align="center">Mutual Non-Disclosure Agreement</h1>A text-align style is not read, and any other value of the attribute counts as stating no alignment: a
block you write fresh is then aligned left, and one you copy over with the data-uuid it came with keeps the
alignment it already had - state data-text-align="left" to align such a block left again.
When you are laying down content derived from a source document (e.g. a PDF), create the parties, dynamic fields and signature blocks first, so this single write can reference them. Weaving them in afterwards costs a second, destructive rewrite of the whole body.
The response carries a warnings list alongside the stored HTML: advisory notes on what the template is still
missing to behave as a template rather than as a flat copy of its source text - dynamic fields or signature
blocks that exist but are placed nowhere, a body naming its parties as fixed text. The write succeeded either
way, but act on them before reporting the template as finished.
Only available for templates with a prosemirror_data content type.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| html | Yes | Full HTML of the template content. Use the same data-* attribute conventions as get-template-html. Replaces the entire document | |
| template_uuid | Yes | UUID of the unpublished template whose content should be replaced | |
| replace_existing_content | No | Required confirmation (true) to overwrite a template that already has content. Omit (or false) for empty templates. Defaults to false. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| html | No | The stored template content serialised back to HTML. Addressable nodes carry a data-uuid attribute usable in subsequent operations. | |
| warnings | No | Advisory notes on what the stored template is still missing to work as a template: dynamic fields or signature blocks that exist but are placed nowhere, a body naming its parties as fixed text. The write succeeded; act on these before reporting the template as finished. |