]> ###2026.09.25 - Now published on GitHub (https://github.com/joshmans/unraid-text-editor-extensions): the plugin has a real update URL and support link instead of a placeholder. No other change. ###2026.08.10.5 - Update author to shwa87 ###2026.08.10.4 - Remove background/border from restore buttons row; add hover tooltips showing which backup file each button uses - Add "Undo Last Change" and "Restore Original" buttons (editor.cfg.bak / editor.cfg.orig) ###2026.08.10.2 - Default new/empty editor.cfg to one-extension-per-line format (confirmed real format) ###2026.08.10.1 - Fix: remove broken self-download FILE block that caused install failures ###2026.08.10 - Initial release: manage /boot/config/editor.cfg from the webGUI 'JSON data / config files', 'yaml' => 'YAML config files', 'yml' => 'YAML config files (short extension)', 'toml' => 'TOML config files', 'ini' => 'INI config files', 'md' => 'Markdown documents', 'env' => 'Environment variable files (.env)', 'properties' => 'Java-style .properties files', 'conf' => 'Generic .conf config files', 'cfg' => 'Generic .cfg config files', 'service' => 'systemd unit files', 'timer' => 'systemd timer files', 'log' => 'Plain text log files', 'csv' => 'Comma-separated data files', 'xml' => 'XML files', 'htaccess' => 'Apache .htaccess files', 'gitignore' => 'Git ignore rules', ]; function tee_read_editor_cfg($file) { if (!file_exists($file)) { return ['list' => [], 'raw' => '', 'delim' => 'newline', 'exists' => false]; } $raw = @file_get_contents($file); if ($raw === false) $raw = ''; // editor.cfg uses one extension per line. Only fall back to comma-separated // if the file has commas but no newlines at all (older/manual format). $hasNewline = (strpos($raw, "\n") !== false) || (strpos($raw, "\r") !== false); $delim = (!$hasNewline && strpos($raw, ",") !== false) ? 'comma' : 'newline'; $parts = preg_split('/[,\r\n]+/', $raw); $parts = array_values(array_filter(array_map('trim', $parts), function ($v) { return $v !== ''; })); return ['list' => $parts, 'raw' => $raw, 'delim' => $delim, 'exists' => true]; } function tee_write_editor_cfg($file, $content) { // Preserve the very first, pristine copy exactly once, before this plugin // ever touches the file. This is what "Restore Original" rolls back to. $origFile = $file . '.orig'; if (file_exists($file) && !file_exists($origFile)) { @copy($file, $origFile); } if (file_exists($file)) { @copy($file, $file . '.bak'); } return @file_put_contents($file, $content) !== false; } function tee_restore_from($backupFile, $targetFile) { if (!file_exists($backupFile)) return false; // Read the backup's content BEFORE touching anything else — this matters // because for "undo last change" the backup being restored from IS // targetFile.bak, so it must not be overwritten before we've read it. $content = @file_get_contents($backupFile); if ($content === false) return false; // Now it's safe to preserve the current (about-to-be-overwritten) state, // so both "Undo Last Change" and "Restore Original" remain recoverable. if (file_exists($targetFile)) { @copy($targetFile, $targetFile . '.bak'); } return @file_put_contents($targetFile, $content) !== false; } $state = tee_read_editor_cfg($cfgFile); $current = $state['list']; $message = ''; $error = ''; // Capture a pristine snapshot the first time this page ever sees the file, // before any edits are made through this plugin. $origFile = $cfgFile . '.orig'; if ($state['exists'] && !file_exists($origFile)) { @copy($cfgFile, $origFile); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['restore_original'])) { if (tee_restore_from($origFile, $cfgFile)) { $message = "Restored editor.cfg to its original contents (from before this plugin made any changes). Your pre-restore state was saved to editor.cfg.bak."; } else { $error = "No original backup found to restore from (editor.cfg.orig is missing)."; } $state = tee_read_editor_cfg($cfgFile); $current = $state['list']; } elseif (isset($_POST['undo_last'])) { $bakFile = $cfgFile . '.bak'; if (tee_restore_from($bakFile, $cfgFile)) { $message = "Undid the last change to editor.cfg."; } else { $error = "No previous backup found to undo to (editor.cfg.bak is missing)."; } $state = tee_read_editor_cfg($cfgFile); $current = $state['list']; } elseif (isset($_POST['raw_save'])) { $newRaw = isset($_POST['raw_content']) ? $_POST['raw_content'] : ''; if (tee_write_editor_cfg($cfgFile, $newRaw)) { $message = "Saved raw contents of editor.cfg (backup written to editor.cfg.bak)."; } else { $error = "Failed to write $cfgFile — check flash drive permissions."; } $state = tee_read_editor_cfg($cfgFile); $current = $state['list']; } elseif (isset($_POST['apply'])) { $checked = isset($_POST['ext']) && is_array($_POST['ext']) ? $_POST['ext'] : []; $customRaw = isset($_POST['custom']) ? trim($_POST['custom']) : ''; $customList = array_filter(array_map('trim', preg_split('/[,\r\n]+/', $customRaw)), function ($v) { return $v !== ''; }); // Keep any extensions that were already present but aren't in our // suggested list (so we never silently drop something you added by hand). $unknownExisting = array_diff($current, array_keys($suggested)); $final = array_values(array_unique(array_merge($checked, $customList, $unknownExisting))); sort($final); $delim = ($state['delim'] === 'newline') ? "\n" : ","; $newRaw = implode($delim, $final); if ($delim === "\n" && $newRaw !== '') $newRaw .= "\n"; if (tee_write_editor_cfg($cfgFile, $newRaw)) { $message = "Updated editor.cfg with " . count($final) . " extension(s). Backup written to editor.cfg.bak."; } else { $error = "Failed to write $cfgFile — check flash drive permissions."; } $state = tee_read_editor_cfg($cfgFile); $current = $state['list']; } } ?>

Editable File Types

Controls which file extensions the built-in File Manager opens in its text editor/preview instead of just downloading. This works by editing on the flash drive. This file doesn't exist yet on your system — it will be created when you click Apply.

$desc): $isChecked = in_array($ext, $current, true) ? 'checked' : ''; ?>
> .




Raw editor.cfg (advanced)

If your Unraid version expects a different format than what's detected above, edit the exact file contents here directly. Whatever you save here is written byte-for-byte to .



]]>
Utilities -> Editable File Types" echo " to choose which extensions (json, yaml, etc.) the File Manager" echo " will open in its text editor." echo "-----------------------------------------------------------------" ]]>