{# Shared file-tree partial used by the content, plugin and theme editors. Renders a nested, collapsible file tree from a list of nodes produced by scanEditorFiles()/scanContentFiles()/scanPluginFiles()/scanThemeFiles(). Required variables (passed via include with ... context): - files: array of nodes [{name, path, is_dir, extension, size, modified, children}] - relFile: currently selected relative file path (for active highlight + auto-expand) - editableExts: array of editable extensions (shown as .EXT badge) - csrf_token: CSRF token for delete forms - treeIdPrefix: prefix for collapse element ids (e.g. 'content-tree', 'plugin-tree', 'theme-tree') - treeRouteBase: admin route base used to build file links, e.g. '/admin/content' - treeRouteParams: extra query string for file links, e.g. 'plugin=MyPlugin&' or 'theme=default&' or '' (content) - treeDeleteRoute: admin route for file delete, e.g. '/admin/content-file-delete' - treeDeleteName: optional hidden field name for delete form (e.g. 'plugin' or 'theme'); emits no field when empty - treeDeleteValue: optional hidden field value for treeDeleteName (e.g. the plugin/theme name) - treeMoveRoute: admin route for file move, e.g. '/admin/plugins-file-move' - treeMoveParams: extra query string for move link, e.g. 'plugin=X&' or '' - treeDirActions: boolean; show per-folder new-file/new-dir/rename/delete buttons (content editor only) - treeHideActionsFor: array of relative paths where move/delete actions are hidden (e.g. ['theme.json']) Icon maps are chosen automatically from the node extension. #} {% macro tree(nodes, opts) %} {% import _self as macros %}