Text Template Combiner (Buff)
{1} meets a real wire
- text
Most ComfyUI users discover the hard way that you can't just write a {subject} in {style} in a text box and expect the braces to do anything. TextTemplateCombiner is the node that makes that template syntax real: you type a template into main with {1}, {2}, … placeholders, connect strings to matching sockets, and get a single assembled string out. It's prompt assembly without concatenation nodes or a pile of string + string plumbing.
This is one of the most genuinely useful ideas in the pack. Keep the skeleton of a prompt in main - say masterpiece, {1} riding a {2}, dramatic lighting - then connect a subject node and a style node to text_1 and text_2. Swap the subject or style upstream and the whole template re-composes. It's the difference between editing a prompt by hand in six places and editing it in one.
How it works
The node scans main for {N} placeholders and replaces each with the corresponding text_N socket's value. Placeholders also drive the UI: drop a {4} in the template and the node's frontend extension auto-expands to show a text_4 socket - no manual counting. Set inputcount manually if you want more inputs than the template implies, then hit the "Update" action the node exposes.
Two details make it more than a string replacer. First, all 20 text_N inputs exist on the backend regardless of what the browser shows, so raw Prompt API workflows can connect text_9 without the UI extension being involved - the API-safe design shows up all over this pack. Second, there's a random-choice syntax: {foo|bar} in main picks one of the options at random each run, and if an option is a bare number it resolves to that text_N input instead. When a template contains any {a|b} choice, the node uses the float("NaN") IS_CHANGED trick to force re-execution every run so the roll actually changes (the mechanics of that trick are covered in comfyui-node-plumbing.md).
Inputs and output
main- the template.{1}…{20}for wired inputs,{a|b}for random picks.inputcount- how many text sockets to show.text_1…text_20- the strings that fill the slots (empty by default; placeholders with no connected value resolve to empty).
One output: text, the assembled string. Straight into a CLIP Text Encode or anywhere else a prompt goes.
Install
From BuffMcBigHuge's pack - ComfyUI Manager (search "ComfyUI-Buff-Nodes") or:
cd ComfyUI/custom_nodes
git clone https://github.com/BuffMcBigHuge/ComfyUI-Buff-Nodes
Restart ComfyUI. No extra dependencies.
Gotchas
Empty sockets resolve to empty strings, so a placeholder you forgot to wire just vanishes from the output - check your wires before you wonder why a prompt is missing a word. Placeholders are matched as bare {N}; if your template legitimately needs literal braces, that's a corner this node doesn't really accommodate. And the random {a|b} syntax is easy to read as standard wildcard syntax and be surprised it's always random - by design. For slot-fillable prompts that stay readable, it's a genuinely nice small node.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| main | STRING | Primary text template. Use {1}, {2}, etc. to insert connected text inputs. Use {foo|bar} to choose a random option. | |
| inputcount | INT | 10–20 | Number of optional text inputs to show. The browser UI also increases this from placeholders in main. |
| text_1opt | STRING | String inserted when the main text contains {1}. | |
| text_2opt | STRING | String inserted when the main text contains {2}. | |
| text_3opt | STRING | String inserted when the main text contains {3}. | |
| text_4opt | STRING | String inserted when the main text contains {4}. | |
| text_5opt | STRING | String inserted when the main text contains {5}. | |
| text_6opt | STRING | String inserted when the main text contains {6}. | |
| text_7opt | STRING | String inserted when the main text contains {7}. | |
| text_8opt | STRING | String inserted when the main text contains {8}. | |
| text_9opt | STRING | String inserted when the main text contains {9}. | |
| text_10opt | STRING | String inserted when the main text contains {10}. | |
| text_11opt | STRING | String inserted when the main text contains {11}. | |
| text_12opt | STRING | String inserted when the main text contains {12}. | |
| text_13opt | STRING | String inserted when the main text contains {13}. | |
| text_14opt | STRING | String inserted when the main text contains {14}. | |
| text_15opt | STRING | String inserted when the main text contains {15}. | |
| text_16opt | STRING | String inserted when the main text contains {16}. | |
| text_17opt | STRING | String inserted when the main text contains {17}. | |
| text_18opt | STRING | String inserted when the main text contains {18}. | |
| text_19opt | STRING | String inserted when the main text contains {19}. | |
| text_20opt | STRING | String inserted when the main text contains {20}. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |