From 9a5ab351ba310c5e3797ddfa5ddc7a3ac259f869 Mon Sep 17 00:00:00 2001 From: Edwin Noorlander Date: Wed, 12 Aug 2026 12:05:53 +0200 Subject: [PATCH] Update all guides (NL + EN) for CodePress 2.5.2 features - Admin guide: RBAC roles, role-based dashboard, plugin types (content/system) - CodePress developer guide: plugin types, admin plugin API, SCSS compilation, asset serving - Theme developer guide: SCSS sole CSS source, css_compiled read-only, guide layout - Content manager guide: layout selection from theme.json, plugin order in frontmatter - Both NL and EN updated with identical structure - 35 files updated --- guide/en/admin-beheerder.md | 16 +-- guide/en/admin-beheerder/content-beheer.md | 51 +++++-- guide/en/admin-beheerder/dashboard.md | 30 +++- guide/en/admin-beheerder/gebruikers.md | 39 +++++- guide/en/admin-beheerder/plugins.md | 50 +++++-- guide/en/admin-beheerder/thema-beheer.md | 69 ++++++++-- guide/en/codepress-developer.md | 23 ++-- guide/en/codepress-developer/architectuur.md | 87 +++++++++++- guide/en/codepress-developer/core-classes.md | 85 +++++++++++- .../codepress-developer/plugin-development.md | 129 ++++++++++++++++-- guide/en/codepress-developer/routing.md | 56 +++++++- .../en/content-beheerder/content-structuur.md | 36 +++-- guide/en/content-beheerder/paginas-beheren.md | 40 +++++- guide/en/index.md | 9 ++ guide/en/theme-developer.md | 2 +- guide/en/theme-developer/layouts.md | 62 +++++++-- guide/en/theme-developer/thema-structuur.md | 51 +++++-- guide/en/theme-developer/theme-json.md | 49 +++++-- guide/nl/admin-beheerder.md | 16 +-- guide/nl/admin-beheerder/content-beheer.md | 51 +++++-- guide/nl/admin-beheerder/dashboard.md | 30 +++- guide/nl/admin-beheerder/gebruikers.md | 33 ++++- guide/nl/admin-beheerder/plugins.md | 50 +++++-- guide/nl/admin-beheerder/thema-beheer.md | 65 +++++++-- guide/nl/codepress-developer.md | 23 ++-- guide/nl/codepress-developer/architectuur.md | 87 +++++++++++- guide/nl/codepress-developer/core-classes.md | 85 +++++++++++- .../codepress-developer/plugin-development.md | 129 ++++++++++++++++-- guide/nl/codepress-developer/routing.md | 56 +++++++- .../nl/content-beheerder/content-structuur.md | 32 ++++- guide/nl/content-beheerder/paginas-beheren.md | 40 +++++- guide/nl/index.md | 9 ++ guide/nl/theme-developer/layouts.md | 62 +++++++-- guide/nl/theme-developer/thema-structuur.md | 47 +++++-- guide/nl/theme-developer/theme-json.md | 49 +++++-- 35 files changed, 1493 insertions(+), 255 deletions(-) diff --git a/guide/en/admin-beheerder.md b/guide/en/admin-beheerder.md index 8510644..8e1d4ec 100644 --- a/guide/en/admin-beheerder.md +++ b/guide/en/admin-beheerder.md @@ -2,14 +2,14 @@ The admin manager guide contains the following topics: -- **Dashboard** - Website overview -- **Content management** - Managing files and pages -- **Configuration** - Site settings -- **Theme management** - Managing and creating themes -- **Security** - Bot protection and sessions -- **Plugins** - Managing and creating plugins -- **Users** - Adding and removing users -- **Statistics** - Viewing visitor statistics +- **Dashboard** - Role-based overview of the website (Admin, Content Manager, BI Manager, Site Admin) +- **Content management** - Managing files and pages with layout selection and plugins +- **Configuration** - Site settings (title, language, author, analytics, logging) +- **Theme management** - Managing, activating and creating themes (SCSS compilation) +- **Security** - Bot protection, rate limiting and session settings +- **Plugins** - Managing plugins: content (sidebar) and system (admin menu/API) +- **Users** - User management with roles (Admin, Content Manager, BI Manager, Site Admin) +- **Statistics** - Viewing and exporting visitor statistics - **Logs** - Viewing and filtering log files Select a topic from the navigation on the left. \ No newline at end of file diff --git a/guide/en/admin-beheerder/content-beheer.md b/guide/en/admin-beheerder/content-beheer.md index cb6945f..20ce09f 100644 --- a/guide/en/admin-beheerder/content-beheer.md +++ b/guide/en/admin-beheerder/content-beheer.md @@ -2,16 +2,45 @@ ## Managing files -- **Upload** - Upload media files -- **New folder** - Create folder structure -- **New file** - Create a page -- **Edit** - Modify existing content -- **Rename** - Change file names -- **Move** - Move content -- **Delete** - Remove content +- **New folder** — Create folder structure +- **New file** — Create a page (`.md`, `.php`, `.html`) +- **Edit** — Modify existing content in the CodeMirror editor +- **Rename** — Change file or folder names +- **Move** — Move content to another folder +- **Delete** — Remove content +- **Rename folder** — Change a folder name -## Editor +## Editor (content-edit) -- CodeMirror with syntax highlighting -- Toolbar for Markdown formatting -- Shortcuts: Ctrl+S (save), Ctrl+N (new) \ No newline at end of file +- **CodeMirror** with syntax highlighting (Markdown, PHP, HTML) +- **Toolbar** for quickly inserting Markdown +- **Shortcuts**: Ctrl+S (save), Ctrl+N (new) + +## Layout selection + +On the content-edit 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 + +- Content plugins (from `plugin.json` with `type: "content"`) appear in the plugin selection +- Choose which plugins appear in the sidebar +- **Order is adjustable** with up/down buttons +- The plugin order is stored in the frontmatter `plugins:` key +- Plugins are **hidden** when the chosen layout has no sidebar (e.g. `full_content`) + +## Frontmatter + +The editor updates the frontmatter live when layout or plugin selection changes: + +```markdown +--- +layout: left_sidebar +plugins: + - HTMLBlock + - Navigation +--- + +# Page title + +Content... +``` \ No newline at end of file diff --git a/guide/en/admin-beheerder/dashboard.md b/guide/en/admin-beheerder/dashboard.md index 96a742b..3dba212 100644 --- a/guide/en/admin-beheerder/dashboard.md +++ b/guide/en/admin-beheerder/dashboard.md @@ -1,10 +1,32 @@ # Dashboard -The dashboard shows an overview of: +The dashboard shows a **role-based overview** of the website. Which widgets are visible depends on the role of the logged-in user. -- Views (30 days) -- Unique visitors +## Roles and widgets + +### Admin +- Views (30 days) and unique visitors - Number of pages and folders - Active plugins - Recent activity -- Quick actions \ No newline at end of file +- System information +- Quick actions (new page, plugin, theme) + +### Content Manager +- Number of pages and folders +- Recent content changes +- Quick actions (new page, folder) + +### BI Manager +- Views (30 days) and unique visitors +- Top pages +- Recent visits + +### Site Admin +- Active plugins and themes +- System information +- Quick actions (theme, plugin, update) + +## Access + +The dashboard is the default page after login (`/admin/dashboard`). All roles have access to the dashboard. \ No newline at end of file diff --git a/guide/en/admin-beheerder/gebruikers.md b/guide/en/admin-beheerder/gebruikers.md index 4b6781c..d2a6f5a 100644 --- a/guide/en/admin-beheerder/gebruikers.md +++ b/guide/en/admin-beheerder/gebruikers.md @@ -1,13 +1,40 @@ # Users -## Add user +Users are stored in `admin/config/admin.json` (file-based, no database). Each user has a **role** that determines which admin routes and sidebar items are visible. + +## Roles + +CodePress has four roles, defined in `AdminAuth::ROLE_PERMISSIONS`: + +| Role | Label | Permissions | +|------|-------|-------------| +| `admin` | Admin | Everything (`*`) | +| `content-manager` | Content Manager | Content management, guide | +| `bi-manager` | BI Manager | Statistics, logs, guide | +| `site-admin` | Site Admin | Theme, plugins, statistics, logs, update, guide | + +Roles are displayed with their label via `AdminAuth::ROLE_LABELS`. + +## Adding a user 1. Go to **Users** 2. Enter username -3. Choose password -4. Click **Add** +3. Choose password (stored as bcrypt hash) +4. Select a role +5. Click **Add** -## Delete user +## Editing a user -- Cannot delete own account -- Confirm with password \ No newline at end of file +- Change password (new bcrypt hash) +- Change role (immediately affects visible routes and sidebar items) + +## Deleting a user + +- Not possible for own account +- Confirm with password + +## Access control + +- Route access is checked in `public/admin.php` via `AdminAuth::hasPermission()` +- Unauthorized routes return a **403 error** +- Sidebar items are conditionally shown via the `has_permission()` Twig function in `admin.twig` \ No newline at end of file diff --git a/guide/en/admin-beheerder/plugins.md b/guide/en/admin-beheerder/plugins.md index d9e2d09..1daac3a 100644 --- a/guide/en/admin-beheerder/plugins.md +++ b/guide/en/admin-beheerder/plugins.md @@ -1,15 +1,49 @@ # Plugins +## Plugin types + +CodePress has two kinds of plugins, determined by the `type` field in `plugin.json`: + +- **Content plugins** (`type: "content"`) — Appear in the sidebar and in the plugin selection on content-edit pages. Provide sidebar content via `getSidebarContent()`. +- **System plugins** (`type: "system"`) — Are loaded by PluginManager but do NOT appear in the sidebar. Provide functionality via admin menu, routes and the CMSAPI. Registered via `getAdminMenu()` and `getAdminRoutes()`. + +When no `type` field is present, `content` is assumed. + +## Essential plugins + +Essential plugins are defined in `getProtectedPlugins()` in `public/admin.php`. Current essential plugin: **Navigation**. + +These plugins: +- Cannot be deactivated +- Cannot be edited +- Cannot be deleted + +On the plugins page they get an **Essential** badge instead of the action buttons. + ## Managing plugins -- **Enable/Disable** - Turn plugins on/off -- **Edit** - Modify plugin code -- **Configuration** - Plugin settings -- **Delete** - Remove plugin +- **Activate/Deactivate** — Turn a plugin on/off (not for essential plugins) +- **Edit** — Modify plugin code in CodeMirror (not for essential plugins) +- **Configuration** — Edit plugin settings +- **Delete** — Remove the plugin folder (not for essential plugins) -## New plugin +The admin plugins page shows a **Content** or **System** badge per plugin. + +## Creating a new plugin 1. Go to **Plugins** → **New plugin** -2. Enter a name (e.g. `MyPlugin`) -3. Edit `plugin.php` -4. Enable the plugin \ No newline at end of file +2. Enter a name (e.g. `MyPlugin`) — this becomes the folder name +3. Choose the type: **Content** or **System** +4. The file `MyPlugin.php` is created (NOT `plugin.php`) +5. Edit the plugin code in CodeMirror +6. Activate the plugin + +## Plugin filename + +Plugin PHP files are named `.php` (e.g. `Navigation.php`, `HTMLBlock.php`). `PluginManager` loads `$pluginDir . '/' . $pluginName . '.php'`. + +## Plugin CSS + +- Content and system plugins can have their own CSS in `assets/scss/` and `assets/css/` +- Plugin CSS is automatically loaded after theme CSS (in `base.twig`), so themes can override plugin styling +- Plugin assets are served via `cms/router.php` at URL `/plugins//assets/...` \ No newline at end of file diff --git a/guide/en/admin-beheerder/thema-beheer.md b/guide/en/admin-beheerder/thema-beheer.md index f43d84e..b64a452 100644 --- a/guide/en/admin-beheerder/thema-beheer.md +++ b/guide/en/admin-beheerder/thema-beheer.md @@ -2,20 +2,65 @@ ## Managing themes -1. Go to **Theme** in admin menu -2. **Activate** - Choose active theme -3. **Compile SCSS** - Process SCSS to CSS -4. **New theme** - Create custom theme +1. Go to **Theme** in the admin menu +2. **Activate** — Choose the active theme (stored in `config.json`) +3. **Compile SCSS** — Process SCSS to CSS (forced) +4. **New theme** — Create a custom theme via admin or manually ## Theme structure ``` themes/default/ -├── theme.json # Theme configuration -├── base.twig # Main layout -├── full_content.twig # Layouts -├── left_sidebar.twig -├── right_sidebar.twig -├── partials/ # Header, nav, footer -└── assets/ # CSS, JS, images -``` \ No newline at end of file +├── theme.json # { title, config.default_template, template: layout→.twig } +├── base.twig # Main layout (head, header, nav, breadcrumb, footer) +├── full_content.twig # Layout: full width +├── left_sidebar.twig # Layout: sidebar on the left +├── right_sidebar.twig # Layout: sidebar on the right +├── custom1.twig # Layout: custom +├── guide.twig # Layout: guide with sidebar (Navigation plugin) +├── partials/ # header.twig, navigation.twig, footer.twig +└── assets/ + ├── scss/theme.scss # SCSS source (only CSS source — manual css/theme.css must not exist) + ├── css_compiled/ # Generated by scssphp (read-only, do not edit manually) + ├── css/ # External CSS (bootstrap.min.css, bootstrap-icons.css, mobile.css) + ├── js/ # app.js, bootstrap.bundle.min.js + ├── fonts/ # bootstrap-icons.woff, woff2 + └── img/ # favicon, icon, world-map +``` + +## theme.json + +```json +{ + "title": "default", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig", + "guide": "guide.twig" + } +} +``` + +- `title` — Display name in admin +- `config.default_template` — Default layout for pages without a `layout:` frontmatter +- `template` — Mapping from layout name to `.twig` file + +## SCSS compilation + +- `ThemeManager` compiles `assets/scss/theme.scss` at runtime to `assets/css_compiled/theme.css` via scssphp +- `css_compiled/` is **read-only** — do not edit manually +- `assets/css/theme.css` must **not** exist; otherwise `ThemeManager::getCssUrl()` ignores the SCSS +- After SCSS changes: remove `assets/css_compiled/theme.css` and `.mtime` to force recompilation + +## Layouts + +Layouts are chosen via the frontmatter `layout:` key in content files. Unknown layouts fall back to `config.default_template` from `theme.json`. + +## guide.twig + +Special layout for guides. Injects the Navigation plugin into the sidebar for sidebar navigation. Automatically used for pages in the `guide/` folder. \ No newline at end of file diff --git a/guide/en/codepress-developer.md b/guide/en/codepress-developer.md index fe58d0f..9eca2ba 100644 --- a/guide/en/codepress-developer.md +++ b/guide/en/codepress-developer.md @@ -2,13 +2,20 @@ The CodePress developer guide contains the following topics: -- **Architecture** - CMS architecture and folder structure -- **Core classes** - CodePressCMS, ThemeManager, PluginManager -- **Plugin development** - Developing plugins -- **Routing** - Frontend and admin routing -- **Security** - XSS, CSRF, path traversal -- **Testing** - Penetration, accessibility and functional tests -- **Debugging** - Logging and cache -- **Performance** - OPcache and SCSS caching +- **Architecture** — CMS architecture and folder structure +- **Core classes** — CodePressCMS, ThemeManager, PluginManager, AdminAuth +- **Plugin development** — Plugin types (content/system), structure, API +- **Routing** — Frontend, admin and plugin admin routing +- **Security** — XSS, CSRF, path traversal, RBAC +- **Testing** — Penetration, accessibility and functional tests +- **Debugging** — Logging and cache +- **Performance** — OPcache and SCSS caching + +Important concepts in CodePress 2.5.2: + +- **Plugin types** — Content plugins (sidebar) and system plugins (admin menu, routes, API) +- **Admin plugin API** — System plugins can register admin menu items and routes +- **SCSS compilation** — `ThemeManager` compiles SCSS to `css_compiled/` via scssphp (read-only) +- **Asset serving** — `public/asset.php` serves themes/, admin/assets/ and plugins/ on Apache (instead of PHP dev router) Select a topic from the navigation on the left. \ No newline at end of file diff --git a/guide/en/codepress-developer/architectuur.md b/guide/en/codepress-developer/architectuur.md index ffd536d..9ab71a2 100644 --- a/guide/en/codepress-developer/architectuur.md +++ b/guide/en/codepress-developer/architectuur.md @@ -1,11 +1,84 @@ # CMS Architecture +CodePress is a file-based CMS without a database. Content, configuration and users are stored in files. + +## Folder structure + ``` codepress/ -├── cms/core/ # Core engine -├── admin/ # Admin console -├── themes/ # Themes -├── plugins/ # Plugins -├── content/ # Content -└── public/ # Web root -``` \ No newline at end of file +├── cms/ # Core CMS engine +│ ├── core/ +│ │ ├── class/ +│ │ │ ├── CodePressCMS.php # Main CMS class (routing, rendering, breadcrumb) +│ │ │ ├── ThemeManager.php # Theme resolver + Twig render + SCSS compile +│ │ │ ├── ContentAPI.php # Read-only API for PHP content +│ │ │ ├── ContentSecurityPolicy.php # CSP header management +│ │ │ ├── Analytics.php # Visitor statistics +│ │ │ ├── BotGuard.php # Bot/AI detection +│ │ │ ├── Cache.php # Cache system +│ │ │ ├── GeoIP.php # GeoIP lookup (country, flag) +│ │ │ ├── Logger.php # Basic logging +│ │ │ ├── LogManager.php # Dynamic logging (SQLite/syslog) +│ │ │ ├── RateLimiter.php # Rate limiting per IP +│ │ │ ├── RequestLogger.php # Request logging + visitor info +│ │ │ ├── SearchEngine.php # Full text search +│ │ │ └── AccessibilityManager.php # Accessibility features +│ │ ├── plugin/ +│ │ │ ├── PluginManager.php # Plugin loader (hooks, filters, sidebar, admin routes) +│ │ │ └── CMSAPI.php # API for plugins (getPage, getConfig, etc.) +│ │ ├── config.php # Config loader (reads config.json) +│ │ └── index.php # Bootstrap (autoloader, requires) +│ ├── lang/ # Language files (nl.php, en.php) +│ └── router.php # PHP dev server router +├── themes/ # Dynamic themes +│ └── default/ # Default theme (views + assets) +│ ├── theme.json # { title, config.default_template, template: layout→.twig } +│ ├── base.twig # Main layout +│ ├── *.twig # Layout templates +│ ├── partials/ # header.twig, navigation.twig, footer.twig +│ └── assets/ +│ ├── scss/theme.scss # SCSS source (only CSS source) +│ ├── css_compiled/ # Generated by scssphp (read-only) +│ ├── css/ # External CSS (bootstrap.min.css, etc.) +│ ├── js/ # JavaScript +│ └── img/ # Images +├── admin/ # Admin panel +│ ├── config/ +│ │ ├── app.php # Admin app configuration +│ │ └── admin.json # Users & security (file-based, .gitignore'd) +│ ├── src/ +│ │ └── AdminAuth.php # Authentication + RBAC +│ ├── theme/default/ # Admin theme (views + assets) +│ │ ├── theme.json +│ │ ├── assets/ # CSS, JS, CodeMirror, fonts +│ │ └── views/ # login.twig, layouts/, pages/ +│ └── storage/ # Logs, cache, geoip +├── plugins/ # CMS plugins +│ ├── Navigation/ # Essential navigation plugin (protected) +│ │ ├── Navigation.php # Plugin code (NOT plugin.php) +│ │ ├── plugin.json # Metadata with type field +│ │ └── assets/ # SCSS + CSS +│ └── HTMLBlock/ # Example sidebar plugin +├── content/ # Website content (.md, .php, .html) — .gitignore'd +├── guide/ # Guides (nl/en) +├── public/ # Web root +│ ├── index.php # Website entry point +│ ├── admin.php # Admin entry point + routing +│ ├── asset.php # Asset server for Apache (themes/, admin/assets/, plugins/) +│ ├── .htaccess # Forwards asset URLs to asset.php +│ ├── favicon.ico +│ └── robots.txt +├── var/ # Cache (twig) — .gitignore'd +├── config.json # Site configuration — .gitignore'd +├── composer.json # PHP dependencies (CommonMark, Twig, scssphp) +└── version.php # Version information (2.5.2) +``` + +## Principles + +- **No database** — Everything in files (content in `content/`, users in `admin/config/admin.json`, config in `config.json`) +- **File-based auth** — `AdminAuth` uses bcrypt hashes in `admin.json`, sessions for login +- **Twig templating** — Themes use Twig; `ThemeManager` renders via Twig +- **SCSS compilation** — `assets/scss/theme.scss` → `assets/css_compiled/theme.css` via scssphp (read-only output) +- **Plugin system** — `PluginManager` loads content and system plugins with hooks/filters +- **Asset serving** — PHP dev router (`cms/router.php`) or Apache (`.htaccess` → `public/asset.php`) \ No newline at end of file diff --git a/guide/en/codepress-developer/core-classes.md b/guide/en/codepress-developer/core-classes.md index aa5bbde..52813ff 100644 --- a/guide/en/codepress-developer/core-classes.md +++ b/guide/en/codepress-developer/core-classes.md @@ -10,6 +10,13 @@ $cms->init(); $cms->renderPage($pagePath); ``` +Responsibilities: +- Routing and page rendering +- Breadcrumb generation (dynamic: Home > [subfolders] > [page]) +- Loading guide pages (`getGuidePage()`) +- Title extraction from H1 (`getTitleFromFile()`) +- Display name processing (`formatDisplayName()`) + ## ThemeManager.php Theme management in `cms/core/class/ThemeManager.php`: @@ -19,14 +26,84 @@ $themeManager = new ThemeManager($config); $themeManager->getActiveTheme(); $themeManager->renderTwig($template, $data); $themeManager->compileCss($force); +$themeManager->getCssUrl(); ``` +Responsibilities: +- Resolving the active theme from `config.json` +- Loading `theme.json` (title, config.default_template, template mapping) +- Building the Twig environment (rooted in the theme folder) +- **SCSS compilation** — compiles `assets/scss/theme.scss` to `assets/css_compiled/theme.css` via scssphp +- Resolving the layout to a `.twig` template (fallback to `config.default_template`) + +`getCssUrl()` priority: 1) `assets/css/theme.css` (manual), 2) `assets/css_compiled/theme.css` (compiled). + ## PluginManager.php -Plugin system in `cms/core/class/PluginManager.php`: +Plugin system in `cms/core/plugin/PluginManager.php`: ```php -$pluginManager = new PluginManager(); -$pluginManager->loadPlugins($enabledPlugins); +$pluginManager = new PluginManager($pluginsPath, $enabledPlugins); +$pluginManager->getSidebarContent($allowedPlugins); +$pluginManager->getPluginCssUrls(); $pluginManager->executeHook($name, $params); -``` \ No newline at end of file +$pluginManager->getAdminMenuItems(); +$pluginManager->handleAdminRoute($route); +$pluginManager->getPluginType($pluginName); +``` + +Responsibilities: +- Loading plugins from `plugins/` folders (only enabled plugins) +- Plugin file: `.php` (NOT `plugin.php`) +- Hooks and filters system (`doAction`, `applyFilters`) +- Collecting sidebar content from content plugins (`getSidebarContent`) +- Collecting plugin CSS URLs (`getPluginCssUrls`) +- **Admin menu items** from system plugins (`getAdminMenuItems`) +- **Admin routes** handled via system plugins (`handleAdminRoute`) +- Determining the **plugin type** (`getPluginType` — `content` or `system`) +- `isPluginViewable` — system plugins do not appear in the sidebar + +## AdminAuth.php + +Authentication and RBAC in `admin/src/AdminAuth.php`: + +```php +$auth = new AdminAuth($appConfig); +$auth->login($username, $password); +$auth->logout(); +$auth->hasPermission($route); +$auth->verifyCsrf($token); +``` + +Constants: +- `ROLE_PERMISSIONS` — Mapping of role → allowed route prefixes. `admin` has wildcard `*`. +- `ROLE_LABELS` — Human-readable labels per role. + +Roles: + +| Role | Label | Permissions | +|------|-------|-------------| +| `admin` | Admin | Everything (`*`) | +| `content-manager` | Content Manager | Content management, guide | +| `bi-manager` | BI Manager | Statistics, logs, guide | +| `site-admin` | Site Admin | Theme, plugins, statistics, logs, update, guide | + +Responsibilities: +- Session-based authentication +- bcrypt password hashing +- CSRF tokens (`verifyCsrf`) +- Brute-force lockout (login attempts tracking) +- RBAC via `hasPermission($route)` — checks the route against `ROLE_PERMISSIONS` + +## CMSAPI.php + +Plugin API in `cms/core/plugin/CMSAPI.php`: + +```php +$api = PluginManager::getAPI(); +$config = $api->getConfig(); +$page = $api->getPage($path); +$content = $api->getContent(); +``` + +Provides read-only access for plugins to CMS data (config, pages, content). \ No newline at end of file diff --git a/guide/en/codepress-developer/plugin-development.md b/guide/en/codepress-developer/plugin-development.md index 6fe7611..792049f 100644 --- a/guide/en/codepress-developer/plugin-development.md +++ b/guide/en/codepress-developer/plugin-development.md @@ -1,43 +1,144 @@ # Plugin Development +## Plugin types + +CodePress has two kinds of plugins, determined by the `type` field in `plugin.json`: + +- **Content plugins** (`type: "content"`) — Appear in the sidebar and in the plugin selection on content-edit pages. Provide sidebar content via `getSidebarContent()`. +- **System plugins** (`type: "system"`) — Are loaded by PluginManager but do NOT appear in the sidebar. Provide functionality via admin menu, routes and the CMSAPI. + +When no `type` field is present, `content` is assumed. + ## Plugin structure ``` plugins/MyPlugin/ -├── plugin.json # Plugin metadata -├── plugin.php # Plugin code -└── config.json # Optional configuration +├── MyPlugin.php # Plugin code (NOT plugin.php) +├── plugin.json # Metadata with type field +├── config.json # Optional configuration +└── assets/ + ├── scss/myplugin.scss # SCSS source (optional) + └── css/myplugin.css # CSS (manually maintained) ``` +Plugin files are named `.php` (e.g. `Navigation.php`, `HTMLBlock.php`). `PluginManager` loads `$pluginDir . '/' . $pluginName . '.php'`. + ## plugin.json ```json { - "name": "My Plugin", - "version": "1.0.0", - "author": "Your Name", - "description": "Description" + "name": "My Plugin", + "version": "1.0.0", + "author": "Your Name", + "description": "Description", + "type": "content" } ``` -## plugin.php example +- `name` — Display name +- `type` — `"content"` or `"system"` (default: `content`) + +## Content plugin example ```php 'My Plugin', + 'type' => 'content', + ]; + } -echo '
Hello World
'; + public function getSidebarContent(): string + { + return '

