# Content management
CodePress uses a **tree view** (`/admin/content`) for content management: a file browser sidebar + CodeMirror editor, uniform with the plugin and theme editors. The old list/table view has been removed.
## Content editor
### File browser sidebar
- Shows the nested file tree of `content/`, with a clickable **content** root at the top
- Hidden directories (`.bak`, `.git`) and dotfiles are skipped
- Click a **file** to open it in the CodeMirror editor
- Click a **folder** (the folder name) to select it — the **folder detail pane** appears on the right
- The chevron (▶/▼) next to a folder expands/collapses it without selecting the folder
- Folders containing the active file are auto-expanded
- Per folder there are action buttons: new file (plus icon), new folder (folder-plus icon) — they operate on the selected folder
- Per file there are action buttons: rename/move (pencil), delete (trash) — appear on hover
### Drag-and-drop
- Drag a file or folder onto another folder to move it
- Valid drop targets are highlighted during dragging
- The move is performed via an AJAX call — the page reloads automatically on success
- Security: a folder cannot be dropped into itself or a subfolder
- Path-traversal protection: all paths stay within the content directory
### Editable file types
`.md` (Markdown), `.php` (PHP), `.html` (HTML) — consistent with the existing content-edit page.
All types support `---` frontmatter (layout, created, edited, plugins). The CMS `parseMetadata()` extracts frontmatter before processing. For PHP files, frontmatter is stripped from the output.
#### PHP content files
PHP files can deliver content in two ways:
1. **Echo** (output buffering): everything `echo`ed or outside `Hello';` — the returned string is used as content
In PHP files, the `ContentAPI` is available via `$api`:
```php
getMenu();
$pages = $api->getAllPages();
$config = $api->getConfig('site_title');
return '
' . htmlspecialchars($config) . '
';
```
#### Frontend URLs and file names
The CMS searches files in order: `.md` → `.php` → `.html`. If files share the same name (e.g. `test.md` and `test.php`), `/nl/test` always opens `test.md`. To open a specific file type, add the extension to the URL:
- `/nl/test` → opens `test.md` (or `.php` / `.html` if `.md` doesn't exist)
- `/nl/test.php` → opens `test.php` (explicit extension)
- `/nl/test.html` → opens `test.html` (explicit extension)
The preview link in the editor automatically uses the extension for non-`.md` files.
### Set image size (Markdown)
The markdown editor toolbar has an "Image size" button (expand icon):
1. Select an image in the editor in markdown format ``
2. Click the "Image size" button
3. Enter width and/or height (px or %, empty = don't set)
4. The `{:width=... height=...}` syntax is added to or replaced on the image
Example:
```markdown
{:width="200" height="100"}
```
Existing `{:width=...}` values are shown in the prompts. The size attributes are rendered as `width`/`height` HTML attributes on the `
` tag in the frontend.
### Images in content
Images in `content/` are served via the `/-media/` endpoint (content/ lives outside the webroot). Markdown syntax `` with local URLs (relative like `image.jpg`, or absolute like `/content/_images/image.jpg`) is automatically rewritten to `/-media/...`. External URLs (`https://...`) are left untouched.
### Create a new file
- Select the target folder in the sidebar (click the folder name), or use the root
- Click **New file** (in the folder-detail pane or at the top)
- Enter a path within content (e.g. `en.page` or `blog/en.post`)
- Choose the file type (Markdown/PHP/HTML)
- Subfolders are created automatically
- Frontmatter with `layout`, `created`, `edited` is auto-generated
- The new file is created in the selected folder
### Upload a file
- Select the target folder in the sidebar (click the folder name), or use the root
- Click **Upload** (in the folder-detail pane or at the top) to upload files to the selected folder
- Allowed: images, video, audio, PDF, ZIP, office docs, CSS, SCSS, JS, JSON, HTML, MD
- Path-traversal protection: target dir must stay within `content/`
- After the upload you return to the selected folder
### Rename / delete a file
- Open the file in the editor (click the file name in the sidebar)
- **Rename**: edit the **Filename** field on the right above the editor and click Save — the file is renamed immediately
- **Delete**: click the delete button (trash) next to the file in the sidebar, with confirmation
### Folder management
- Click a folder in the sidebar to open the **folder-detail pane** on the right
- **Rename folder**: edit the **Folder name** field in the folder-detail pane and click Save
- **New file / new folder / upload into this folder**: use the buttons in the folder-detail pane — they operate on the selected folder
- **Delete folder**: delete button in the folder-detail pane (only empty folders)
- The content root is also selectable (click "content" at the top of the tree) — shows the folder-detail pane for the root (rename disabled)
### Layout selection
On the editor page you can choose the layout from the layouts defined in `theme.json` (template mapping). The selected layout is stored in the frontmatter `layout:` key.
### Plugins on pages
- Only active **content plugins** (from `plugin.json` with `type: "content"`) appear in the plugin multiselect; system plugins (like Statistics/Logs/Dashboard) are excluded
- Choose which plugins run on the page via the multiselect (use Ctrl/Cmd+click for multiple)
- The plugin selection is stored in the frontmatter `plugins:` key
### Backup integration
At the top of the content editor there is a **Backup** button linking to the backup page (`/admin/content-backup`) for ZIP backup/restore and (if available) git versioning. Git integration in the editor sidebar has been removed; git will become a system plugin later.
### Frontmatter
The editor shows the **Created** and **Edited** timestamps (read-only, automatically updated on every save). The `edited:` value is refreshed on each save.
```markdown
---
layout: left_sidebar
created: 2026-08-19 10:30:25
edited: 2026-08-20 14:22:01
plugins: HTMLBlock, Navigation
---
# Page title
Content...
```
## Frontmatter
The editor updates the frontmatter live when layout or plugin selection changes:
```markdown
---
layout: left_sidebar
created: 2026-08-19 10:30:25
edited: 2026-08-20 14:22:01
plugins: HTMLBlock, Navigation
---
# Page title
Content...
```