commit 5da4502205b01ba17db18dbae5e962d42302e83a Author: Jeremy Tennant Date: Fri Apr 10 14:37:33 2026 +1000 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3b31bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +*.pyc +*.pyo +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..eb44cdc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 tennantje + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6b7ee10 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# ComfyUI Template String + +A simple ComfyUI custom node for string interpolation. Define a template with `{}` placeholders, wire up to 10 string inputs, and the node substitutes them in order. Anything inside the braces — e.g. `{subject}` — is treated as a comment and discarded during substitution, so you can label slots for readability without affecting the output. + +## Usage + +1. Add the **Template String** node (category: `text`) +2. Write a template with `{}` placeholders. You can put anything inside the braces (like `{subject}` or `{1}`) as a label — it's ignored during substitution, only the position matters +3. Wire string outputs from other nodes (Set/Get, primitives, etc.) into `input_1` through `input_10` (all 10 slots are optional) +4. Placeholders are replaced left-to-right by the connected inputs + +### Example + +**Template:** +``` +a {subject} in a {setting}, {lighting} lighting, {quality} +``` + +**Inputs:** +- input_1: `burger` +- input_2: `dim restaurant` +- input_3: `cinematic` +- input_4: `8k` + +**Output:** +``` +a burger in a dim restaurant, cinematic lighting, 8k +``` + +The names `subject`, `setting`, `lighting`, and `quality` are just labels — `a {} in a {}, {} lighting, {}` would produce the same result. Unconnected inputs are skipped, and unused placeholders are left as-is. + +## Install + +Copy or symlink into your ComfyUI custom nodes directory: + +```bash +cd /path/to/ComfyUI/custom_nodes +git clone https://github.com/YOUR_USERNAME/comfyui-template-string.git +``` + +Restart ComfyUI. No pip dependencies required. diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..4542a82 --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +from .node import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/node.py b/node.py new file mode 100644 index 0000000..05d90bb --- /dev/null +++ b/node.py @@ -0,0 +1,67 @@ +class TemplateString: + """ + Replaces {} placeholders in a template with input values, in order. + + Template: "a {subject} on a {surface}, {lighting} lighting, {quality}" + input_1: "burger" + input_2: "wooden table" + input_3: "cinematic" + input_4: "8k" + Result: "a burger on a wooden table, cinematic lighting, 8k" + + Text inside {} is treated as a comment and ignored during substitution. + Unused placeholders are left as-is. Extra inputs are ignored. + """ + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "template": ("STRING", { + "default": "a {}, {}, {}", + "multiline": True, + }), + }, + "optional": { + "input_1": ("STRING", {"default": "", "forceInput": True}), + "input_2": ("STRING", {"default": "", "forceInput": True}), + "input_3": ("STRING", {"default": "", "forceInput": True}), + "input_4": ("STRING", {"default": "", "forceInput": True}), + "input_5": ("STRING", {"default": "", "forceInput": True}), + "input_6": ("STRING", {"default": "", "forceInput": True}), + "input_7": ("STRING", {"default": "", "forceInput": True}), + "input_8": ("STRING", {"default": "", "forceInput": True}), + "input_9": ("STRING", {"default": "", "forceInput": True}), + "input_10": ("STRING", {"default": "", "forceInput": True}), + }, + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("text",) + FUNCTION = "render" + CATEGORY = "text" + + def render(self, template, **kwargs): + values = [] + for i in range(1, 11): + key = f"input_{i}" + if key in kwargs and kwargs[key] is not None: + values.append(kwargs[key]) + + # Replace {anything} placeholders one at a time, left to right + # Text inside braces is treated as a comment and discarded + import re + result = template + for val in values: + result = re.sub(r"\{[^}]*\}", val, result, count=1) + + return (result,) + + +NODE_CLASS_MAPPINGS = { + "TemplateString": TemplateString, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "TemplateString": "Template String", +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8eed1b9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,8 @@ +[project] +name = "comfyui-template-string" +description = "String template node with {} placeholder substitution" +version = "1.0.0" +license = "MIT" + +[tool.comfy] +PublisherId = "tennantje"