Hello World

'; + } +} ``` +## System plugin example + +```php + 'My System', + 'type' => 'system', + ]; + } + + public function getAdminMenu(): array + { + return [ + ['label' => 'My System', 'route' => 'my-system', 'icon' => 'bi-gear'], + ]; + } + + public function getAdminRoutes(): array + { + return ['my-system']; + } + + public function handleAdminRoute(string $route): void + { + echo '

My System page

'; + } +} +``` + +System plugins are shown in the admin sidebar via `PluginManager::getAdminMenuItems()` and handled via `PluginManager::handleAdminRoute()`. + ## Using CMSAPI ```php getConfig(); -$content = $api->getContent(); -``` \ No newline at end of file +$page = $api->getPage($path); +``` + +`setAPI()` is called automatically by `PluginManager` if the plugin has the method. + +## Plugin CSS + +- Plugin CSS in `assets/css/` is manually maintained (SCSS compilation for plugins is not yet automatic) +- Plugin CSS is automatically loaded after theme CSS (in `base.twig`), so themes can override plugin styling +- Plugin assets are served via `cms/router.php` at URL `/plugins//assets/...` +- Implement `getCssUrl()` in the plugin class to return the CSS URL + +```php +public function getCssUrl(): string +{ + return '/plugins/MyPlugin/assets/css/myplugin.css'; +} +``` + +## Hooks and filters + +PluginManager auto-registers these methods as hooks/filters: + +- **Hooks**: `onPageLoad`, `onBeforeRender`, `onAfterRender`, `onSearch`, `onMenuBuild` +- **Filters**: `onContentFilter`, `onTitleFilter`, `onMenuFilter` + +```php +public function onPageLoad($page) { /* ... */ } +public function onContentFilter($content) { return $content; } +``` + +## Essential plugins + +Essential plugins are defined in `getProtectedPlugins()` in `public/admin.php`. Current essential plugin: **Navigation**. + +These plugins cannot be deactivated, edited or deleted. Always add the `isProtectedPlugin()` check to new plugin handlers. \ No newline at end of file diff --git a/guide/en/codepress-developer/routing.md b/guide/en/codepress-developer/routing.md index 3a06b3f..031c9e2 100644 --- a/guide/en/codepress-developer/routing.md +++ b/guide/en/codepress-developer/routing.md @@ -2,18 +2,60 @@ ## Frontend routing -Via `cms/router.php` for PHP dev server: +Frontend routing goes through `cms/router.php` (PHP dev server) or `.htaccess` (Apache). Both provide clean URLs. -```php -// Clean URLs: /nl/page -// Query: ?page=page&lang=nl +### PHP dev server + +Start the server with: + +```bash +php -S localhost:8080 cms/router.php ``` +`cms/router.php` serves: +- Clean URLs: `/nl/page` → `public/index.php?page=page&lang=nl` +- `themes/` assets +- `admin/assets/` assets +- `plugins/` assets + +### Apache (live server) + +`public/.htaccess` rewrites URLs to `public/index.php`. Asset URLs (`/themes/`, `/admin/assets/`, `/plugins/`) are forwarded to `public/asset.php`. + +`public/asset.php` serves files from the correct folders with the correct MIME type: +- `/themes//assets/...` → `themes//assets/...` +- `/admin/assets/...` → `admin/theme/default/assets/...` +- `/plugins//assets/...` → `plugins//assets/...` + ## Admin routing -Via `public/admin.php`: +Admin routing goes through `public/admin.php` with clean URLs: + +``` +/admin/dashboard → ?route=dashboard +/admin/content → ?route=content +/admin/plugins → ?route=plugins +``` + +`cms/router.php` or `.htaccess` converts `/admin/` to `?route=`. + +### Route access control (RBAC) + +Each route is checked via `AdminAuth::hasPermission($route)`: +- The `admin` role has wildcard `*` access +- Other roles have an explicit list of allowed routes in `ROLE_PERMISSIONS` +- Unauthorized routes return a **403 error** + +## Plugin admin routing + +System plugins can register admin routes. These are handled by `PluginManager::handleAdminRoute($route)`: + +1. The system plugin registers routes via `getAdminRoutes()` +2. `PluginManager::getAdminMenuItems()` collects admin menu items via `getAdminMenu()` +3. On an admin request `PluginManager::handleAdminRoute($route)` finds a plugin that handles the route +4. The plugin method `handleAdminRoute($route)` renders the page content ```php -// Routes: /admin/dashboard, /admin/content, etc. -// Query parameter: ?route=dashboard +// PluginManager calls this for /admin/my-system +$plugin->handleAdminRoute('my-system'); ``` \ No newline at end of file diff --git a/guide/en/content-beheerder/content-structuur.md b/guide/en/content-beheerder/content-structuur.md index 1fc5f4f..b59aec5 100644 --- a/guide/en/content-beheerder/content-structuur.md +++ b/guide/en/content-beheerder/content-structuur.md @@ -4,28 +4,48 @@ Content is stored in the `content/` folder without a database. ## Supported file formats -- `.md` - Markdown (recommended) -- `.php` - Dynamic PHP pages -- `.html` - Static HTML pages +- `.md` — Markdown (recommended) +- `.php` — Dynamic PHP pages +- `.html` — Static HTML pages ## File name conventions ``` -en.page-name.md # English page -nl.pagina-naam.md # Dutch page +nl.pagina-naam.md # Dutch page +en.page-name.md # English page +nl.folder/ # Dutch folder (requires an index file to be clickable) ``` +The language prefix is dynamically removed based on available languages via `getAvailableLanguages()`. + ## Frontmatter Markdown files can contain frontmatter metadata: ```markdown --- -layout: full_content -plugins: HTMLBlock +layout: left_sidebar +plugins: + - HTMLBlock + - Navigation --- # Page title Content... -``` \ No newline at end of file +``` + +## Frontmatter fields + +- `layout` — Layout name (must exist in the `theme.json` template mapping; fallback to `config.default_template`) +- `plugins` — List of content plugins that appear in the sidebar + +### plugins field + +The `plugins` field determines: +- **Which plugins** appear in the sidebar (only content plugins, not system plugins) +- **The order** of the plugins in the sidebar (top to bottom) + +The order in the frontmatter is the order in which the plugins are shown. In the admin content-edit page you can adjust the order with up/down buttons; the frontmatter is updated live. + +Plugins are not shown when the chosen layout has no sidebar (e.g. `full_content`). \ No newline at end of file diff --git a/guide/en/content-beheerder/paginas-beheren.md b/guide/en/content-beheerder/paginas-beheren.md index 430827f..55885bf 100644 --- a/guide/en/content-beheerder/paginas-beheren.md +++ b/guide/en/content-beheerder/paginas-beheren.md @@ -5,12 +5,44 @@ 1. Login at `/admin` 2. Go to **Content** 3. Choose a folder or create a new page -4. Edit content in the editor +4. Edit content in the CodeMirror editor 5. Save with Ctrl+S ## Editor features -- **CodeMirror** editor with syntax highlighting +- **CodeMirror** editor with syntax highlighting (Markdown, PHP, HTML) - **Toolbar** for quick Markdown insertion -- **Live preview** via button -- **Auto-save** backups in `.bak/` folder \ No newline at end of file +- **Shortcuts**: Ctrl+S (save), Ctrl+N (new) +- **Auto-save** backups in `.bak/` folder + +## Layout selection + +On the content-edit 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. + +```markdown +--- +layout: left_sidebar +--- +``` + +Unknown layouts fall back to `config.default_template` from `theme.json`. + +## Plugin selection and order + +On the content-edit page you can choose content plugins for the sidebar: + +- **Selection** — Only content plugins (from `plugin.json` with `type: "content"`) appear in the plugin selection +- **Order** — Adjust the order with up/down buttons +- **Frontmatter update** — The frontmatter `plugins:` key is updated live on changes +- **Layout without sidebar** — Plugins are hidden when the chosen layout has no sidebar (e.g. `full_content`) + +```markdown +--- +layout: left_sidebar +plugins: + - HTMLBlock + - Navigation +--- +``` + +The order in the frontmatter determines the order of the plugins in the sidebar (top to bottom). \ No newline at end of file diff --git a/guide/en/index.md b/guide/en/index.md index 9598bc8..a3e78e1 100644 --- a/guide/en/index.md +++ b/guide/en/index.md @@ -1,3 +1,12 @@ # Manual +Welcome to the CodePress CMS manual (version 2.5.2). CodePress is a file-based CMS without a database — content, configuration and users are stored in files. + +The manual is divided into four sections: + +- **Admin Manager** — Managing the website: dashboard, content, configuration, themes, security, plugins (content and system), users with roles, statistics and logs +- **Content Manager** — Managing content: structure, managing pages (layout selection, plugin order), media and the Content API +- **Theme Developer** — Developing themes: structure, `theme.json`, Twig templates, SCSS styling (only CSS source), layouts and new themes +- **CodePress Developer** — Core development: architecture, core classes, plugin development (content/system), routing, security (RBAC), testing, debugging and performance + Select a topic from the navigation on the left. \ No newline at end of file diff --git a/guide/en/theme-developer.md b/guide/en/theme-developer.md index 361363f..d024655 100644 --- a/guide/en/theme-developer.md +++ b/guide/en/theme-developer.md @@ -3,7 +3,7 @@ The theme developer guide contains the following topics: - **Theme structure** - Folder structure of a theme -- **theme.json** - Theme configuration +- **theme.json** - Configuration of a theme - **Twig templates** - Twig syntax, variables and blocks - **SCSS styling** - Compiling and writing SCSS - **Layouts** - Defining and using layouts diff --git a/guide/en/theme-developer/layouts.md b/guide/en/theme-developer/layouts.md index 91a931a..e5ec933 100644 --- a/guide/en/theme-developer/layouts.md +++ b/guide/en/theme-developer/layouts.md @@ -1,5 +1,7 @@ # Layouts +Layouts define the page structure (left sidebar, full width, etc.). Layouts are defined in `theme.json` and chosen via frontmatter in content files. + ## Choosing a layout in content ```markdown @@ -14,14 +16,58 @@ Content... ## Layouts in theme.json +Layouts are defined in the `template` mapping. The `config.default_template` is the fallback for pages without a `layout:` frontmatter or with an unknown layout: + ```json { - "default_layout": "full_content", - "layouts": { - "full_content": "full_content.twig", - "left_sidebar": "left_sidebar.twig", - "right_sidebar": "right_sidebar.twig", - "custom1": "custom1.twig" - } + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig", + "guide": "guide.twig" + } } -``` \ No newline at end of file +``` + +## Layout template + +A layout template extends `base.twig` and fills the `content` block: + +```twig +{% extends 'base.twig' %} + +{% block content %} +
+ {{ content|raw }} +
+{% endblock %} +``` + +## Layouts with sidebar + +Layouts with a sidebar can show plugin content: + +```twig +{% extends 'base.twig' %} + +{% block content %} +
+
+ {{ content|raw }} +
+ +
+{% endblock %} +``` + +If a page has no plugins or the layout has no sidebar, `sidebar_content` is empty. + +## Guide layout + +The `guide` layout (`guide.twig`) is special for guides. It injects the Navigation plugin into the sidebar for sidebar navigation. Automatically used for pages in the `guide/` folder. \ No newline at end of file diff --git a/guide/en/theme-developer/thema-structuur.md b/guide/en/theme-developer/thema-structuur.md index 78b0955..8d62331 100644 --- a/guide/en/theme-developer/thema-structuur.md +++ b/guide/en/theme-developer/thema-structuur.md @@ -2,20 +2,49 @@ ``` themes/my-theme/ -├── theme.json # Theme configuration -├── base.twig # Main layout -├── full_content.twig # Layout: full-width -├── left_sidebar.twig # Layout: left sidebar -├── right_sidebar.twig # Layout: right sidebar -├── custom.twig # Layout: custom +├── theme.json # { title, config.default_template, template: layout→.twig } +├── base.twig # Main layout (head, header, nav, breadcrumb, footer) +├── full_content.twig # Layout: full width +├── left_sidebar.twig # Layout: sidebar on the left +├── right_sidebar.twig # Layout: sidebar on the right +├── custom1.twig # Layout: custom +├── guide.twig # Layout: guide with sidebar (Navigation plugin) ├── partials/ │ ├── header.twig │ ├── navigation.twig │ └── footer.twig └── assets/ - ├── scss/theme.scss # SCSS source - ├── css/ # CSS files - ├── js/theme.js # JavaScript - ├── fonts/ # Fonts - └── img/ # Images + ├── scss/theme.scss # SCSS source (the only CSS source) + ├── css_compiled/ # Generated by scssphp (read-only, do not edit manually) + ├── css/ # External CSS (bootstrap.min.css, bootstrap-icons.css, mobile.css) + ├── js/ # app.js, bootstrap.bundle.min.js + ├── fonts/ # bootstrap-icons.woff, woff2 + └── img/ # favicon, icon, world-map +``` + +## SCSS is the only CSS source + +- **ALWAYS** edit `assets/scss/theme.scss` — this is the only CSS source +- `ThemeManager` compiles SCSS at runtime to `assets/css_compiled/theme.css` via scssphp +- `assets/css_compiled/` is **read-only** — do not edit manually +- **NEVER** create or edit `assets/css/theme.css` manually; this file must not exist +- `ThemeManager::getCssUrl()` priority: 1) `assets/css/theme.css` (manual), 2) `assets/css_compiled/theme.css` (compiled). If `theme.css` exists, the SCSS is ignored. +- After SCSS changes: remove `assets/css_compiled/theme.css` and `.mtime` to force recompilation + +```bash +rm themes/my-theme/assets/css_compiled/theme.css themes/my-theme/assets/css_compiled/.mtime +``` + +## guide.twig + +Special layout for guides. Injects the Navigation plugin into the sidebar for sidebar navigation. Automatically used for pages in the `guide/` folder. + +## Plugin CSS loading + +Plugin CSS is automatically loaded after theme CSS in `base.twig`, so themes can override plugin styling: + +```twig +{% for cssUrl in plugin_css_urls|default([]) %} + +{% endfor %} ``` \ No newline at end of file diff --git a/guide/en/theme-developer/theme-json.md b/guide/en/theme-developer/theme-json.md index 8abe8e8..348e826 100644 --- a/guide/en/theme-developer/theme-json.md +++ b/guide/en/theme-developer/theme-json.md @@ -2,20 +2,45 @@ ```json { - "title": "My Theme", - "default_layout": "full_content", - "header_color": "#0a369d", - "layouts": { - "full_content": "full_content.twig", - "left_sidebar": "left_sidebar.twig", - "right_sidebar": "right_sidebar.twig" - } + "title": "My Theme", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig", + "guide": "guide.twig" + } } ``` ## Fields -- `title` - Display name in admin -- `default_layout` - Default layout for new pages -- `header_color` - Admin sidebar color -- `layouts` - Mapping of layout names to .twig files \ No newline at end of file +- `title` — Display name in admin +- `config.default_template` — Default layout for pages without a `layout:` frontmatter (fallback for unknown layouts) +- `template` — Mapping from layout name to `.twig` file + +## Template mapping + +The `template` mapping defines which layouts are available. Each key is a layout name, each value is the `.twig` file: + +| Layout name | Twig file | Description | +|-------------|-----------|-------------| +| `full_content` | `full_content.twig` | Full width, no sidebar | +| `left_sidebar` | `left_sidebar.twig` | Sidebar on the left | +| `right_sidebar` | `right_sidebar.twig` | Sidebar on the right | +| `custom1` | `custom1.twig` | Custom layout | +| `guide` | `guide.twig` | Guide with sidebar (Navigation plugin) | + +## Layout selection + +- Layouts are chosen via the frontmatter `layout:` key in content files +- Unknown layouts fall back to `config.default_template` +- `ThemeManager::getTemplates()` returns the template mapping +- `ThemeManager::getConfig()` returns the config section (including `default_template`) + +## Guide layout + +The `guide` layout is special for guides. `getGuidePage()` in `CodePressCMS.php` automatically injects the Navigation plugin into the metadata for sidebar navigation. \ No newline at end of file diff --git a/guide/nl/admin-beheerder.md b/guide/nl/admin-beheerder.md index 835a5fc..341063e 100644 --- a/guide/nl/admin-beheerder.md +++ b/guide/nl/admin-beheerder.md @@ -2,14 +2,14 @@ De admin beheerder handleiding bevat de volgende onderwerpen: -- **Dashboard** - Overzicht van de website -- **Content beheer** - Bestanden en pagina's beheren -- **Configuratie** - Site instellingen -- **Thema beheer** - Thema's beheren en aanmaken -- **Beveiliging** - Bot bescherming en sessies -- **Plugins** - Plugins beheren en aanmaken -- **Gebruikers** - Gebruikers toevoegen en verwijderen -- **Statistieken** - Bezoekersstatistieken bekijken +- **Dashboard** - Role-based overzicht van de website (Admin, Content Beheerder, BI Beheerder, Site Admin) +- **Content beheer** - Bestanden en pagina's beheren met layout selectie en plugins +- **Configuratie** - Site instellingen (titel, taal, auteur, analytics, logging) +- **Thema beheer** - Thema's beheren, activeren en aanmaken (SCSS compilatie) +- **Beveiliging** - Bot bescherming, rate limiting en sessie instellingen +- **Plugins** - Plugins beheren: content (sidebar) en systeem (admin menu/API) +- **Gebruikers** - Gebruikersbeheer met rollen (Admin, Content Beheerder, BI Beheerder, Site Admin) +- **Statistieken** - Bezoekersstatistieken bekijken en exporteren - **Logs** - Logbestanden bekijken en filteren Selecteer een onderwerp uit de navigatie aan de linkerkant. \ No newline at end of file diff --git a/guide/nl/admin-beheerder/content-beheer.md b/guide/nl/admin-beheerder/content-beheer.md index 6dca670..6c08b4d 100644 --- a/guide/nl/admin-beheerder/content-beheer.md +++ b/guide/nl/admin-beheerder/content-beheer.md @@ -2,16 +2,45 @@ ## Bestanden beheren -- **Uploaden** - Media bestanden uploaden -- **Nieuwe map** - Mappen structuur aanmaken -- **Nieuw bestand** - Pagina aanmaken -- **Bewerken** - Bestaande content wijzigen -- **Hernoemen** - Bestandsnamen aanpassen -- **Verplaatsen** - Content verplaatsen -- **Verwijderen** - Content verwijderen +- **Nieuwe map** — Mappen structuur aanmaken +- **Nieuw bestand** — Pagina aanmaken (`.md`, `.php`, `.html`) +- **Bewerken** — Bestaande content wijzigen in CodeMirror editor +- **Hernoemen** — Bestands- of mapnamen aanpassen +- **Verplaatsen** — Content verplaatsen naar andere map +- **Verwijderen** — Content verwijderen +- **Map hernoemen** — Map naam wijzigen -## Editor +## Editor (content-edit) -- CodeMirror met syntax highlighting -- Toolbar voor Markdown formatting -- Sneltoetsen: Ctrl+S (opslaan), Ctrl+N (nieuw) \ No newline at end of file +- **CodeMirror** met syntax highlighting (Markdown, PHP, HTML) +- **Toolbar** voor snel Markdown invoeren +- **Sneltoetsen**: Ctrl+S (opslaan), Ctrl+N (nieuw) + +## Layout selectie + +Op de content-edit pagina kun je de layout kiezen uit de layouts gedefinieerd in `theme.json` (template mapping). De geselecteerde layout wordt opgeslagen in de frontmatter `layout:` key. + +## Plugins op pagina's + +- Content plugins (uit `plugin.json` met `type: "content"`) verschijnen in de plugin selectie +- Kies welke plugins in de sidebar verschijnen +- **Volgorde aanpasbaar** met up/down knoppen +- De plugin volgorde wordt opgeslagen in de frontmatter `plugins:` key +- Plugins worden **verbergen** als de gekozen layout geen sidebar heeft (bijv. `full_content`) + +## Frontmatter + +De editor werkt de frontmatter live bij bij wijzigingen van layout of plugin selectie: + +```markdown +--- +layout: left_sidebar +plugins: + - HTMLBlock + - Navigation +--- + +# Pagina titel + +Content... +``` \ No newline at end of file diff --git a/guide/nl/admin-beheerder/dashboard.md b/guide/nl/admin-beheerder/dashboard.md index 01d0159..18fd674 100644 --- a/guide/nl/admin-beheerder/dashboard.md +++ b/guide/nl/admin-beheerder/dashboard.md @@ -1,10 +1,32 @@ # Dashboard -Het dashboard toont een overzicht van: +Het dashboard toont een **role-based overzicht** van de website. Welke widgets zichtbaar zijn, hangt af van de rol van de ingelogde gebruiker. -- Weergaven (30 dagen) -- Unieke bezoekers +## Rollen en widgets + +### Admin +- Weergaven (30 dagen) en unieke bezoekers - Aantal pagina's en mappen - Actieve plugins - Recente activiteit -- Snelle acties \ No newline at end of file +- Systeem informatie +- Snelle acties (nieuwe pagina, plugin, thema) + +### Content Beheerder +- Aantal pagina's en mappen +- Recente content wijzigingen +- Snelle acties (nieuwe pagina, map) + +### BI Beheerder +- Weergaven (30 dagen) en unieke bezoekers +- Top pagina's +- Recente bezoeken + +### Site Admin +- Actieve plugins en thema's +- Systeem informatie +- Snelle acties (thema, plugin, update) + +## Toegang + +Het dashboard is de standaard pagina na login (`/admin/dashboard`). Alle rollen hebben toegang tot het dashboard. \ No newline at end of file diff --git a/guide/nl/admin-beheerder/gebruikers.md b/guide/nl/admin-beheerder/gebruikers.md index 7018b8e..0d4d9b8 100644 --- a/guide/nl/admin-beheerder/gebruikers.md +++ b/guide/nl/admin-beheerder/gebruikers.md @@ -1,13 +1,40 @@ # Gebruikers +Gebruikers worden opgeslagen in `admin/config/admin.json` (file-based, geen database). Elke gebruiker heeft een **rol** die bepaalt welke admin routes en sidebar items zichtbaar zijn. + +## Rollen + +CodePress kent vier rollen, gedefinieerd in `AdminAuth::ROLE_PERMISSIONS`: + +| Rol | Label | Permissies | +|-----|-------|-----------| +| `admin` | Admin | Alles (`*`) | +| `content-manager` | Content Beheerder | Content beheer, handleiding | +| `bi-manager` | BI Beheerder | Statistieken, logs, handleiding | +| `site-admin` | Site Admin | Thema, plugins, statistieken, logs, update, handleiding | + +Rollen worden getoond met hun label via `AdminAuth::ROLE_LABELS`. + ## Gebruiker toevoegen 1. Ga naar **Gebruikers** 2. Vul gebruikersnaam in -3. Kies wachtwoord -4. Klik **Toevoegen** +3. Kies wachtwoord (opgeslagen als bcrypt hash) +4. Selecteer een rol +5. Klik **Toevoegen** + +## Gebruiker bewerken + +- Wachtwoord wijzigen (nieuwe bcrypt hash) +- Rol wijzigen (beïnvloedt direct zichtbare routes en sidebar items) ## Gebruiker verwijderen - Kan niet voor eigen account -- Bevestig met wachtwoord \ No newline at end of file +- Bevestig met wachtwoord + +## Toegangscontrole + +- Route access wordt gecontroleerd in `public/admin.php` via `AdminAuth::hasPermission()` +- Onbevoegde routes geven een **403 error** +- Sidebar items worden conditioneel getoond via de `has_permission()` Twig function in `admin.twig` \ No newline at end of file diff --git a/guide/nl/admin-beheerder/plugins.md b/guide/nl/admin-beheerder/plugins.md index c3ad63d..b30d5f2 100644 --- a/guide/nl/admin-beheerder/plugins.md +++ b/guide/nl/admin-beheerder/plugins.md @@ -1,15 +1,49 @@ # Plugins +## Plugin types + +CodePress kent twee soorten plugins, bepaald door het `type` veld in `plugin.json`: + +- **Content plugins** (`type: "content"`) — Verschijnen in de sidebar en in de plugin selectie op content-edit pagina's. Bieden sidebar content via `getSidebarContent()`. +- **Systeem plugins** (`type: "system"`) — Worden geladen door PluginManager maar verschijnen NIET in de sidebar. Bieden functionaliteit via admin menu, routes en de CMSAPI. Geregistreerd via `getAdminMenu()` en `getAdminRoutes()`. + +Bij afwezigheid van een `type` veld wordt `content` aangenomen. + +## Essentiële plugins + +Essentiële plugins zijn gedefinieerd in `getProtectedPlugins()` in `public/admin.php`. Huidige essentiële plugin: **Navigation**. + +Deze plugins: +- Kunnen NIET worden gedeactiveerd +- Kunnen NIET worden bewerkt +- Kunnen NIET worden verwijderd + +Op de plugins pagina krijgen ze een **Essentieel** badge i.p.v. de actieknoppen. + ## Plugins beheren -- **Activeren/Deactiveren** - Plugins aan/uit -- **Bewerken** - Plugin code aanpassen -- **Configuratie** - Plugin instellingen -- **Verwijderen** - Plugin verwijderen +- **Activeren/Deactiveren** — Plugin aan/uit zetten (niet voor essentiële plugins) +- **Bewerken** — Plugin code aanpassen in CodeMirror (niet voor essentiële plugins) +- **Configuratie** — Plugin instellingen bewerken +- **Verwijderen** — Plugin map verwijderen (niet voor essentiële plugins) -## Nieuwe plugin +De admin plugins pagina toont een **Content** of **Systeem** badge per plugin. + +## Nieuwe plugin aanmaken 1. Ga naar **Plugins** → **Nieuwe plugin** -2. Geef naam op (bijv. `MijnPlugin`) -3. Bewerk `plugin.php` -4. Activeer de plugin \ No newline at end of file +2. Geef naam op (bijv. `MijnPlugin`) — dit wordt de mapnaam +3. Kies het type: **Content** of **Systeem** +4. Het bestand `MijnPlugin.php` wordt aangemaakt (NIET `plugin.php`) +5. Bewerk de plugin code in CodeMirror +6. Activeer de plugin + +## Plugin bestandsnaam + +Plugin PHP bestanden heten `.php` (bijv. `Navigation.php`, `HTMLBlock.php`). `PluginManager` laadt `$pluginDir . '/' . $pluginName . '.php'`. + +## Plugin CSS + +- Content en systeem plugins kunnen eigen CSS hebben in `assets/scss/` en `assets/css/` +- Plugin CSS wordt automatisch geladen ná theme CSS (in `base.twig`), zodat thema's plugin styling kunnen overschrijven +- Plugin assets worden geserveerd via `cms/router.php` op URL `/plugins//assets/...` \ No newline at end of file diff --git a/guide/nl/admin-beheerder/thema-beheer.md b/guide/nl/admin-beheerder/thema-beheer.md index e92d186..afe64b9 100644 --- a/guide/nl/admin-beheerder/thema-beheer.md +++ b/guide/nl/admin-beheerder/thema-beheer.md @@ -3,17 +3,64 @@ ## Thema's beheren 1. Ga naar **Thema** in admin menu -2. **Activeren** - Kies actief thema -3. **SCSS compileren** - Verwerk SCSS naar CSS -4. **Nieuw thema** - Eigen thema aanmaken +2. **Activeren** — Kies actief thema (wordt opgeslagen in `config.json`) +3. **SCSS compileren** — Verwerk SCSS naar CSS (geforceerd) +4. **Nieuw thema** — Eigen thema aanmaken via admin of handmatig ## Thema structuur ``` themes/default/ -├── theme.json # Thema configuratie -├── base.twig # Hoofd layout -├── full_content.twig # Layouts -├── partials/ # Header, nav, footer -└── assets/ # CSS, JS, afbeeldingen -``` \ No newline at end of file +├── theme.json # { title, config.default_template, template: layout→.twig } +├── base.twig # Hoofd layout (head, header, nav, breadcrumb, footer) +├── full_content.twig # Layout: volledige breedte +├── left_sidebar.twig # Layout: sidebar links +├── right_sidebar.twig # Layout: sidebar rechts +├── custom1.twig # Layout: custom +├── guide.twig # Layout: handleiding met sidebar (Navigation plugin) +├── partials/ # header.twig, navigation.twig, footer.twig +└── assets/ + ├── scss/theme.scss # SCSS bron (enige CSS bron — handmatige css/theme.css mag niet bestaan) + ├── css_compiled/ # Gegenereerd door scssphp (read-only, niet handmatig aanpassen) + ├── css/ # Externe CSS (bootstrap.min.css, bootstrap-icons.css, mobile.css) + ├── js/ # app.js, bootstrap.bundle.min.js + ├── fonts/ # bootstrap-icons.woff, woff2 + └── img/ # favicon, icon, world-map +``` + +## theme.json + +```json +{ + "title": "default", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig", + "guide": "guide.twig" + } +} +``` + +- `title` — Weergavenaam in admin +- `config.default_template` — Standaard layout voor pagina's zonder `layout:` frontmatter +- `template` — Mapping van layout naam naar `.twig` bestand + +## SCSS compilatie + +- `ThemeManager` compileert `assets/scss/theme.scss` runtime naar `assets/css_compiled/theme.css` via scssphp +- `css_compiled/` is **read-only** — niet handmatig aanpassen +- `assets/css/theme.css` mag **niet** bestaan; anders negeert `ThemeManager::getCssUrl()` de SCSS +- Na SCSS wijzigingen: verwijder `assets/css_compiled/theme.css` en `.mtime` om te forceren + +## Layouts + +Layouts worden gekozen via frontmatter `layout:` key in content bestanden. Onbekende layouts vallen terug op `config.default_template` uit `theme.json`. + +## guide.twig + +Speciale layout voor handleidingen. Injecteert de Navigation plugin in de sidebar voor zijbalk navigatie. Wordt automatisch gebruikt voor pagina's in de `guide/` map. \ No newline at end of file diff --git a/guide/nl/codepress-developer.md b/guide/nl/codepress-developer.md index 591b966..947b8bf 100644 --- a/guide/nl/codepress-developer.md +++ b/guide/nl/codepress-developer.md @@ -2,13 +2,20 @@ De CodePress developer handleiding bevat de volgende onderwerpen: -- **Architectuur** - CMS architectuur en mappenstructuur -- **Core classes** - CodePressCMS, ThemeManager, PluginManager -- **Plugin development** - Plugins ontwikkelen -- **Routing** - Frontend en admin routing -- **Beveiliging** - XSS, CSRF, path traversal -- **Testing** - Penetratie, accessibility en functionele tests -- **Debugging** - Logging en cache -- **Performance** - OPcache en SCSS caching +- **Architectuur** — CMS architectuur en mappenstructuur +- **Core classes** — CodePressCMS, ThemeManager, PluginManager, AdminAuth +- **Plugin development** — Plugin types (content/systeem), structuur, API +- **Routing** — Frontend, admin en plugin admin routing +- **Beveiliging** — XSS, CSRF, path traversal, RBAC +- **Testing** — Penetratie, accessibility en functionele tests +- **Debugging** — Logging en cache +- **Performance** — OPcache en SCSS caching + +Belangrijke concepten in CodePress 2.5.2: + +- **Plugin types** — Content plugins (sidebar) en systeem plugins (admin menu, routes, API) +- **Admin plugin API** — Systeem plugins kunnen admin menu items en routes registreren +- **SCSS compilatie** — `ThemeManager` compileert SCSS naar `css_compiled/` via scssphp (read-only) +- **Asset serving** — `public/asset.php` serveert themes/, admin/assets/ en plugins/ op Apache (i.p.v. PHP dev router) Selecteer een onderwerp uit de navigatie aan de linkerkant. \ No newline at end of file diff --git a/guide/nl/codepress-developer/architectuur.md b/guide/nl/codepress-developer/architectuur.md index cbeec72..6ff3510 100644 --- a/guide/nl/codepress-developer/architectuur.md +++ b/guide/nl/codepress-developer/architectuur.md @@ -1,11 +1,84 @@ # CMS Architectuur +CodePress is een file-based CMS zonder database. Content, configuratie en gebruikers worden opgeslagen in bestanden. + +## Mappenstructuur + ``` codepress/ -├── cms/core/ # Core engine -├── admin/ # Admin console -├── themes/ # Thema's -├── plugins/ # Plugins -├── content/ # Content -└── public/ # Web root -``` \ No newline at end of file +├── cms/ # Core CMS engine +│ ├── core/ +│ │ ├── class/ +│ │ │ ├── CodePressCMS.php # Hoofd CMS class (routing, rendering, breadcrumb) +│ │ │ ├── ThemeManager.php # Thema-resolver + Twig render + SCSS compile +│ │ │ ├── ContentAPI.php # Read-only API voor PHP content +│ │ │ ├── ContentSecurityPolicy.php # CSP header management +│ │ │ ├── Analytics.php # Bezoekersstatistieken +│ │ │ ├── BotGuard.php # Bot/AI detectie +│ │ │ ├── Cache.php # Cache systeem +│ │ │ ├── GeoIP.php # GeoIP lookup (land, vlag) +│ │ │ ├── Logger.php # Basis logging +│ │ │ ├── LogManager.php # Dynamisch logging (SQLite/syslog) +│ │ │ ├── RateLimiter.php # Rate limiting per IP +│ │ │ ├── RequestLogger.php # Request logging + visitor info +│ │ │ ├── SearchEngine.php # Volledige tekst zoekfunctie +│ │ │ └── AccessibilityManager.php # Accessibility features +│ │ ├── plugin/ +│ │ │ ├── PluginManager.php # Plugin loader (hooks, filters, sidebar, admin routes) +│ │ │ └── CMSAPI.php # API voor plugins (getPage, getConfig, etc.) +│ │ ├── config.php # Config loader (leest config.json) +│ │ └── index.php # Bootstrap (autoloader, requires) +│ ├── lang/ # Taalbestanden (nl.php, en.php) +│ └── router.php # PHP dev server router +├── themes/ # Dynamische thema's +│ └── default/ # Standaard thema (views + assets) +│ ├── theme.json # { title, config.default_template, template: layout→.twig } +│ ├── base.twig # Hoofd layout +│ ├── *.twig # Layout templates +│ ├── partials/ # header.twig, navigation.twig, footer.twig +│ └── assets/ +│ ├── scss/theme.scss # SCSS bron (enige CSS bron) +│ ├── css_compiled/ # Gegenereerd door scssphp (read-only) +│ ├── css/ # Externe CSS (bootstrap.min.css, etc.) +│ ├── js/ # JavaScript +│ └── img/ # Afbeeldingen +├── admin/ # Admin paneel +│ ├── config/ +│ │ ├── app.php # Admin app configuratie +│ │ └── admin.json # Gebruikers & security (file-based, .gitignore'd) +│ ├── src/ +│ │ └── AdminAuth.php # Authenticatie + RBAC +│ ├── theme/default/ # Admin thema (views + assets) +│ │ ├── theme.json +│ │ ├── assets/ # CSS, JS, CodeMirror, fonts +│ │ └── views/ # login.twig, layouts/, pages/ +│ └── storage/ # Logs, cache, geoip +├── plugins/ # CMS plugins +│ ├── Navigation/ # Essentiële navigatie plugin (beschermd) +│ │ ├── Navigation.php # Plugin code (NIET plugin.php) +│ │ ├── plugin.json # Metadata met type veld +│ │ └── assets/ # SCSS + CSS +│ └── HTMLBlock/ # Voorbeeld sidebar plugin +├── content/ # Website content (.md, .php, .html) — .gitignore'd +├── guide/ # Handleidingen (nl/en) +├── public/ # Web root +│ ├── index.php # Website entry point +│ ├── admin.php # Admin entry point + routing +│ ├── asset.php # Asset server voor Apache (themes/, admin/assets/, plugins/) +│ ├── .htaccess # Stuurt asset URLs door naar asset.php +│ ├── favicon.ico +│ └── robots.txt +├── var/ # Cache (twig) — .gitignore'd +├── config.json # Site configuratie — .gitignore'd +├── composer.json # PHP dependencies (CommonMark, Twig, scssphp) +└── version.php # Versie informatie (2.5.2) +``` + +## Principes + +- **Geen database** — Alles in bestanden (content in `content/`, gebruikers in `admin/config/admin.json`, config in `config.json`) +- **File-based auth** — `AdminAuth` gebruikt bcrypt hashes in `admin.json`, sessies voor login +- **Twig templating** — Themes gebruiken Twig; `ThemeManager` rendert via Twig +- **SCSS compilatie** — `assets/scss/theme.scss` → `assets/css_compiled/theme.css` via scssphp (read-only output) +- **Plugin systeem** — `PluginManager` laadt content en systeem plugins met hooks/filters +- **Asset serving** — PHP dev router (`cms/router.php`) of Apache (`.htaccess` → `public/asset.php`) \ No newline at end of file diff --git a/guide/nl/codepress-developer/core-classes.md b/guide/nl/codepress-developer/core-classes.md index 31c1a81..6e21c4a 100644 --- a/guide/nl/codepress-developer/core-classes.md +++ b/guide/nl/codepress-developer/core-classes.md @@ -10,6 +10,13 @@ $cms->init(); $cms->renderPage($pagePath); ``` +Verantwoordelijkheden: +- Routing en pagina rendering +- Breadcrumb generatie (dynamisch: Home > [submappen] > [pagina]) +- Guide pagina's laden (`getGuidePage()`) +- Titel extractie uit H1 (`getTitleFromFile()`) +- Weergavenaam verwerking (`formatDisplayName()`) + ## ThemeManager.php Themabeheer in `cms/core/class/ThemeManager.php`: @@ -19,14 +26,84 @@ $themeManager = new ThemeManager($config); $themeManager->getActiveTheme(); $themeManager->renderTwig($template, $data); $themeManager->compileCss($force); +$themeManager->getCssUrl(); ``` +Verantwoordelijkheden: +- Actief thema resolveren vanuit `config.json` +- `theme.json` laden (title, config.default_template, template mapping) +- Twig environment bouwen (geroot in thema map) +- **SCSS compilatie** — compileert `assets/scss/theme.scss` naar `assets/css_compiled/theme.css` via scssphp +- Layout resolveren naar `.twig` template (fallback op `config.default_template`) + +`getCssUrl()` prioriteit: 1) `assets/css/theme.css` (handmatig), 2) `assets/css_compiled/theme.css` (gecompileerd). + ## PluginManager.php -Plugin systeem in `cms/core/class/PluginManager.php`: +Plugin systeem in `cms/core/plugin/PluginManager.php`: ```php -$pluginManager = new PluginManager(); -$pluginManager->loadPlugins($enabledPlugins); +$pluginManager = new PluginManager($pluginsPath, $enabledPlugins); +$pluginManager->getSidebarContent($allowedPlugins); +$pluginManager->getPluginCssUrls(); $pluginManager->executeHook($name, $params); -``` \ No newline at end of file +$pluginManager->getAdminMenuItems(); +$pluginManager->handleAdminRoute($route); +$pluginManager->getPluginType($pluginName); +``` + +Verantwoordelijkheden: +- Plugins laden vanuit `plugins/` mappen (alleen ingeschakelde plugins) +- Plugin bestand: `.php` (NIET `plugin.php`) +- Hooks en filters systeem (`doAction`, `applyFilters`) +- Sidebar content verzamelen van content plugins (`getSidebarContent`) +- Plugin CSS URLs verzamelen (`getPluginCssUrls`) +- **Admin menu items** van systeem plugins (`getAdminMenuItems`) +- **Admin routes** afhandelen via systeem plugins (`handleAdminRoute`) +- **Plugin type** bepalen (`getPluginType` — `content` of `system`) +- `isPluginViewable` — systeem plugins verschijnen niet in sidebar + +## AdminAuth.php + +Authenticatie en RBAC in `admin/src/AdminAuth.php`: + +```php +$auth = new AdminAuth($appConfig); +$auth->login($username, $password); +$auth->logout(); +$auth->hasPermission($route); +$auth->verifyCsrf($token); +``` + +Constanten: +- `ROLE_PERMISSIONS` — Mapping van rol → toegestane route prefixes. `admin` heeft wildcard `*`. +- `ROLE_LABELS` — Human-readable labels per rol. + +Rollen: + +| Rol | Label | Permissies | +|-----|-------|-----------| +| `admin` | Admin | Alles (`*`) | +| `content-manager` | Content Beheerder | Content beheer, handleiding | +| `bi-manager` | BI Beheerder | Statistieken, logs, handleiding | +| `site-admin` | Site Admin | Thema, plugins, statistieken, logs, update, handleiding | + +Verantwoordelijkheden: +- Session-based authenticatie +- bcrypt password hashing +- CSRF tokens (`verifyCsrf`) +- Brute-force lockout (login attempts tracking) +- RBAC via `hasPermission($route)` — checkt route tegen `ROLE_PERMISSIONS` + +## CMSAPI.php + +Plugin API in `cms/core/plugin/CMSAPI.php`: + +```php +$api = PluginManager::getAPI(); +$config = $api->getConfig(); +$page = $api->getPage($path); +$content = $api->getContent(); +``` + +Biedt read-only toegang aan plugins tot CMS data (config, pagina's, content). \ No newline at end of file diff --git a/guide/nl/codepress-developer/plugin-development.md b/guide/nl/codepress-developer/plugin-development.md index 707daf2..319dc17 100644 --- a/guide/nl/codepress-developer/plugin-development.md +++ b/guide/nl/codepress-developer/plugin-development.md @@ -1,43 +1,144 @@ # Plugin Development +## Plugin types + +CodePress kent twee soorten plugins, bepaald door het `type` veld in `plugin.json`: + +- **Content plugins** (`type: "content"`) — Verschijnen in de sidebar en in de plugin selectie op content-edit pagina's. Bieden sidebar content via `getSidebarContent()`. +- **Systeem plugins** (`type: "system"`) — Worden geladen door PluginManager maar verschijnen NIET in de sidebar. Bieden functionaliteit via admin menu, routes en de CMSAPI. + +Bij afwezigheid van een `type` veld wordt `content` aangenomen. + ## Plugin structuur ``` plugins/MijnPlugin/ -├── plugin.json # Plugin metadata -├── plugin.php # Plugin code -└── config.json # Optionele configuratie +├── MijnPlugin.php # Plugin code (NIET plugin.php) +├── plugin.json # Metadata met type veld +├── config.json # Optionele configuratie +└── assets/ + ├── scss/mijnplugin.scss # SCSS bron (optioneel) + └── css/mijnplugin.css # CSS (handmatig onderhouden) ``` +Plugin bestanden heten `.php` (bijv. `Navigation.php`, `HTMLBlock.php`). `PluginManager` laadt `$pluginDir . '/' . $pluginName . '.php'`. + ## plugin.json ```json { - "name": "Mijn Plugin", - "version": "1.0.0", - "author": "Jouw Naam", - "description": "Beschrijving" + "name": "Mijn Plugin", + "version": "1.0.0", + "author": "Jouw Naam", + "description": "Beschrijving", + "type": "content" } ``` -## plugin.php voorbeeld +- `name` — Weergavenaam +- `type` — `"content"` of `"system"` (default: `content`) + +## Content plugin voorbeeld ```php 'Mijn Plugin', + 'type' => 'content', + ]; + } -echo '
Hello World
'; + public function getSidebarContent(): string + { + return '

Hello World

'; + } +} ``` +## Systeem plugin voorbeeld + +```php + 'Mijn Systeem', + 'type' => 'system', + ]; + } + + public function getAdminMenu(): array + { + return [ + ['label' => 'Mijn Systeem', 'route' => 'mijn-systeem', 'icon' => 'bi-gear'], + ]; + } + + public function getAdminRoutes(): array + { + return ['mijn-systeem']; + } + + public function handleAdminRoute(string $route): void + { + echo '

Mijn Systeem pagina

'; + } +} +``` + +Systeem plugins worden via `PluginManager::getAdminMenuItems()` in de admin sidebar getoond en via `PluginManager::handleAdminRoute()` afgehandeld. + ## CMSAPI gebruiken ```php getConfig(); -$content = $api->getContent(); -``` \ No newline at end of file +$page = $api->getPage($path); +``` + +`setAPI()` wordt automatisch aangeroepen door `PluginManager` als de plugin de methode heeft. + +## Plugin CSS + +- Plugin CSS in `assets/css/` is handmatig te onderhouden (SCSS compilatie voor plugins is nog niet automatisch) +- Plugin CSS wordt automatisch geladen ná theme CSS (in `base.twig`), zodat thema's plugin styling kunnen overschrijven +- Plugin assets worden geserveerd via `cms/router.php` op URL `/plugins//assets/...` +- Implementeer `getCssUrl()` in de plugin klasse om de CSS URL terug te geven + +```php +public function getCssUrl(): string +{ + return '/plugins/MijnPlugin/assets/css/mijnplugin.css'; +} +``` + +## Hooks en filters + +PluginManager auto-registert deze methoden als hooks/filters: + +- **Hooks**: `onPageLoad`, `onBeforeRender`, `onAfterRender`, `onSearch`, `onMenuBuild` +- **Filters**: `onContentFilter`, `onTitleFilter`, `onMenuFilter` + +```php +public function onPageLoad($page) { /* ... */ } +public function onContentFilter($content) { return $content; } +``` + +## Essentiële plugins + +Essentiële plugins zijn gedefinieerd in `getProtectedPlugins()` in `public/admin.php`. Huidige essentiële plugin: **Navigation**. + +Deze plugins kunnen niet worden gedeactiveerd, bewerkt of verwijderd. Voeg altijd de `isProtectedPlugin()` check toe aan nieuwe plugin handlers. \ No newline at end of file diff --git a/guide/nl/codepress-developer/routing.md b/guide/nl/codepress-developer/routing.md index 585c48c..6537144 100644 --- a/guide/nl/codepress-developer/routing.md +++ b/guide/nl/codepress-developer/routing.md @@ -2,18 +2,60 @@ ## Frontend routing -Via `cms/router.php` voor PHP dev server: +Frontend routing verloopt via `cms/router.php` (PHP dev server) of `.htaccess` (Apache). Beide zorgen voor clean URLs. -```php -// Schone URLs: /nl/pagina -// Query: ?page=pagina&lang=nl +### PHP dev server + +Start de server met: + +```bash +php -S localhost:8080 cms/router.php ``` +`cms/router.php` serveert: +- Schone URLs: `/nl/pagina` → `public/index.php?page=pagina&lang=nl` +- `themes/` assets +- `admin/assets/` assets +- `plugins/` assets + +### Apache (live server) + +`public/.htaccess` herschrijft URLs naar `public/index.php`. Asset URLs (`/themes/`, `/admin/assets/`, `/plugins/`) worden doorgestuurd naar `public/asset.php`. + +`public/asset.php` serveert bestanden vanuit de juiste mappen met het juiste MIME-type: +- `/themes//assets/...` → `themes//assets/...` +- `/admin/assets/...` → `admin/theme/default/assets/...` +- `/plugins//assets/...` → `plugins//assets/...` + ## Admin routing -Via `public/admin.php`: +Admin routing verloopt via `public/admin.php` met clean URLs: + +``` +/admin/dashboard → ?route=dashboard +/admin/content → ?route=content +/admin/plugins → ?route=plugins +``` + +`cms/router.php` of `.htaccess` zet `/admin/` om naar `?route=`. + +### Route access control (RBAC) + +Elke route wordt gecontroleerd via `AdminAuth::hasPermission($route)`: +- `admin` rol heeft wildcard `*` toegang +- Andere rollen hebben een expliciete lijst van toegestane routes in `ROLE_PERMISSIONS` +- Onbevoegde routes geven een **403 error** + +## Plugin admin routing + +Systeem plugins kunnen admin routes registreren. Deze worden afgehandeld door `PluginManager::handleAdminRoute($route)`: + +1. Systeem plugin registreert routes via `getAdminRoutes()` +2. `PluginManager::getAdminMenuItems()` verzamelt admin menu items via `getAdminMenu()` +3. Bij een admin request zoekt `PluginManager::handleAdminRoute($route)` een plugin die de route afhandelt +4. De plugin methode `handleAdminRoute($route)` rendert de pagina inhoud ```php -// Routes: /admin/dashboard, /admin/content, etc. -// Query parameter: ?route=dashboard +// PluginManager roept deze aan voor /admin/mijn-systeem +$plugin->handleAdminRoute('mijn-systeem'); ``` \ No newline at end of file diff --git a/guide/nl/content-beheerder/content-structuur.md b/guide/nl/content-beheerder/content-structuur.md index 4bcfb50..3311612 100644 --- a/guide/nl/content-beheerder/content-structuur.md +++ b/guide/nl/content-beheerder/content-structuur.md @@ -4,28 +4,48 @@ Content wordt opgeslagen in de `content/` map zonder database. ## Ondersteunde bestandsformaten -- `.md` - Markdown (aanbevolen) -- `.php` - Dynamische PHP pagina's -- `.html` - Statische HTML pagina's +- `.md` — Markdown (aanbevolen) +- `.php` — Dynamische PHP pagina's +- `.html` — Statische HTML pagina's ## Bestandsnaam conventies ``` nl.pagina-naam.md # Nederlandse pagina en.page-name.md # Engelse pagina +nl.map/ # Nederlandse map (vereist index bestand om klikbaar te zijn) ``` +Taalprefix wordt dynamisch verwijderd op basis van beschikbare talen via `getAvailableLanguages()`. + ## Frontmatter Markdown bestanden kunnen frontmatter metadata bevatten: ```markdown --- -layout: full_content -plugins: HTMLBlock +layout: left_sidebar +plugins: + - HTMLBlock + - Navigation --- # Pagina titel Content... -``` \ No newline at end of file +``` + +## Frontmatter velden + +- `layout` — Layout naam (moet voorkomen in `theme.json` template mapping; fallback op `config.default_template`) +- `plugins` — Lijst van content plugins die in de sidebar verschijnen + +### plugins veld + +Het `plugins` veld bepaalt: +- **Welke plugins** in de sidebar verschijnen (alleen content plugins, niet systeem plugins) +- **De volgorde** van de plugins in de sidebar (top tot onder) + +De volgorde in de frontmatter is de volgorde waarin de plugins worden getoond. In de admin content-edit pagina kun je de volgorde aanpassen met up/down knoppen; de frontmatter wordt live bijgewerkt. + +Plugins worden niet getoond als de gekozen layout geen sidebar heeft (bijv. `full_content`). \ No newline at end of file diff --git a/guide/nl/content-beheerder/paginas-beheren.md b/guide/nl/content-beheerder/paginas-beheren.md index 3127d1a..5172c17 100644 --- a/guide/nl/content-beheerder/paginas-beheren.md +++ b/guide/nl/content-beheerder/paginas-beheren.md @@ -5,12 +5,44 @@ 1. Login op `/admin` 2. Ga naar **Content** 3. Kies een map of maak een nieuwe pagina -4. Bewerk content in de editor +4. Bewerk content in de CodeMirror editor 5. Sla op met Ctrl+S ## Editor functies -- **CodeMirror** editor met syntax highlighting +- **CodeMirror** editor met syntax highlighting (Markdown, PHP, HTML) - **Toolbar** voor snel Markdown invoegen -- **Live preview** via knop -- **Auto-save** backups in `.bak/` map \ No newline at end of file +- **Sneltoetsen**: Ctrl+S (opslaan), Ctrl+N (nieuw) +- **Auto-save** backups in `.bak/` map + +## Layout selectie + +Op de content-edit pagina kun je de layout kiezen uit de layouts gedefinieerd in `theme.json` (template mapping). De geselecteerde layout wordt opgeslagen in de frontmatter `layout:` key. + +```markdown +--- +layout: left_sidebar +--- +``` + +Onbekende layouts vallen terug op `config.default_template` uit `theme.json`. + +## Plugin selectie en volgorde + +Op de content-edit pagina kun je content plugins kiezen voor de sidebar: + +- **Selectie** — Alleen content plugins (uit `plugin.json` met `type: "content"`) verschijnen in de plugin selectie +- **Volgorde** — Pas de volgorde aan met up/down knoppen +- **Frontmatter update** — De frontmatter `plugins:` key wordt live bijgewerkt bij wijzigingen +- **Layout zonder sidebar** — Plugins worden verborgen als de gekozen layout geen sidebar heeft (bijv. `full_content`) + +```markdown +--- +layout: left_sidebar +plugins: + - HTMLBlock + - Navigation +--- +``` + +De volgorde in de frontmatter bepaalt de volgorde van de plugins in de sidebar (top tot onder). \ No newline at end of file diff --git a/guide/nl/index.md b/guide/nl/index.md index 3f314ea..ed010dc 100644 --- a/guide/nl/index.md +++ b/guide/nl/index.md @@ -1,3 +1,12 @@ # Handleiding +Welkom bij de CodePress CMS handleiding (versie 2.5.2). CodePress is een file-based CMS zonder database — content, configuratie en gebruikers worden opgeslagen in bestanden. + +De handleiding is verdeeld in vier secties: + +- **Admin Beheerder** — Beheer van de website: dashboard, content, configuratie, thema's, beveiliging, plugins (content en systeem), gebruikers met rollen, statistieken en logs +- **Content Beheerder** — Content beheren: structuur, pagina's beheren (layout selectie, plugin volgorde), media en de Content API +- **Theme Developer** — Thema's ontwikkelen: structuur, `theme.json`, Twig templates, SCSS styling (enige CSS bron), layouts en nieuwe thema's +- **CodePress Developer** — Core ontwikkeling: architectuur, core classes, plugin development (content/systeem), routing, beveiliging (RBAC), testing, debugging en performance + Selecteer een onderwerp uit de navigatie aan de linkerkant. \ No newline at end of file diff --git a/guide/nl/theme-developer/layouts.md b/guide/nl/theme-developer/layouts.md index 0516dbe..e5b14e1 100644 --- a/guide/nl/theme-developer/layouts.md +++ b/guide/nl/theme-developer/layouts.md @@ -1,5 +1,7 @@ # Layouts +Layouts definiëren de pagina structuur (sidebar links, volledige breedte, etc.). Layouts worden gedefinieerd in `theme.json` en gekozen via frontmatter in content bestanden. + ## Layout kiezen in content ```markdown @@ -14,14 +16,58 @@ Content... ## Layouts in theme.json +Layouts worden gedefinieerd in de `template` mapping. De `config.default_template` is de fallback voor pagina's zonder `layout:` frontmatter of met een onbekende layout: + ```json { - "default_layout": "full_content", - "layouts": { - "full_content": "full_content.twig", - "left_sidebar": "left_sidebar.twig", - "right_sidebar": "right_sidebar.twig", - "custom1": "custom1.twig" - } + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig", + "guide": "guide.twig" + } } -``` \ No newline at end of file +``` + +## Layout template + +Een layout template extends `base.twig` en vult het `content` block: + +```twig +{% extends 'base.twig' %} + +{% block content %} +
+ {{ content|raw }} +
+{% endblock %} +``` + +## Layouts met sidebar + +Layouts met sidebar kunnen plugin content tonen: + +```twig +{% extends 'base.twig' %} + +{% block content %} +
+
+ {{ content|raw }} +
+ +
+{% endblock %} +``` + +Als een pagina geen plugins heeft of de layout geen sidebar bevat, is `sidebar_content` leeg. + +## Guide layout + +De `guide` layout (`guide.twig`) is speciaal voor handleidingen. Het injecteert de Navigation plugin in de sidebar voor zijbalk navigatie. Wordt automatisch gebruikt voor pagina's in de `guide/` map. \ No newline at end of file diff --git a/guide/nl/theme-developer/thema-structuur.md b/guide/nl/theme-developer/thema-structuur.md index 74cd6e3..05c8f5f 100644 --- a/guide/nl/theme-developer/thema-structuur.md +++ b/guide/nl/theme-developer/thema-structuur.md @@ -2,20 +2,49 @@ ``` themes/mijn-thema/ -├── theme.json # Thema configuratie -├── base.twig # Hoofd layout -├── full_content.twig # Layout: full-width +├── theme.json # { title, config.default_template, template: layout→.twig } +├── base.twig # Hoofd layout (head, header, nav, breadcrumb, footer) +├── full_content.twig # Layout: volledige breedte ├── left_sidebar.twig # Layout: sidebar links ├── right_sidebar.twig # Layout: sidebar rechts -├── custom.twig # Layout: custom +├── custom1.twig # Layout: custom +├── guide.twig # Layout: handleiding met sidebar (Navigation plugin) ├── partials/ │ ├── header.twig │ ├── navigation.twig │ └── footer.twig └── assets/ - ├── scss/theme.scss # SCSS bron - ├── css/ # CSS bestanden - ├── js/theme.js # JavaScript - ├── fonts/ # Lettertypes - └── img/ # Afbeeldingen + ├── scss/theme.scss # SCSS bron (de enige CSS bron) + ├── css_compiled/ # Gegenereerd door scssphp (read-only, niet handmatig aanpassen) + ├── css/ # Externe CSS (bootstrap.min.css, bootstrap-icons.css, mobile.css) + ├── js/ # app.js, bootstrap.bundle.min.js + ├── fonts/ # bootstrap-icons.woff, woff2 + └── img/ # favicon, icon, world-map +``` + +## SCSS is de enige CSS bron + +- **ALTIJD** `assets/scss/theme.scss` aanpassen — dit is de enige CSS bron +- `ThemeManager` compileert SCSS runtime naar `assets/css_compiled/theme.css` via scssphp +- `assets/css_compiled/` is **read-only** — niet handmatig aanpassen +- **NOOIT** `assets/css/theme.css` handmatig aanmaken of aanpassen; dit bestand mag niet bestaan +- `ThemeManager::getCssUrl()` prioriteit: 1) `assets/css/theme.css` (handmatig), 2) `assets/css_compiled/theme.css` (gecompileerd). Als `theme.css` bestaat, wordt de SCSS negeren. +- Na SCSS wijzigingen: verwijder `assets/css_compiled/theme.css` en `.mtime` om te forceren + +```bash +rm themes/mijn-thema/assets/css_compiled/theme.css themes/mijn-thema/assets/css_compiled/.mtime +``` + +## guide.twig + +Speciale layout voor handleidingen. Injecteert de Navigation plugin in de sidebar voor zijbalk navigatie. Wordt automatisch gebruikt voor pagina's in de `guide/` map. + +## Plugin CSS laden + +Plugin CSS wordt automatisch geladen ná theme CSS in `base.twig`, zodat thema's plugin styling kunnen overschrijven: + +```twig +{% for cssUrl in plugin_css_urls|default([]) %} + +{% endfor %} ``` \ No newline at end of file diff --git a/guide/nl/theme-developer/theme-json.md b/guide/nl/theme-developer/theme-json.md index 2e8bec3..57c4401 100644 --- a/guide/nl/theme-developer/theme-json.md +++ b/guide/nl/theme-developer/theme-json.md @@ -2,20 +2,45 @@ ```json { - "title": "Mijn Thema", - "default_layout": "full_content", - "header_color": "#0a369d", - "layouts": { - "full_content": "full_content.twig", - "left_sidebar": "left_sidebar.twig", - "right_sidebar": "right_sidebar.twig" - } + "title": "Mijn Thema", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig", + "guide": "guide.twig" + } } ``` ## Velden -- `title` - Weergavenaam in admin -- `default_layout` - Standaard layout voor nieuwe pagina's -- `header_color` - Kleur admin sidebar -- `layouts` - Mapping van layout namen naar .twig bestanden \ No newline at end of file +- `title` — Weergavenaam in admin +- `config.default_template` — Standaard layout voor pagina's zonder `layout:` frontmatter (fallback bij onbekende layouts) +- `template` — Mapping van layout naam naar `.twig` bestand + +## Template mapping + +De `template` mapping definieert welke layouts beschikbaar zijn. Elke key is een layout naam, elke value is het `.twig` bestand: + +| Layout naam | Twig bestand | Beschrijving | +|-------------|--------------|--------------| +| `full_content` | `full_content.twig` | Volledige breedte, geen sidebar | +| `left_sidebar` | `left_sidebar.twig` | Sidebar links | +| `right_sidebar` | `right_sidebar.twig` | Sidebar rechts | +| `custom1` | `custom1.twig` | Custom layout | +| `guide` | `guide.twig` | Handleiding met sidebar (Navigation plugin) | + +## Layout keuze + +- Layouts worden gekozen via frontmatter `layout:` key in content bestanden +- Onbekende layouts vallen terug op `config.default_template` +- `ThemeManager::getTemplates()` geeft de template mapping terug +- `ThemeManager::getConfig()` geeft de config sectie terug (inclusief `default_template`) + +## Guide layout + +De `guide` layout is speciaal voor handleidingen. `getGuidePage()` in `CodePressCMS.php` injecteert automatisch de Navigation plugin in de metadata voor zijbalk navigatie. \ No newline at end of file