# Required boilerplate for ComfyUI custom nodes. # - class LoadTextFile: - "Hello, I am a new node." # - INPUT_TYPES - "Here is the form for the inputs I need." # - RETURN_TYPES - "Here is what I will give back." # - FUNCTION - "This is the name of the function that does the actual work." # - CATEGORY - "Put me in this menu, please." # - load_text(self, ...) - "I am the actual function that does the work." # - NODE_CLASS_MAPPINGS - "This is the official registration form." # Import any necessary modules import os import folder_paths import hashlib # Here you are naming your node class class LoadTextFile_Rathius: @classmethod def INPUT_TYPES(cls): return { "required": { # This is just a placeholder text box. # Our JS will find this widget by its name ("file_name") # and replace it with an upload button. "file_name": ("STRING", {"default": "example.txt", "multiline": False}), } } RETURN_TYPES = ("STRING",) RETURN_NAMES = ("text",) FUNCTION = "load_text" CATEGORY = "RathiusNodes/Utils" @classmethod def IS_CHANGED(cls, file_name): # This re-runs the node if the file name changes try: file_path = folder_paths.get_annotated_filepath(file_name) except: # File doesnt exist yet return float("inf") m = hashlib.sha256() with open(file_path, 'rb') as f: m.update(f.read()) return m.digest().hex() def load_text(self, file_name): # This function is more robust. It searches in all known input folders. try: file_path = folder_paths.get_annotated_filepath(file_name) with open(file_path, 'r', encoding='utf-8') as f: text_content = f.read() return (text_content, ) except Exception as e: print(f"[LoadTextFile] Error: {e}") # Return the error message as a string so it can be debugged return (f"Error: {e}", ) # Here you are naming your node class class SimpleTextMixer: """ A simple 5-input text concatenator for Ricky's Prompt Lab. It filters out empty inputs so you don't get dangling commas. """ def __init__(self): pass @classmethod def INPUT_TYPES(s): return { "required": { "separator": ("STRING", {"default": ", ", "multiline": False}), }, "optional": { "text_1": ("STRING", {"multiline": True, "forceInput": True}), "text_2": ("STRING", {"multiline": True, "forceInput": True}), "text_3": ("STRING", {"multiline": True, "forceInput": True}), "text_4": ("STRING", {"multiline": True, "forceInput": True}), "text_5": ("STRING", {"multiline": True, "forceInput": True}), }, } RETURN_TYPES = ("STRING",) RETURN_NAMES = ("mixed_text",) FUNCTION = "mix_text" CATEGORY = "Ricky Tools" def mix_text(self, separator=", ", text_1="", text_2="", text_3="", text_4="", text_5=""): # Collect all inputs into a list inputs = [text_1, text_2, text_3, text_4, text_5] # Filter out empty strings or strings that are just whitespace clean_inputs = [t for t in inputs if t and t.strip() != ""] # Join them with the separator result = separator.join(clean_inputs) return (result,) # --- Node Registration --- NODE_CLASS_MAPPINGS = { "LoadTextFile_Rathius": LoadTextFile_Rathius, "SimpleTextMixer": SimpleTextMixer } NODE_DISPLAY_NAME_MAPPINGS = { "LoadTextFile_Rathius": "Load Text from File (Upload)", "SimpleTextMixer": "Ricky's Prompt Mixer (5-Input)" }