Fix: /admin/content is nu boom-editor + image-grootte knop + custom syntax
- /admin/content is nu de boom-editor (plugin-file-tree structuur),
consistent met plugin- en thema-editors. Oude tabelweergave verhuisd
naar /admin/content-list, bereikbaar via 'Boom weergave'/'Lijst
weergave' knoppen. /admin/content-files redirect naar /admin/content.
- Image-grootte knop in markdown editor-toolbar: selecteer ,
klik knop, breedte/hoogte dialog, {:width=... height=...} syntax
toevoegen/vervangen. Bestaande waarden worden in prompts getoond.
- Custom-grootte syntax {:width=...} nu ook correct herschreven naar
/-media/ endpoint (was alleen gewone  herschreven).
- Handleidingen bijgewerkt (content-beheer.md NL+EN: boom/lijst
weergave uitleg + image-grootte + images in content sectie)
- Release notes v2.6.2 bijgewerkt
- Pentest 30/30, WCAG 25/25
This commit is contained in:
@@ -104,12 +104,14 @@
|
||||
- [x] Pentest controles uitgevoerd (30/30)
|
||||
- [x] WCAG 2.1 AA accessibility tests (25/25)
|
||||
- [x] Thema editor (thema's net zo bewerkbaar maken als plugins): bestandsbrowser zijbalk, nieuw bestand, uploaden, verwijderen, verplaatsen, SCSS compileren vanuit editor, thema activeren/verwijderen, nieuw thema met basis-kopie, uniforme thema-structuur
|
||||
- [x] Content editor (content consistent met plugins en thema's): bestandsbrowser zijbalk naast bestaande lijst weergave, nieuw bestand/map, uploaden, verwijderen, verplaatsen, mappen beheer, layout/plugins selectie, git/backup integratie in editor zijbalk
|
||||
- [x] Content editor (content consistent met plugins en thema's): bestandsbrowser zijbalk nu op /admin/content (vervangt tabelweergave), nieuw bestand/map, uploaden, verwijderen, verplaatsen, mappen beheer, layout/plugins selectie, git/backup integratie in editor zijbalk; oude tabelweergave verhuisd naar /admin/content-list
|
||||
- [x] Uniformiteit: scanEditorFiles() unified scanner (scanPluginFiles/scanThemeFiles/scanContentFiles als dunne wrappers)
|
||||
- [x] Media invoegen in editor: ?theme= scope voor media-list endpoint + _media-modal.twig
|
||||
- [x] Bug: thema-naam niet overgenomen bij kopiëren — title in theme.json wordt overschreven met nieuwe themanaam; README.md krijgt nieuwe header
|
||||
- [x] Bug: mappen met `_` prefix zichtbaar in frontend navigatie — scanDirectory/searchInDirectory/scanForPageTitles skippen nu `_` prefix (consistente filtering met `.` en `-`)
|
||||
- [x] Bug: images in markdown niet weergegeven — processContent() herschrijft lokale image/link URLs naar /-media/ endpoint (relatief, /content/, subdir); externe URLs ongewijzigd gelaten
|
||||
- [x] Bug: images in markdown niet weergegeven — processContent() herschrijft lokale image/link URLs naar /-media/ endpoint (relatief, /content/, subdir, custom-grootte syntax); externe URLs ongewijzigd gelaten
|
||||
- [x] UX: /admin/content is nu de boom-editor (plugin-file-tree structuur); oude tabelweergave op /admin/content-list met "Boom weergave"/"Lijst weergave" knoppen
|
||||
- [x] UX: image-grootte knop in editor-toolbar (markdown) — selecteer , klik knop, breedte/hoogte dialog, {:width=... height=...} syntax toevoegen/vervangen
|
||||
- [x] Handleidingen in guide/ bijgewerkt (thema-beheer.md NL+EN volledig herschreven met thema-editor uitleg; content-beheer.md NL+EN volledig herschreven met content-editor uitleg)
|
||||
- [x] Verslag gemaakt (docs/release-notes/v2.6.2.md)
|
||||
- [x] Versie verhoogd naar 2.6.2
|
||||
|
||||
@@ -16,7 +16,7 @@ class AdminAuth
|
||||
*/
|
||||
public const ROLE_PERMISSIONS = [
|
||||
'admin' => ['*'],
|
||||
'content-manager' => ['dashboard', 'content', 'content-files', 'content-edit', 'content-new', 'content-delete', 'content-file-upload', 'content-file-delete', 'content-file-move', 'content-dir-create', 'content-dir-create-in', 'content-dir-rename', 'content-dir-rename-in', 'content-dir-delete', 'content-dir-delete-in', 'content-move', 'content-backup', 'content-restore', 'content-git-init', 'content-git-commit', 'content-git-restore', 'guide', 'logout'],
|
||||
'content-manager' => ['dashboard', 'content', 'content-list', 'content-files', 'content-edit', 'content-new', 'content-delete', 'content-file-upload', 'content-file-delete', 'content-file-move', 'content-dir-create', 'content-dir-create-in', 'content-dir-rename', 'content-dir-rename-in', 'content-dir-delete', 'content-dir-delete-in', 'content-move', 'content-backup', 'content-restore', 'content-git-init', 'content-git-commit', 'content-git-restore', 'guide', 'logout'],
|
||||
'bi-manager' => ['dashboard', 'statistics', 'logs', 'guide', 'logout'],
|
||||
'site-admin' => ['dashboard', 'theme', 'theme-new', 'theme-edit', 'theme-file-upload', 'theme-file-delete', 'theme-file-move', 'theme-activate', 'theme-delete', 'theme-scss', 'plugins', 'plugins-new', 'plugins-edit', 'plugins-config', 'plugins-toggle', 'plugins-delete', 'statistics', 'logs', 'update', 'guide', 'logout'],
|
||||
];
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
{ cmd: 'quote', icon: 'bi-chat-quote', title: 'Citaat' },
|
||||
null,
|
||||
{ cmd: 'hr', icon: 'bi-hr', title: 'Horizontale lijn' },
|
||||
{ cmd: 'image-size', icon: 'bi-arrows-angle-expand', title: 'Afbeelding grootte' },
|
||||
null,
|
||||
{ cmd: 'media', icon: 'bi-images', title: 'Media invoegen' }
|
||||
],
|
||||
@@ -152,6 +153,43 @@
|
||||
modal.show();
|
||||
}
|
||||
break;
|
||||
case 'image-size':
|
||||
// Set width/height on a markdown image: {:width="W" height="H"}
|
||||
var selImg = editor.getSelection();
|
||||
if (!selImg) {
|
||||
// No selection — ask the user to select an image first
|
||||
alert('Selecteer eerst een afbeelding in de editor () om de grootte in te stellen.');
|
||||
editor.focus();
|
||||
break;
|
||||
}
|
||||
// Match  optionally followed by {:...}
|
||||
var imgMatch = selImg.match(/^!\[([^\]]*)\]\(([^)]+)\)(\s*\{:([^}]*)\})?/);
|
||||
if (!imgMatch) {
|
||||
alert('Selectie is geen afbeelding. Selecteer een afbeelding in markdown formaat: ');
|
||||
editor.focus();
|
||||
break;
|
||||
}
|
||||
var alt = imgMatch[1];
|
||||
var url = imgMatch[2];
|
||||
// Parse existing width/height from the {:...} block
|
||||
var existingAttrs = imgMatch[4] || '';
|
||||
var existingW = (existingAttrs.match(/width\s*=\s*"([^"]*)"/) || [])[1] || '';
|
||||
var existingH = (existingAttrs.match(/height\s*=\s*"([^"]*)"/) || [])[1] || '';
|
||||
var width = prompt('Breedte (px of %, leeg = niet instellen):', existingW);
|
||||
if (width === null) { editor.focus(); break; }
|
||||
var height = prompt('Hoogte (px of %, leeg = niet instellen):', existingH);
|
||||
if (height === null) { editor.focus(); break; }
|
||||
// Build the {:width=... height=...} suffix
|
||||
var attrs = [];
|
||||
if (width.trim() !== '') attrs.push('width="' + width.replace(/"/g, '') + '"');
|
||||
if (height.trim() !== '') attrs.push('height="' + height.replace(/"/g, '') + '"');
|
||||
var replacement = '';
|
||||
if (attrs.length > 0) {
|
||||
replacement += '{:' + attrs.join(' ') + '}';
|
||||
}
|
||||
editor.replaceSelection(replacement);
|
||||
editor.focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-check-lg"></i> {{ ta.rename|default('Hernoemen') }}
|
||||
</button>
|
||||
<a href="/admin/content?dir={{ dir|url_encode }}" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
<a href="/admin/content-list?dir={{ dir|url_encode }}" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-2">
|
||||
<h2 class="mb-0"><i class="bi bi-pencil"></i> {{ ta.rename_folder|default('Map hernoemen') }}</h2>
|
||||
<a href="/admin/content-files" class="btn btn-outline-secondary btn-sm">
|
||||
<a href="/admin/content" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="bi bi-arrow-left"></i> {{ ta.back|default('Terug') }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-check-lg"></i> {{ ta.rename|default('Hernoemen') }}
|
||||
</button>
|
||||
<a href="/admin/content-files" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
<a href="/admin/content" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -71,7 +71,7 @@
|
||||
<i class="bi bi-eye"></i> {{ ta.preview|default('Preview') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="/admin/content?dir={{ fileDir|url_encode }}" class="btn btn-outline-secondary" id="back-btn">{{ ta.back|default('Terug') }}</a>
|
||||
<a href="/admin/content-list?dir={{ fileDir|url_encode }}" class="btn btn-outline-secondary" id="back-btn">{{ ta.back|default('Terug') }}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<a href="/admin/content-files?file={{ n.path|url_encode }}"
|
||||
<a href="/admin/content?file={{ n.path|url_encode }}"
|
||||
class="tree-link {{ isActive ? 'is-active' : '' }}"
|
||||
title="{{ n.path }}">
|
||||
<span class="tree-chevron-spacer"></span>
|
||||
@@ -159,7 +159,7 @@
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#newDirModal" data-in-dir="">
|
||||
<i class="bi bi-folder-plus"></i> {{ ta.new_folder|default('Nieuwe map') }}
|
||||
</button>
|
||||
<a href="/admin/content" class="btn btn-outline-secondary btn-sm">
|
||||
<a href="/admin/content-list" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="bi bi-list"></i> {{ ta.list_view|default('Lijst weergave') }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -228,7 +228,7 @@
|
||||
{% if loop.last %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ part }}</li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-item"><a href="/admin/content-files?file={{ crumbPath|url_encode }}">{{ part }}</a></li>
|
||||
<li class="breadcrumb-item"><a href="/admin/content?file={{ crumbPath|url_encode }}">{{ part }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
@@ -236,7 +236,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if isEditable %}
|
||||
<form method="POST" action="/admin/content-files?file={{ relFile|url_encode }}" id="editor-form">
|
||||
<form method="POST" action="/admin/content?file={{ relFile|url_encode }}" id="editor-form">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
@@ -297,7 +297,7 @@
|
||||
<a href="/{{ currentLang }}{% if fileDir %}/{{ fileDir }}{% endif %}/{{ fileName|replace({'.md': '', '.php': '', '.html': ''}) }}" target="_blank" class="btn btn-outline-info" title="{{ ta.open_new_tab|default('Open in nieuw tabblad') }}">
|
||||
<i class="bi bi-eye"></i> {{ ta.preview|default('Preview') }}
|
||||
</a>
|
||||
<a href="/admin/content?dir={{ fileDir|url_encode }}" class="btn btn-outline-secondary">{{ ta.list_view|default('Lijst weergave') }}</a>
|
||||
<a href="/admin/content-list?dir={{ fileDir|url_encode }}" class="btn btn-outline-secondary">{{ ta.list_view|default('Lijst weergave') }}</a>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
@@ -319,7 +319,7 @@
|
||||
<div class="modal fade" id="newFileModal" tabindex="-1" aria-labelledby="newFileModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form method="POST" action="/admin/content-files">
|
||||
<form method="POST" action="/admin/content">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<input type="hidden" name="action" value="new_file">
|
||||
<input type="hidden" name="in_dir" id="newFileDir" value="">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-2">
|
||||
<h2 class="mb-0"><i class="bi bi-arrows-move"></i> {{ ta.file|default('Bestand') }} {{ ta.move_suffix|default('verplaatsen') }}</h2>
|
||||
<a href="/admin/content-files?file={{ relFile|url_encode }}" class="btn btn-outline-secondary btn-sm">
|
||||
<a href="/admin/content?file={{ relFile|url_encode }}" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="bi bi-arrow-left"></i> {{ ta.back|default('Terug') }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -32,7 +32,7 @@
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-check-lg"></i> {{ ta.move|default('Verplaatsen') }}
|
||||
</button>
|
||||
<a href="/admin/content-files?file={{ relFile|url_encode }}" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
<a href="/admin/content?file={{ relFile|url_encode }}" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -34,7 +34,7 @@
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-check-lg"></i> {{ ta.create|default('Aanmaken') }}
|
||||
</button>
|
||||
<a href="/admin/content?dir={{ dir|url_encode }}" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
<a href="/admin/content-list?dir={{ dir|url_encode }}" class="btn btn-outline-secondary">{{ ta.cancel|default('Annuleren') }}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2><i class="bi bi-file-earmark-text"></i> {{ ta.content|default('Content') }}</h2>
|
||||
<div>
|
||||
<a href="/admin/content" class="btn btn-outline-primary btn-sm me-1" title="{{ ta.tree_view|default('Boom weergave') }}">
|
||||
<i class="bi bi-diagram-3"></i> {{ ta.tree_view|default('Boom weergave') }}
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-success btn-sm me-1" data-bs-toggle="collapse" data-bs-target="#uploadForm">
|
||||
<i class="bi bi-cloud-upload"></i> {{ ta.upload|default('Upload') }}
|
||||
</button>
|
||||
@@ -24,7 +27,7 @@
|
||||
<div class="collapse mb-4" id="uploadForm">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<form method="POST" action="/admin/content?dir={{ subdir|url_encode }}" enctype="multipart/form-data">
|
||||
<form method="POST" action="/admin/content-list?dir={{ subdir|url_encode }}" enctype="multipart/form-data">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div class="mb-3">
|
||||
<label for="file" class="form-label">{{ ta.select_files|default('Bestanden selecteren') }}</label>
|
||||
@@ -43,7 +46,7 @@
|
||||
{% set parentDir = subdir|split('/')|slice(0, -1)|join('/') %}
|
||||
<nav aria-label="breadcrumb" class="mb-3">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/admin/content"><i class="bi bi-house"></i></a></li>
|
||||
<li class="breadcrumb-item"><a href="/admin/content-list"><i class="bi bi-house"></i></a></li>
|
||||
{% set crumbPath = '' %}
|
||||
{% for crumb in subdir|split('/') %}
|
||||
{% set crumbPath = crumbPath ? crumbPath ~ '/' ~ crumb : crumb %}
|
||||
@@ -51,7 +54,7 @@
|
||||
{% if crumbPath == subdir %}
|
||||
{{ crumb }}
|
||||
{% else %}
|
||||
<a href="/admin/content?dir={{ crumbPath|url_encode }}">{{ crumb }}</a>
|
||||
<a href="/admin/content-list?dir={{ crumbPath|url_encode }}">{{ crumb }}</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
@@ -86,7 +89,7 @@
|
||||
<tr data-name="{{ item.name|lower }}">
|
||||
<td>
|
||||
{% if item.is_dir %}
|
||||
<a href="/admin/content?dir={{ item.path|url_encode }}">
|
||||
<a href="/admin/content-list?dir={{ item.path|url_encode }}">
|
||||
<i class="bi bi-folder-fill text-warning"></i> {{ item.name }}
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
@@ -117,8 +117,13 @@ De file-upload/delete/move handler-families zijn per-scope behouden (plugin: pro
|
||||
## Bug fixes
|
||||
|
||||
- **Thema-naam niet overgenomen bij kopiëren** — bij het aanmaken van een nieuw thema met een basisthema werd de `title` uit het basisthema's `theme.json` gekopieerd; nu wordt de `title` overschreven met de nieuwe themanaam en krijgt `README.md` een nieuwe header
|
||||
- **Mappen met `_` prefix zichtbaar in frontend navigatie** — mappen zoals `_drafts`, `_data` werden in het menu getoond omdat `scanDirectory()` alleen `.` en `-` prefixen oversloeg. Nu worden ook `_`-prefix mappen overgeslagen in `scanDirectory()`, `searchInDirectory()` en `scanForPageTitles()` (consistente filtering)
|
||||
- **Images in markdown niet weergegeven** — `` werd gerenderd als `<img src="test.svg">` (relatieve URL → 404) of `` als `<img src="/content/test.svg">` (content/ staat buiten webroot → 404). `processContent()` herschrijft nu lokale image/link URLs naar de `/-media/` endpoint die bestanden uit `content/` serveert met juiste MIME-type. Externe URLs (`http(s)://`), `/-media/`, `/-assets/`, `/themes/`, `/plugins/`, `/admin/`, `data:` en `mailto:` worden ongewijzigd gelaten.
|
||||
- **Mappen met `_` prefix zichtbaar in frontend navigatie** — mappen zoals `_drafts`, `_data`, `_images` werden in het menu getoond omdat `scanDirectory()` alleen `.` en `-` prefixen oversloeg. Nu worden ook `_`-prefix mappen overgeslagen in `scanDirectory()`, `searchInDirectory()` en `scanForPageTitles()` (consistente filtering)
|
||||
- **Images in markdown niet weergegeven** — `` werd gerenderd als `<img src="test.svg">` (relatieve URL → 404) of `` als `<img src="/content/test.svg">` (content/ staat buiten webroot → 404). `processContent()` herschrijft nu lokale image/link URLs naar de `/-media/` endpoint die bestanden uit `content/` serveert met juiste MIME-type. Externe URLs (`http(s)://`), `/-media/`, `/-assets/`, `/themes/`, `/plugins/`, `/admin/`, `data:` en `mailto:` worden ongewijzigd gelaten. Ook de custom-grootte syntax `{:width=... height=...}` wordt correct herschreven.
|
||||
|
||||
## UX verbeteringen
|
||||
|
||||
- **`/admin/content` is nu de boom-editor** — de hoofdroute `/admin/content` toont nu de bestandsbrowser zijbalk structuur (zoals `plugin-file-tree`), consistent met de plugin- en thema-editors. De oude tabelweergave is verhuisd naar `/admin/content-list` en is bereikbaar via de "Lijst weergave" knop. Een "Boom weergave" knop in de tabelweergave keert terug naar de boom-editor. De `content-files` route redirect naar `/admin/content` (backward compat).
|
||||
- **Image-grootte knop in editor-toolbar** — nieuwe knop "Afbeelding grootte" (expand-icoon) in de markdown editor-toolbar. Selecteer een `` image in de editor en klik op de knop om een breedte/hoogte-dialog te krijgen. De `{:width=... height=...}` syntax wordt aan de image toegevoegd of vervangen. Bestaande waarden worden getoond in de prompts.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
CodePress offers two views for content management:
|
||||
|
||||
1. **List view** (`/admin/content`) — classic table with filter, upload, new folder/file per folder
|
||||
2. **Content editor** (`/admin/content-files`) — file browser sidebar + CodeMirror editor (uniform with plugin/theme editors)
|
||||
1. **Tree view** (`/admin/content`) — default, file browser sidebar + CodeMirror editor (uniform with plugin/theme editors)
|
||||
2. **List view** (`/admin/content-list`) — classic table with filter, upload, new folder/file per folder
|
||||
|
||||
Both work side-by-side and use the same content directory. The content editor offers the same functionality as the list view, but with a nested file-tree sidebar like the plugin and theme editors — for a consistent editor experience.
|
||||
Both work side-by-side and use the same content directory. Switch between views via the "List view"/"Tree view" buttons at the top right. The tree view offers the same functionality as the list view, but with a nested file-tree sidebar like the plugin and theme editors — for a consistent editor experience.
|
||||
|
||||
## Content editor (content-files)
|
||||
## Tree view (content)
|
||||
|
||||
### File browser sidebar
|
||||
- Shows the nested file tree of `content/`
|
||||
@@ -19,6 +19,23 @@ Both work side-by-side and use the same content directory. The content editor of
|
||||
### Editable file types
|
||||
`.md` (Markdown), `.php` (PHP), `.html` (HTML) — consistent with the existing content-edit page.
|
||||
|
||||
### 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 `<img>` 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
|
||||
- Click **New file** (at the top or per folder in the sidebar)
|
||||
- Enter a path within content (e.g. `en.page` or `blog/en.post`)
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
CodePress biedt twee weergaven voor content-beheer:
|
||||
|
||||
1. **Lijst weergave** (`/admin/content`) — klassieke tabel met filter, upload, nieuwe map/bestand per map
|
||||
2. **Content editor** (`/admin/content-files`) — bestandsbrowser zijbalk + CodeMirror editor (uniform met plugin/theme-editors)
|
||||
1. **Boom weergave** (`/admin/content`) — standaard, bestandsbrowser zijbalk + CodeMirror editor (uniform met plugin/theme-editors)
|
||||
2. **Lijst weergave** (`/admin/content-list`) — klassieke tabel met filter, upload, nieuwe map/bestand per map
|
||||
|
||||
Beide werken naast elkaarlijk en gebruiken dezelfde content-map. De content-editor biedt dezelfde functionaliteit als de lijst weergave, maar dan met een geneste bestandsboom zijbalk zoals de plugin- en thema-editors — voor consistente editor-ervaring.
|
||||
Beide werken naast elkaar en gebruiken dezelfde content-map. Wissel tussen de weergaven via de "Lijst weergave"/"Boom weergave" knoppen rechtsboven. De boom weergave biedt dezelfde functionaliteit als de lijst weergave, maar dan met een geneste bestandsboom zijbalk zoals de plugin- en thema-editors — voor consistente editor-ervaring.
|
||||
|
||||
## Content editor (content-files)
|
||||
## Boom weergave (content)
|
||||
|
||||
### Bestandsbrowser zijbalk
|
||||
- Toont de geneste bestandsboom van `content/`
|
||||
@@ -19,6 +19,23 @@ Beide werken naast elkaarlijk en gebruiken dezelfde content-map. De content-edit
|
||||
### Bewerkbare bestandstypen
|
||||
`.md` (Markdown), `.php` (PHP), `.html` (HTML) — consistent met de bestaande content-edit pagina.
|
||||
|
||||
### Image-grootte instellen (Markdown)
|
||||
In de markdown editor-toolbar staat een "Afbeelding grootte" knop (expand-icoon):
|
||||
1. Selecteer een afbeelding in de editor in markdown formaat ``
|
||||
2. Klik op de "Afbeelding grootte" knop
|
||||
3. Vul breedte en/of hoogte in (px of %, leeg = niet instellen)
|
||||
4. De `{:width=... height=...}` syntax wordt aan de afbeelding toegevoegd of vervangen
|
||||
|
||||
Voorbeeld:
|
||||
```markdown
|
||||
{:width="200" height="100"}
|
||||
```
|
||||
|
||||
Bestaande `{:width=...}` waarden worden in de prompts getoond. De grootte-attributen worden in de frontend als `width`/`height` HTML-attributen op de `<img>` tag gezet.
|
||||
|
||||
### Images in content
|
||||
Images in `content/` worden via de `/-media/` endpoint geserveerd (content/ staat buiten de webroot). De markdown syntax `` met lokale URLs (relatief zoals `image.jpg`, of absoluut zoals `/content/_images/image.jpg`) wordt automatisch herschreven naar `/-media/...`. Externe URLs (`https://...`) worden ongewijzigd gelaten.
|
||||
|
||||
### Nieuw bestand aanmaken
|
||||
- Klik op **Nieuw bestand** (bovenaan of per map in de zijbalk)
|
||||
- Geef een pad op binnen content (bijv. `nl.pagina` of `blog/nl.post`)
|
||||
|
||||
@@ -100,6 +100,7 @@ return [
|
||||
'content_upload_help' => 'Dateien werden in content/ hochgeladen. Erlaubt: Bilder, Video, Audio, PDF, ZIP, Office-Dokumente, CSS, SCSS, JS, JSON, HTML, MD.',
|
||||
'file_type' => 'Dateityp',
|
||||
'list_view' => 'Listenansicht',
|
||||
'tree_view' => 'Baumansicht',
|
||||
'rename_folder' => 'Ordner umbenennen',
|
||||
'rename_prefix' => 'Umbenennen',
|
||||
'new_name' => 'Neuer Name',
|
||||
|
||||
@@ -100,6 +100,7 @@ return [
|
||||
'content_upload_help' => 'Files are uploaded to content/. Allowed: images, video, audio, PDF, ZIP, office docs, CSS, SCSS, JS, JSON, HTML, MD.',
|
||||
'file_type' => 'File type',
|
||||
'list_view' => 'List view',
|
||||
'tree_view' => 'Tree view',
|
||||
'rename_folder' => 'Rename folder',
|
||||
'rename_prefix' => 'Rename',
|
||||
'new_name' => 'New name',
|
||||
|
||||
@@ -102,6 +102,7 @@ return [
|
||||
'content_upload_help' => 'Bestanden worden geüpload naar content/. Toegestaan: afbeeldingen, video, audio, PDF, ZIP, office docs, CSS, SCSS, JS, JSON, HTML, MD.',
|
||||
'file_type' => 'Bestandstype',
|
||||
'list_view' => 'Lijst weergave',
|
||||
'tree_view' => 'Boom weergave',
|
||||
'rename_folder' => 'Map hernoemen',
|
||||
'rename_prefix' => 'Hernoem',
|
||||
'new_name' => 'Nieuwe naam',
|
||||
|
||||
+56
-51
@@ -270,12 +270,17 @@ switch ($route) {
|
||||
break;
|
||||
|
||||
case 'content':
|
||||
handleContentFiles($auth, $appConfig, $twig, $user, $csrf, $siteConfig);
|
||||
break;
|
||||
|
||||
case 'content-list':
|
||||
handleContent($auth, $appConfig, $twig, $user, $csrf, $siteConfig);
|
||||
break;
|
||||
|
||||
case 'content-files':
|
||||
handleContentFiles($auth, $appConfig, $twig, $user, $csrf, $siteConfig);
|
||||
break;
|
||||
// Backward compat: redirect to the unified content editor
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
|
||||
case 'content-file-upload':
|
||||
handleContentFileUpload($auth, $appConfig, $user);
|
||||
@@ -1015,18 +1020,18 @@ function handleContentFiles($auth, $config, $twig, $user, $csrf, $siteConfig): v
|
||||
function handleContentFileUpload($auth, $config, $user): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
$contentDir = $config['content_dir'];
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realContentDir || !is_dir($realContentDir)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1040,13 +1045,13 @@ function handleContentFileUpload($auth, $config, $user): void
|
||||
$realTarget = realpath($targetDir);
|
||||
if ($realTarget === false) {
|
||||
if (!@mkdir($targetDir, 0755, true)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
$realTarget = realpath($targetDir);
|
||||
}
|
||||
if (!$realTarget || strpos($realTarget, $realContentDir) !== 0 || !is_dir($realTarget)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1090,7 +1095,7 @@ function handleContentFileUpload($auth, $config, $user): void
|
||||
$type = $type === 'success' ? 'success' : 'danger';
|
||||
}
|
||||
|
||||
$redir = '/admin/content-files';
|
||||
$redir = '/admin/content';
|
||||
if (!empty($msg)) {
|
||||
$redir .= '?msg=' . urlencode(implode(' ', $msg)) . '&msgtype=' . urlencode($type);
|
||||
}
|
||||
@@ -1105,18 +1110,18 @@ function handleContentFileUpload($auth, $config, $user): void
|
||||
function handleContentFileDelete($auth, $config, $user): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
$contentDir = $config['content_dir'];
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realContentDir || !is_dir($realContentDir)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1124,20 +1129,20 @@ function handleContentFileDelete($auth, $config, $user): void
|
||||
$relFile = ltrim($relFile, '/');
|
||||
foreach (explode('/', $relFile) as $seg) {
|
||||
if ($seg === '..' || $seg === '.') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$base = basename($relFile);
|
||||
if ($base === '' || $base[0] === '.') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
$fullPath = $realContentDir . '/' . $relFile;
|
||||
$realPath = realpath($fullPath);
|
||||
if ($realPath === false || strpos($realPath, $realContentDir) !== 0 || !is_file($realPath)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1152,7 +1157,7 @@ function handleContentFileDelete($auth, $config, $user): void
|
||||
$type = 'danger';
|
||||
}
|
||||
|
||||
header('Location: /admin/content-files?msg=' . urlencode($msg) . '&msgtype=' . urlencode($type));
|
||||
header('Location: /admin/content?msg=' . urlencode($msg) . '&msgtype=' . urlencode($type));
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1165,7 +1170,7 @@ function handleContentFileMove($auth, $config, $twig, $user, $csrf): void
|
||||
$contentDir = $config['content_dir'];
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realContentDir || !is_dir($realContentDir)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1173,20 +1178,20 @@ function handleContentFileMove($auth, $config, $twig, $user, $csrf): void
|
||||
$relFile = ltrim($relFile, '/');
|
||||
foreach (explode('/', $relFile) as $seg) {
|
||||
if ($seg === '..' || $seg === '.') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$base = basename($relFile);
|
||||
if ($base === '' || $base[0] === '.') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
$fullPath = $realContentDir . '/' . $relFile;
|
||||
$realPath = realpath($fullPath);
|
||||
if ($realPath === false || strpos($realPath, $realContentDir) !== 0 || !is_file($realPath)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1241,7 +1246,7 @@ function handleContentFileMove($auth, $config, $twig, $user, $csrf): void
|
||||
} elseif (rename($realPath, $newPath)) {
|
||||
adminLog($config, 'info', $user['username'] . ' verplaatste content/' . $relFile . ' naar content/' . ($dest ? $dest . '/' : '') . basename($relFile));
|
||||
$newRel = $dest === '' ? basename($relFile) : $dest . '/' . basename($relFile);
|
||||
header('Location: /admin/content-files?file=' . urlencode($newRel) . '&msg=' . urlencode('Bestand verplaatst.') . '&msgtype=success');
|
||||
header('Location: /admin/content?file=' . urlencode($newRel) . '&msg=' . urlencode('Bestand verplaatst.') . '&msgtype=success');
|
||||
exit;
|
||||
} else {
|
||||
$err = error_get_last();
|
||||
@@ -1275,18 +1280,18 @@ function handleContentFileMove($auth, $config, $twig, $user, $csrf): void
|
||||
function handleContentDirCreateIn($auth, $config, $user): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
$contentDir = $config['content_dir'];
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realContentDir || !is_dir($realContentDir)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1298,19 +1303,19 @@ function handleContentDirCreateIn($auth, $config, $user): void
|
||||
$dirname = trim($_POST['dirname'] ?? '');
|
||||
$dirname = preg_replace('/[^a-zA-Z0-9._-]/', '-', $dirname);
|
||||
if ($dirname === '' || $dirname === '.' || $dirname === '..') {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Ongeldige mapnaam.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Ongeldige mapnaam.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
$newPath = $realContentDir . '/' . ($inDir ? $inDir . '/' : '') . $dirname;
|
||||
if (file_exists($newPath)) {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map bestaat al.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map bestaat al.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
if (@mkdir($newPath, 0755, true)) {
|
||||
adminLog($config, 'info', $user['username'] . ' creëerde content map ' . ($inDir ? $inDir . '/' : '') . $dirname);
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map aangemaakt.') . '&msgtype=success');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map aangemaakt.') . '&msgtype=success');
|
||||
} else {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map aanmaken mislukt.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map aanmaken mislukt.') . '&msgtype=danger');
|
||||
}
|
||||
exit;
|
||||
}
|
||||
@@ -1324,7 +1329,7 @@ function handleContentDirRenameIn($auth, $config, $twig, $user, $csrf): void
|
||||
$contentDir = $config['content_dir'];
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realContentDir || !is_dir($realContentDir)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1366,7 +1371,7 @@ function handleContentDirRenameIn($auth, $config, $twig, $user, $csrf): void
|
||||
$messageType = 'danger';
|
||||
} elseif (rename($realDir, $newPath)) {
|
||||
adminLog($config, 'info', $user['username'] . ' hernoemde content map ' . $dirRel . ' naar ' . $newName);
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map hernoemd.') . '&msgtype=success');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map hernoemd.') . '&msgtype=success');
|
||||
exit;
|
||||
} else {
|
||||
$message = 'Hernoemen mislukt.';
|
||||
@@ -1378,7 +1383,7 @@ function handleContentDirRenameIn($auth, $config, $twig, $user, $csrf): void
|
||||
}
|
||||
|
||||
if ($dirRel === '') {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map niet gevonden.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map niet gevonden.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1403,18 +1408,18 @@ function handleContentDirRenameIn($auth, $config, $twig, $user, $csrf): void
|
||||
function handleContentDirDeleteIn($auth, $config, $user): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
$contentDir = $config['content_dir'];
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realContentDir || !is_dir($realContentDir)) {
|
||||
header('Location: /admin/content-files');
|
||||
header('Location: /admin/content');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1422,19 +1427,19 @@ function handleContentDirDeleteIn($auth, $config, $user): void
|
||||
$dirRel = ltrim($dirRel, '/');
|
||||
foreach (explode('/', $dirRel) as $seg) {
|
||||
if ($seg === '..' || $seg === '.') {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Ongeldige map.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Ongeldige map.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
if ($dirRel === '') {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Ongeldige map.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Ongeldige map.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
|
||||
$fullPath = $realContentDir . '/' . $dirRel;
|
||||
$realDir = realpath($fullPath);
|
||||
if (!$realDir || !is_dir($realDir) || strpos($realDir, $realContentDir) !== 0) {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map niet gevonden.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map niet gevonden.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1445,14 +1450,14 @@ function handleContentDirDeleteIn($auth, $config, $user): void
|
||||
if ($e[0] !== '.') { $isEmpty = false; break; }
|
||||
}
|
||||
if (!$isEmpty) {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map moet leeg zijn.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map moet leeg zijn.') . '&msgtype=danger');
|
||||
exit;
|
||||
}
|
||||
if (@rmdir($realDir)) {
|
||||
adminLog($config, 'info', $user['username'] . ' verwijderde content map ' . $dirRel);
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map verwijderd.') . '&msgtype=success');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map verwijderd.') . '&msgtype=success');
|
||||
} else {
|
||||
header('Location: /admin/content-files?msg=' . urlencode('Map verwijderen mislukt.') . '&msgtype=danger');
|
||||
header('Location: /admin/content?msg=' . urlencode('Map verwijderen mislukt.') . '&msgtype=danger');
|
||||
}
|
||||
exit;
|
||||
}
|
||||
@@ -1470,7 +1475,7 @@ function handleContentEdit($auth, $config, $twig, $user, $csrf, $siteConfig): vo
|
||||
$realPath = realpath($filePath);
|
||||
$realContentDir = realpath($contentDir);
|
||||
if (!$realPath || !$realContentDir || strpos($realPath, $realContentDir) !== 0) {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1690,13 +1695,13 @@ function handleContentNew($auth, $config, $twig, $user, $csrf, $siteConfig): voi
|
||||
function handleContentDelete($auth, $config): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
$user = $auth->getCurrentUser();
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1710,20 +1715,20 @@ function handleContentDelete($auth, $config): void
|
||||
adminLog($config, 'info', $user['username'] . ' verwijderde ' . $file);
|
||||
}
|
||||
|
||||
header('Location: /admin/content?dir=' . urlencode(dirname($file)));
|
||||
header('Location: /admin/content-list?dir=' . urlencode(dirname($file)));
|
||||
exit;
|
||||
}
|
||||
|
||||
function handleContentDirCreate($auth, $config): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
$user = $auth->getCurrentUser();
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1741,7 +1746,7 @@ function handleContentDirCreate($auth, $config): void
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: /admin/content?dir=' . urlencode($subdir));
|
||||
header('Location: /admin/content-list?dir=' . urlencode($subdir));
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1768,7 +1773,7 @@ function handleContentDirRename($auth, $config, $twig, $user, $csrf): void
|
||||
if (!file_exists($newPath) && $newPath !== $fullPath) {
|
||||
rename($fullPath, $newPath);
|
||||
adminLog($config, 'info', $user['username'] . ' hernoemde map ' . basename($dir) . ' naar ' . $newName);
|
||||
header('Location: /admin/content?dir=' . urlencode(dirname($dir) . '/' . $newName));
|
||||
header('Location: /admin/content-list?dir=' . urlencode(dirname($dir) . '/' . $newName));
|
||||
exit;
|
||||
} else {
|
||||
$message = 'Map bestaat al of ongeldige naam.';
|
||||
@@ -1797,13 +1802,13 @@ function handleContentDirRename($auth, $config, $twig, $user, $csrf): void
|
||||
function handleContentDirDelete($auth, $config): void
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
$user = $auth->getCurrentUser();
|
||||
if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) {
|
||||
header('Location: /admin/content');
|
||||
header('Location: /admin/content-list');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1821,7 +1826,7 @@ function handleContentDirDelete($auth, $config): void
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: /admin/content?dir=' . urlencode(dirname($dir)));
|
||||
header('Location: /admin/content-list?dir=' . urlencode(dirname($dir)));
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1867,7 +1872,7 @@ function handleContentMove($auth, $config, $twig, $user, $csrf): void
|
||||
if (!file_exists($newPath)) {
|
||||
rename($fullPath, $newPath);
|
||||
adminLog($config, 'info', $user['username'] . ' verplaatste ' . $item . ' naar ' . $dest);
|
||||
header('Location: /admin/content?dir=' . urlencode($dest));
|
||||
header('Location: /admin/content-list?dir=' . urlencode($dest));
|
||||
exit;
|
||||
} else {
|
||||
$message = 'Bestand of map bestaat al op de bestemming.';
|
||||
|
||||
Reference in New Issue
Block a user