Variable Text Processor (masslevel)
The Variable Text Processor
- text
ComfyUI has a dirty little secret: half the "glue" in a workflow is string soup. You type 1920x1080 into a text node for the resize, punch the same numbers into a filename template, retype the cfg and fps when you tweak a video sampler, and eventually one of those copies drifts out of sync and you're saving 1080p files with "1920x1080" baked into the name. This node is a clean cure for that. You write the text once, with {placeholder} tokens, and wire the actual values in as typed pins.
What it actually is
Variable Text Processor (masslevel) is the entire current contents of masslevel's TextProcessing pack - one node, no dependencies, no model downloads, no API keys. The author is the same masslevel who posts high-res Wan 2.1 workflows on r/StableDiffusion and whose sample images have been used by SDXL LoRA trainers, so this is a workflow tool built by someone who actually fights with resolution math daily. It's not a prompt-writing magic box; it's a string assembler that sits before your text encoder or save node and keeps every value in one place.
How it works
The backend is almost insultingly simple, and that's the point. Every pin you add shows up at execution time as a named argument, and the node does a plain template.replace("{key}", str(value)) for each one. That's the whole engine:
- One
templateinput (multiline STRING) is the only statically-declared field. - Dynamic pins are added, removed, and renamed from the node's UI by a frontend JS extension. Each pin is a wildcard (
*) input, so you can wire a number, a string, or anything else into it - INT and FLOAT get auto-converted to strings. - The pin name is the placeholder. Add a pin called
fps, and{fps}in the template becomes the pin's value. - Unresolved placeholders - a
{token}with no matching pin - are passed through unchanged rather than erroring. Handy, but easy to mistake for a broken wire. VALIDATE_INPUTSalways returnsTrue, which bypasses ComfyUI's strict input checking for the dynamically-created slots. This is how the wildcard pins work at all.
Names get sanitized on the way in (letters, numbers, underscores only; a leading digit gets an underscore prefix), so keep your template tokens to that alphabet too or they'll never match.
The inputs that matter
Honestly, there are only two things to learn:
template- your text,{placeholder}tokens included. You can type it in or wire it from another multiline string node.- The pins - click + Add Variable on the node body, name it, wire something in. Right-click the node for Remove Variable Pin / Rename Variable Pin; the pin's own right-click Rename Slot also works.
The single text output is a STRING, and it plugs into anything that eats text: PreviewAny, a save-text node, a metadata writer, or a CLIPTextEncode if you're templating a prompt (check the pack's example workflow - the output wires straight into PreviewAny).
Installing it
Either open ComfyUI Manager and search masslevel or ComfyUI-masslevel-TextProcessing, or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/masslevel/ComfyUI-masslevel-TextProcessing
Then restart ComfyUI. That's it - requirements.txt is empty and the pyproject declares zero dependencies, so there's nothing to pip-install and no model files to fetch. MIT licensed, Python 3.10+.
Where people get burned
- Renaming a pin does not touch your template. The pin becomes the placeholder; the text doesn't. Rename
fpstoframe_rateand{fps}silently stops resolving (and passes through unchanged, because nothing errors). - Sanitization can orphan a token. A pin named
my ratebecomesmy_rate- but your template still says{my rate}. Exact match or nothing. - It's a str.replace, not a regex. That's usually a feature: every occurrence of
{cfg}is replaced, so you can reuse a token in a filename and a metadata block. It just means braces in your literal text are doing work you didn't ask for.
Also, set your expectations: this is a small personal utility with basically zero community footprint (no reddit threads, no impressions on comfy.icu yet). It won't restructure your workflow the way rgthree or the Impact Pack will. But if you keep a template like resolution: {video_width}x{video_height} and wire those numbers from actual primitive nodes, it quietly kills an entire class of copy-paste bugs - which is exactly the kind of tool you stop noticing once it's there.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| template | STRING | Enter your template here. Use {variable_name} as placeholders. | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |