Text Boxes
Microsoft Word text boxes are floating shapes that hold text outside the main document flow. AdviceDocs renders placeholders and conditionals that sit inside text boxes at document-fill time, but it does not extract or track those fields the way it does for regular paragraphs and tables. This page explains exactly what works, what’s silently skipped, and why we recommend avoiding text boxes for any {{ }} or {% %} content.
Short version: avoid text boxes for placeholders
What works and what doesn’t
- Renders at fill time —
{{ field }},{% if %}, and{% for %}all evaluate inside text boxes when a single Jinja2 construct sits within a single paragraph in the box. - Multi-paragraph blocks do not work — an
iforforblock whose opening tag and closing tag live in different paragraphs of a text box is rendered paragraph-by-paragraph, so the block is never closed and the content breaks. - Field extraction skips text boxes — placeholders inside a text box are not added to the template’s field list. They can’t be configured, typed, or given condition dependencies.
- The CRM document editor can’t edit text-box anchors — later edit and re-fill stages walk top-level paragraphs and table cells only, so text-box content is invisible to those flows.
- No UI cue — the editor doesn’t flag text-box placeholders as different. They simply won’t appear in the field list at all.
How rendering treats text boxes
At document-fill time the renderer walks the Word XML and explicitly looks for w:txbxContent nodes (Word’s internal storage for text-box content). For each text box it finds, it iterates over the paragraphs inside and runs the full Jinja2 engine on each paragraph individually.
That means:
- A placeholder split across XML runs (which Word does whenever you change formatting mid-placeholder) is reconstructed before parsing — so bold, italic, and font changes inside
{{ name }}are tolerated. - Headers, footers, and body text boxes are all walked.
- Each paragraph in the box is its own Jinja2 render. Constructs that span paragraphs do not work.
Total recommended: {{ recommended_amount }}
{% if has_partner %}Partner: {{ partner.name }}{% endif %}{% if has_partner %}
Partner name: {{ partner.name }}
Partner DOB: {{ partner.dob }}
{% endif %}Why we recommend against placeholders in text boxes
Even when rendering works, the rest of the AdviceDocs pipeline doesn’t know the placeholder exists. The implications are real:
- The field won’t appear in the field configuration UI — no chart-type picker, no colour, no condition badge, no manual type override.
- You can’t add a description to it, which means downstream extraction has less context to work with.
- Stage 1 extraction can’t flag the field as out-of-scope, because it has no record of the field’s
condition_dependencies. The placeholder will render against whatever data the renderer can see — or render an empty string if nothing matches. - The document editor (Stage 4) can’t target the text-box content for re-fill or for human-in-the-loop edits.
- Type inference is skipped —
{{ portfolio_graph }}in a text box will not be recognised as a graph field, so the chart configuration UI will never show.
Graph and image fields will not work in a text box
{{ portfolio_graph }} in a text box will render as the string value of whatever variable name the data happens to contain — not as a chart.Recommended alternatives
If you want the visual look of a text box (bordered region, coloured background, callout style), use one of the following instead. All of them keep your content in the regular document flow, where every AdviceDocs feature works.
- Single-cell table with borders or shading — visually identical to a callout box, fully supported by extraction, conditionals, and the editor. Use a 1×1 table, then style the cell.
- Styled paragraph with paragraph borders — in Word, apply a paragraph border and shading via Format → Borders and Shading. Functionally equivalent to a styled box but lives in the main document flow.
- Quote / pullquote paragraph style — same idea, using one of Word’s built-in paragraph styles.
If you really need to use a text box
Text boxes are sometimes unavoidable — for example when a fixed-position layout requires content to overlay an image. Follow these rules:
- Keep each Jinja2 construct in a single paragraph. Open and close
{% if %}/{% endif %}on the same line. Same for{% for %}/{% endfor %}. - Don’t use graph or image placeholders inside text boxes. They won’t render as charts or images.
- Duplicate the field somewhere outside the text box if you need it to appear in the field editor. Place an invisible (white-on-white)
{{ field }}in a regular paragraph so the field is registered and configurable; the visible copy in the text box will then resolve against the same data at fill time. - Test the rendered output on a small sample before relying on a text-box placeholder in a production template.
Workaround: duplicate the field outside the text box
Common pitfalls
Field doesn't appear in the editor
Conditional block isn't being honoured
{% if %} block in a text box renders both the conditional content and the surrounding tags as plain text, you’ve probably split the block across paragraphs. Collapse it onto a single line, or move the block out of the text box.Graph renders as a string of digits
Header and footer text boxes work too
w:txbxContent nodes in headers and footers in addition to the document body. The same caveats apply: rendering works, extraction does not.Syntax to copy
Safe forms for use inside a text box (each construct kept on a single line). For everything else, use a regular paragraph or a single-cell table.
{{ client_name }}
Adviser: {{ adviser_name }}{% if has_partner %}Partner: {{ partner.name }}{% endif %}{% for product in products %}{{ product.name }}; {% endfor %}