Nodes/ComfyUI-masslevel-TextProcessing/Variable Text Processor (masslevel)
ComfyUI Node

Variable Text Processor (masslevel)

The Variable Text Processor

By masslevel·Created 6 months ago·Updated 6 months ago· 3
Variable Text Processor (masslevel)
    • text
    templateEnter your template here. Use {variable_name} as placeholders.

    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 template input (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_INPUTS always returns True, 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 fps to frame_rate and {fps} silently stops resolving (and passes through unchanged, because nothing errors).
    • Sanitization can orphan a token. A pin named my rate becomes my_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.

    Categorymasslevel/Text

    Inputs (1)

    NameTypeDefaultDescription
    templateSTRINGEnter your template here. Use {variable_name} as placeholders.

    Outputs (1)

    NameTypeDescription
    textSTRING