v1.9.2: Admin sidebar groepen, IP-uitsluitingen, guides herschreven

This commit is contained in:
2026-07-29 16:08:04 +02:00
parent 92d782e6c5
commit 5ab18c7b46
4 changed files with 817 additions and 892 deletions
+29 -16
View File
@@ -22,6 +22,7 @@ $layoutSidebarColor = $layoutThemeConfig['header_color'] ?? '#0a369d';
.admin-sidebar .nav-link:hover { color: #fff; background-color: rgba(255,255,255,0.1); }
.admin-sidebar .nav-link.active { color: #fff; background-color: rgba(255,255,255,0.2); border-left: 3px solid #fff; }
.admin-sidebar .nav-link i { width: 24px; text-align: center; margin-right: 0.5rem; }
.admin-sidebar .nav-section { color: rgba(255,255,255,0.4); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; padding: 1rem 1.25rem 0.3rem 1.25rem; }
.admin-main { margin-left: 240px; padding: 2rem; }
.admin-brand { color: #fff; padding: 1.25rem; font-size: 1.1rem; border-bottom: 1px solid rgba(255,255,255,0.15); }
.admin-brand i { margin-right: 0.5rem; }
@@ -45,37 +46,50 @@ $layoutSidebarColor = $layoutThemeConfig['header_color'] ?? '#0a369d';
<i class="bi bi-gear-fill"></i> CodePress Admin
</div>
<ul class="nav flex-column mt-2">
<li class="nav-section">Algemeen</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'dashboard' || ($route ?? '') === '' ? 'active' : '' ?>" href="/admin/dashboard">
<i class="bi bi-speedometer2"></i> Dashboard
</a>
</li>
<li class="nav-section">Content</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'content' || str_starts_with($route ?? '', 'content') ? 'active' : '' ?>" href="/admin/content">
<i class="bi bi-file-earmark-text"></i> Content
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'theme' ? 'active' : '' ?>" href="/admin/theme">
<i class="bi bi-palette"></i> Thema
</a>
</li>
<li class="nav-section">Instellingen</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'config' ? 'active' : '' ?>" href="/admin/config">
<i class="bi bi-sliders"></i> Configuratie
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'theme' ? 'active' : '' ?>" href="/admin/theme">
<i class="bi bi-palette"></i> Thema
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'security' ? 'active' : '' ?>" href="/admin/security">
<i class="bi bi-shield-check"></i> Beveiliging
</a>
</li>
<li class="nav-section">Gegevens</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'statistics' ? 'active' : '' ?>" href="/admin/statistics">
<i class="bi bi-bar-chart"></i> Statistieken
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'logs' ? 'active' : '' ?>" href="/admin/logs">
<i class="bi bi-journal-text"></i> Logs
</a>
</li>
<li class="nav-section">Systeem</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'plugins' ? 'active' : '' ?>" href="/admin/plugins">
<i class="bi bi-plug"></i> Plugins
@@ -86,22 +100,21 @@ $layoutSidebarColor = $layoutThemeConfig['header_color'] ?? '#0a369d';
<i class="bi bi-people"></i> Gebruikers
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'guide' ? 'active' : '' ?>" href="/admin/guide">
<i class="bi bi-book"></i> Handleiding
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'logs' ? 'active' : '' ?>" href="/admin/logs">
<i class="bi bi-journal-text"></i> Logs
</a>
</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'update' ? 'active' : '' ?>" href="/admin/update">
<i class="bi bi-cloud-arrow-down"></i> Update
</a>
</li>
<li class="nav-item mt-3">
<li class="nav-section">Help</li>
<li class="nav-item">
<a class="nav-link <?= ($route ?? '') === 'guide' ? 'active' : '' ?>" href="/admin/guide">
<i class="bi bi-book"></i> Handleiding
</a>
</li>
<li class="nav-section mt-3">Links</li>
<li class="nav-item">
<a class="nav-link" href="/" target="_blank">
<i class="bi bi-box-arrow-up-right"></i> Website bekijken
</a>
+382 -428
View File
@@ -3,22 +3,36 @@
## Table of Contents
- [Overview](#overview)
- [Features](#features)
- [Installation](#installation)
- [Project Structure](#project-structure)
- [Configuration](#configuration)
- [Content](#content)
- [Content Structure](#content-structure)
- [Admin Console](#admin-console)
- [Logging & Request Log](#logging--request-log)
- [Content API (for PHP content files)](#content-api-for-php-content-files)
- [Settings](#settings)
- [Configuration](#configuration)
- [Themes](#themes)
- [Security](#security)
- [Data](#data)
- [Statistics & Analytics](#statistics--analytics)
- [Logging](#logging)
- [System](#system)
- [Plugin System](#plugin-system)
- [User Management](#user-management)
- [Update](#update)
- [Guide (in Admin)](#guide-in-admin)
- [Other](#other)
- [Templates](#templates)
- [URL Structure](#url-structure)
- [SEO Optimization](#seo-optimization)
- [Plugin System](#plugin-system)
- [Content API](#content-api-for-php-content-files)
- [Analytics & Tracking](#analytics--tracking)
- [Frequently Asked Questions](#frequently-asked-questions)
- [Troubleshooting](#troubleshooting)
- [Security](#security)
- [Version](#version)
- [Support](#support)
- [License](#license)
@@ -27,72 +41,6 @@
CodePress CMS is a lightweight, file-based content management system built with PHP (>=8.0). Works without a database.
## Features
### Navigation
- Tab-style navigation with Bootstrap 5 styling
- Dropdown menus for folders and sub-folders
- Home button with icon
- Automatic menu generation based on directory structure
- Responsive design
- Breadcrumb navigation with sidebar toggle
- Active state marking
- **Sidebar toggle** - Button placed left of HOME in the breadcrumb to open/close the sidebar. The icon changes between open and closed state. The choice is preserved during the session
### Content Types
- **Markdown (.md)** - CommonMark support via `league/commonmark`
- **PHP (.php)** - Dynamic content with **Content API** (`$api` variable)
- **HTML (.html)** - Static HTML pages
- **Directory listings** - Automatic directory overviews
- **Language-specific content** - `en.` and `nl.` prefixes
### Search Functionality
- Full-text search through all content
- Results with snippets and highlighting
- Direct navigation to found pages
- SEO-friendly search results
- Search URL: `?search=query`
### Configuration
- **Settings form** in admin panel via `/admin/config`
- Dynamic homepage setting via dropdown (auto, newest modified page, or manual selection)
- SEO settings (description, keywords)
- Author information with links
- Theme configuration via `themes/` directory
- Language settings
- Feature toggles (auto_link_pages, search_enabled, breadcrumbs_enabled)
### Layout & Design
- Flexbox layout for responsive structure
- Fixed header with logo and search
- Breadcrumb navigation
- Fixed footer with file info and links
- Bootstrap 5 styling
- Mustache templates (`cms/templates/`)
- Semantic HTML5 structure
- **Dynamic layouts** with YAML frontmatter
- **Sidebar support** with plugin integration and toggle function via breadcrumb
- **Theme support** via `themes/` directory with theme.json per theme
### Admin Console
- Built-in admin panel at `/admin`
- **Dashboard** with statistics (pages, directories, plugins) and quick actions
- **Content management** - Browse files, upload, create, edit, rename, move and delete
- **CodeMirror editor** with toolbar (bold, italic, heading, link, image, list, media insert)
- **Media browser modal** in the editor for selecting images/files
- **Directory management** - Create, rename and delete directories (empty only)
- **Configuration editor** - Settings form for site configuration (title, homepage, language, SEO, author, features)
- **Theme management** - Create, activate, edit (colors, background) and delete themes
- **Plugin management** - Overview, create, edit, configure, enable/disable and delete
- **Media management** - Upload and delete media files in `content/-assets/`
- **User management** - Add, remove users, change passwords
- **Guide** - Built-in documentation with API reference
- **Logging** - Activity log and request log with IP, page, domain; view and download via `/admin/logs`
- **Bot & AI blocking** - Automatic 403 for known bots and AI crawlers
- Session-based authentication with bcrypt hashing
- CSRF protection, brute-force lockout (5 attempts, 15 min)
- Default login: `admin` / `admin` (change immediately after installation)
## Installation
1. Upload files to web server
@@ -111,7 +59,12 @@ codepress/
│ │ ├── class/
│ │ │ ├── CodePressCMS.php # Main CMS class (content, navigation, search)
│ │ │ ├── Logger.php # Structured logging system
│ │ │ ── SimpleTemplate.php # Mustache-style template engine
│ │ │ ── SimpleTemplate.php # Mustache-style template engine
│ │ │ ├── Analytics.php # Visitor statistics
│ │ │ ├── BotGuard.php # Bot/AI/scraper detection
│ │ │ ├── GeoIP.php # Country lookup by IP
│ │ │ ├── Cache.php # File-based caching
│ │ │ └── RateLimiter.php # Per-IP rate limiting
│ │ ├── plugin/
│ │ │ ├── PluginManager.php # Plugin loader and manager
│ │ │ └── CMSAPI.php # API for plugin developers
@@ -120,7 +73,6 @@ codepress/
│ ├── lang/ # Language files
│ │ ├── nl.php # Dutch translations
│ │ └── en.php # English translations
│ ├── logs/ # CMS logs
│ ├── templates/ # Mustache templates
│ │ ├── layout.mustache # Main layout (CSS, structure)
│ │ ├── assets/ # Header, navigation, footer partials
@@ -144,14 +96,18 @@ codepress/
│ │ ├── content-new.php # Create new content
│ │ ├── content-dir-form.php # Create/edit directory
│ │ ├── content-move-form.php # Move content
│ │ ├── config.php # Configuration editor (JSON)
│ │ ├── config.php # Configuration editor
│ │ ├── security.php # Security settings
│ │ ├── statistics.php # Statistics dashboard
│ │ ├── plugins.php # Plugin overview
│ │ ├── plugins-edit.php # Plugin PHP source code editor
│ │ ├── plugins-new.php # Create new plugin
│ │ ├── plugin-config.php # Plugin configuration editor
│ │ ├── theme.php # Theme management (create, activate, edit)
│ │ ├── media.php # Media management (upload, delete)
│ │ ── users.php # User management
│ │ ├── theme.php # Theme management
│ │ ├── users.php # User management
│ │ ── logs.php # Log viewer
│ │ ├── update.php # System update
│ │ └── guide.php # Guide
│ └── storage/logs/ # Admin logs
├── cli/ # CLI scripts & tests
├── content/ # Content files
@@ -160,8 +116,7 @@ codepress/
│ └── ... # Other content
├── plugins/ # CMS plugins
│ ├── HTMLBlock/ # Custom HTML blocks in sidebar
── MQTTTracker/ # Real-time analytics and tracking
│ └── test/ # Test plugin
── MQTTTracker/ # Real-time analytics and tracking
├── public/ # Web root
│ ├── index.php # Website entry point (media serving + CMS)
│ ├── admin.php # Admin entry point + routing
@@ -174,28 +129,173 @@ codepress/
├── themes/ # Theme definitions
│ ├── default/ # Default theme
│ │ └── theme.json # Colors, heights, background
│ └── test/ # Test theme
│ └── theme.json
│ └── ... # Other themes
├── config.json # Site configuration
├── version.php # Version information (1.6.0)
├── version.php # Version information
└── vendor/ # Composer dependencies
```
## Configuration
---
### Basic Configuration
## Content
The site configuration is managed via the **admin panel** at `/admin/config`. Here you'll find a settings form with the following sections:
### Content Structure
#### File Structure
```
content/
├── folder1/
│ ├── subfolder1/
│ │ ├── nl.page1.md
│ │ └── en.page1.md
│ └── page3.html
├── folder2/
│ └── page4.md
├── index.md
└── -assets/
├── image.jpg
└── document.pdf
```
#### File Naming
- Use lowercase filenames
- No spaces - use `-` or `_`
- Logical extensions - `.md`, `.php`, `.html`
- Unique names - no duplicates
- Language prefixes - `nl.file.md` and `en.file.md`
#### Media Files
Media files (images, PDFs, video, audio) can be placed in any `content/` subdirectory and are served via:
- **`/-media/path/file.jpg`** - Media from any content subdirectory
- **`/-assets/file.jpg`** - Backward compatibility (old URLs)
- Uploads via the admin panel go to `content/-assets/`
### Content API (for PHP content files)
PHP content files (`.php` in the `content/` directory) have access to an `$api` variable with the following methods:
#### Getting pages
```php
// Get all pages with titles
$pages = $api->getAllPages();
// Result: ['index' => 'Home', 'about' => 'About Us', ...]
// Get a specific page's content
$page = $api->getPage('about');
// $page['title'], $page['content'], $page['path'], $page['layout'], $page['metadata']
// Check if a page exists
if ($api->pageExists('contact')) {
// ...
}
```
#### Navigation
```php
// Get menu structure
$menu = $api->getMenu();
// Nested array with 'title', 'path', 'url', 'children'
```
#### Configuration
```php
// Get config value (dot notation)
$title = $api->getConfig('site_title');
$lang = $api->getConfig('language.default');
$seoDesc = $api->getConfig('seo.description', 'Default description');
```
#### Current page
```php
// Current page title
$pageTitle = $api->getCurrentPageTitle();
// Current page path
$pagePath = $api->getCurrentPagePath();
// Check if this is the homepage
if ($api->isHomepage()) {
echo 'Welcome!';
}
```
#### URLs and language
```php
// Build URL for a page
$url = $api->buildUrl('about', 'en');
// Current language
$lang = $api->getCurrentLanguage();
// Available languages
$languages = $api->getAvailableLanguages();
// Site title
$title = $api->getSiteTitle();
```
#### Translations and search
```php
// Get translation
$label = $api->t('home');
// Search results (if searching)
if ($api->isSearching()) {
$results = $api->getSearchResults();
}
```
#### Example PHP content file
```php
---
title: Page Overview
layout: content
---
<h1>All Pages</h1>
<ul>
<?php foreach ($api->getAllPages() as $path => $title): ?>
<li><a href="<?= $api->buildUrl($path) ?>"><?= htmlspecialchars($title) ?></a></li>
<?php endforeach; ?>
</ul>
```
---
## Settings
### Configuration
The site configuration is managed via the **admin panel** at `/admin/config`. The form includes:
- **General settings** - Site title and homepage (dropdown with available pages)
- **Language** - Default language and available languages
- **SEO** - Meta description and keywords
- **Author** - Name and website
- **Features** - Auto-link pages, search, breadcrumbs, show version
- **IP Exclusions** - Exclude IP addresses from statistics and security checks
The configuration is stored in `config.json`. You can also edit this file manually for advanced options like `active_theme`, `content_dir` and `templates_dir`.
The configuration is stored in `config.json`. You can also edit this file manually for advanced options.
### Example `config.json`
#### IP Exclusions
Under **Configuration** in the admin panel, the "IP Exclusions" field lets you specify IP addresses that will be:
- Excluded from visitor statistics
- Skipped during all security checks (bot detection, rate limiting, IP blocklist)
This is useful for your own IP address or internal monitoring tools.
#### Example `config.json`
```json
{
@@ -220,11 +320,25 @@ The configuration is stored in `config.json`. You can also edit this file manual
"auto_link_pages": true,
"search_enabled": true,
"breadcrumbs_enabled": true
},
"analytics": {
"enabled": true,
"excluded_ips": ["127.0.0.1", "::1"]
},
"security": {
"block_ai_bots": true,
"block_scrapers": true,
"block_empty_user_agent": true,
"rate_limit_enabled": true
}
}
```
### Theme Configuration (`themes/<name>/theme.json`)
### Themes
Themes are managed via the admin panel at `/admin/theme`. You can create, activate, adjust colors, upload background images, and delete themes.
#### Theme Configuration (`themes/<name>/theme.json`)
```json
{
@@ -242,232 +356,82 @@ The configuration is stored in `config.json`. You can also edit this file manual
}
```
Themes can be managed via the admin panel: create, activate, adjust colors, upload background image and delete.
#### How to create a new theme
## Content Structure
1. Go to `/admin/theme`
2. Enter a name and click "Create"
3. Adjust colors, heights and background
4. Activate the theme
### File Structure
### Security
```
content/
├── folder1/
│ ├── subfolder1/
│ │ ├── nl.page1.md
│ │ └── en.page1.md
│ └── page3.html
├── folder2/
│ └── page4.md
├── index.md
└── -assets/
├── image.jpg
└── document.pdf
```
Security settings are managed via `/admin/security`. Includes:
### File Naming
- Use lowercase filenames
- No spaces - use `-` or `_`
- Logical extensions - `.md`, `.php`, `.html`
- Unique names - no duplicates
- Language prefixes - `nl.file.md` and `en.file.md`
### Media Files
Media files (images, PDFs, video, audio) can be placed in any `content/` subdirectory and are served via:
- **`/-media/path/file.jpg`** - Media from any content subdirectory
- **`/-assets/file.jpg`** - Backward compatibility (old URLs)
- Uploads via the admin panel go to `content/-assets/`
## Admin Console
### Access
- **URL**: `/admin`
- **Default login**: `admin` / `admin`
### Routes
| Route | Description |
|---|---|
| `login` | Login page |
| `logout` | Logout |
| `dashboard` | Dashboard with statistics |
| `content` | Content overview (browse, upload) |
| `content-edit` | Edit content (CodeMirror editor) |
| `content-new` | Create new content |
| `content-delete` | Delete content |
| `content-move` | Move content to another directory |
| `content-dir-form` | Create or edit directory |
| `content-dir-rename` | Rename directory |
| `content-dir-create` | Create directory (POST) |
| `content-dir-delete` | Delete directory (empty only) |
| `config` | Configuration form (title, homepage, language, SEO, author, features) |
| `security` | Security settings (bot/AI blocking, rate limiting, IP block/allowlist) |
| `statistics` | Visitor statistics with world map, countries, pages and GeoIP settings |
| `update` | One-click system update via Git pull |
| `theme` | Theme management |
| `plugins` | Plugin overview |
| `plugins-new` | Create new plugin |
| `plugins-edit` | Edit plugin PHP source code |
| `plugins-config` | Edit plugin configuration |
| `plugins-toggle` | Enable/disable plugin |
| `plugins-delete` | Delete plugin |
| `media` | Media management (upload, delete) |
| `media-list` | JSON list of all media (for editor modal) |
| `users` | User management |
| `guide` | Guide / documentation |
| `logs` | Log viewer (activity + requests) |
### Editor Features
The content editor (`content-edit`, `content-new`) includes:
- **CodeMirror** syntax highlighting for Markdown/PHP/HTML
- **Toolbar** with buttons for: bold, italic, heading, link, image, list, media insert
- **Media browser modal** - Open via the "Media" button to select images/files
- **Inline filename rename** - Inline filename input with extension badge
- **Layout selector** - Choose from available layouts
- **Plugin per-page visibility** - Select which plugins to show on this page
- **Upload and "Create" buttons** are disabled until input is provided
- **"Cancel" button** (instead of "Back") for unsaved changes
### Logging & Request Log
The admin console maintains two logs:
- **Activity log** (`admin/storage/logs/admin.log`) — admin actions like creating, editing, deleting pages, enabling/disabling plugins, changing configuration.
- **Request log** (`admin/storage/logs/requests.log`) — every page view on the website, including IP, page, domain, language, user agent, and referrer.
Both logs can be viewed and downloaded via **`/admin/logs`** or the sidebar "Logs" link. The dashboard shows the last 20 entries of each log. Click "View all →" for the full list, where you can also download or clear.
### Bot & AI Blocking
#### Bot, AI & Scraper Blocking
Incoming requests are checked against known bot and AI crawler patterns via the User-Agent header. Detected bots receive a **403 Forbidden** response.
Blocked categories:
| Category | Examples |
|---|---|
| AI Crawlers | GPTBot, ChatGPT-User, Claude-Web, ClaudeBot, Google-Extended, CCBot, PerplexityBot |
| Search Engines | Googlebot, Bingbot, BingPreview, DuckDuckBot, YandexBot, Baiduspider |
| Scrapers | HTTrack, Scrapy, PhantomJS |
## Templates
#### Rate Limiting
### Template Variables
Prevents IPs from overloading the site. Returns HTTP 429 on exceedance.
#### Site Info
- `site_title` - Website title
- `author_name` - Author name
- `author_website` - Author website
- `author_git` - Git repository link
#### IP Lists
#### Page Info
- `page_title` - Page title
- `content` - Content (HTML)
- `file_info` - File information
- `is_homepage` - Boolean: is this the homepage?
- **IP Whitelist** - IPs on the whitelist are never blocked
- **IP Blocklist** - IPs on the blocklist always receive a 403 Forbidden
#### Navigation
- `menu` - Navigation menu
- `breadcrumb` - Breadcrumb navigation
- `homepage` - Homepage link
#### Dynamic robots.txt
#### Theme (from theme.json)
- `header_color` - Header background color
- `header_font_color` - Header text color
- `header_height` - Header height in pixels
- `navigation_color` - Navigation background color
- `navigation_font_color` - Navigation text color
- `nav_height` - Navigation height in pixels
- `sidebar_background` - Sidebar background color
- `sidebar_border` - Sidebar border color
- `background_image_css` - CSS for background image
- `background_image_opacity` - Overlay opacity
The system automatically generates a `robots.txt` based on your security settings, available at `/robots.txt`.
#### Language
- `current_lang` - Current language (en/nl)
- `current_lang_upper` - Current language (EN/NL)
- `t_*` - Translated strings
### Layout Options
Use YAML frontmatter to select layout:
```yaml
---
title: My Page
layout: sidebar-content
plugins: HTMLBlock
## Data
### Statistics & Analytics
The statistics dashboard is available at `/admin/statistics` and provides:
- **KPI cards** - Page views, unique visitors, human/bot ratio, blocked requests
- **World map** - Visual representation of visitors per country with color intensity
- **Countries list** - Top 25 countries with percentage
- **Most viewed pages** - Top 25 pages
- **Daily chart** - Bar chart of visitors per day
- **Referring sites** - Top 15 referrers
#### Periods and export
Filter by 7, 30, 90 days or all time. Export data as CSV or JSON.
#### GeoIP
Country detection via three sources:
- **Local (DB-IP Lite)** - Offline, privacy-friendly, auto-updated
- **MaxMind database (.mmdb)** - Custom MMDB file
- **External API** - Custom API URL and key
### Logging
The admin console maintains two logs, viewable at `/admin/logs`:
- **Activity log** (`admin/storage/logs/admin.log`) — admin actions like creating, editing, deleting pages, enabling/disabling plugins, changing configuration.
- **Request log** (`admin/storage/logs/requests.log`) — every page view on the website, including IP, page, domain, language, user agent, and referrer.
The dashboard shows the last 20 entries of each log. Click "View all →" for the full list, where you can also download or clear.
---
```
### Available Layouts
## System
- `sidebar-content` - Sidebar left, content right (default)
- `content` - Content only (full width)
- `sidebar` - Sidebar only
- `content-sidebar` - Content left, sidebar right
- `content-sidebar-reverse` - Content right, sidebar left
### Plugin System
### Meta Data
```yaml
---
title: Page Title
layout: content-sidebar
description: Page description
author: Author Name
date: 2025-11-26
plugins: HTMLBlock, MQTTTracker
---
```
## URL Structure
### Frontend Page URLs
- **Home**: `/` or `/en/`
- **Page**: `/en/folder/page`
- **Search**: `?search=query` (via search form)
- **Guide**: `/en/guide`
- **Language switch**: `/nl` or `/en`
### Media URLs
- **Media**: `/-media/path/to/file.jpg` (from any content subdirectory)
- **Assets**: `/-assets/file.jpg` (from content/-assets/, backward compatible)
### Admin URLs
- **Admin**: `/admin`
- **Dashboard**: `/admin/dashboard`
- **Edit content**: `/admin/content-edit?file=page.md`
- **New content**: `/admin/content-new?dir=folder`
- **Edit theme**: `/admin/theme?edit=themename`
## SEO Optimization
### Meta Tags
The CMS automatically adds meta tags:
```html
<meta name="generator" content="CodePress CMS">
<meta name="author" content="E. Noorlander">
<meta name="description" content="...">
<meta name="keywords" content="...">
```
### Security Headers
```http
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; ...
```
## Plugin System
### Plugin Structure
#### Plugin Structure
```
plugins/
@@ -479,13 +443,9 @@ plugins/
│ ├── MQTTTracker.php
│ ├── config.json
│ └── README.md
└── test/
├── test.php
├── config.json
└── README.md
```
### Plugin Development
#### Plugin Development
- **API access** via `CMSAPI` class - gives access to CMS configuration, templates, menu
- **Sidebar content** with `getSidebarContent()` - returns HTML for sidebar
@@ -494,7 +454,7 @@ plugins/
- **viewable** field in config.json determines if plugin is visible in sidebar
- **Per-page visibility** - via the editor plugin selector per page
### Plugin Boilerplate
#### Plugin Boilerplate
```php
<?php
@@ -533,196 +493,190 @@ class MyPlugin
}
```
### Available Plugins
- **HTMLBlock** - Custom HTML blocks in sidebar
- **MQTTTracker** - Real-time analytics and tracking via MQTT
- **test** - Example/test plugin
### Known Issue: MQTTTracker Credentials
#### Known Issue: MQTTTracker Credentials
The MQTTTracker plugin stores `broker_host`, `broker_port`, `client_id`, `username` and `password` in plain text in `plugins/MQTTTracker/config.json`. This is a known open security issue - in a production environment it is recommended to externalize these credentials to environment variables or a separate credential manager.
## Content API (for PHP content files)
### User Management
PHP content files (`.php` in the `content/` directory) have access to an `$api` variable with the following methods:
Users are managed via `/admin/users`. Features:
- Add user with username, password and role
- Delete user
- Change password for other users (admin)
- Change own password (requires current password)
### Getting pages
Passwords are stored as bcrypt hashes in `admin/config/admin.json`.
```php
// Get all pages with titles
$pages = $api->getAllPages();
// Result: ['index' => 'Home', 'about' => 'About Us', ...]
### Update
// Get a specific page's content
$page = $api->getPage('about');
// $page['title'], $page['content'], $page['path'], $page['layout'], $page['metadata']
Via `/admin/update` the system can be updated in one click via Git pull. The page shows the current version and git branch, and executes `git pull origin <branch>` on confirmation.
// Check if a page exists
if ($api->pageExists('contact')) {
// ...
}
```
### Navigation
```php
// Get menu structure
$menu = $api->getMenu();
// Nested array with 'title', 'path', 'url', 'children'
```
### Configuration
```php
// Get config value (dot notation)
$title = $api->getConfig('site_title');
$lang = $api->getConfig('language.default');
$seoDesc = $api->getConfig('seo.description', 'Default description');
```
### Current page
```php
// Current page title
$pageTitle = $api->getCurrentPageTitle();
// Current page path
$pagePath = $api->getCurrentPagePath();
// Check if this is the homepage
if ($api->isHomepage()) {
echo 'Welcome!';
}
```
### URLs and language
```php
// Build URL for a page
$url = $api->buildUrl('about', 'en');
// Current language
$lang = $api->getCurrentLanguage();
// Available languages
$languages = $api->getAvailableLanguages();
// Site title
$title = $api->getSiteTitle();
```
### Translations and search
```php
// Get translation
$label = $api->t('home');
// Search results (if searching)
if ($api->isSearching()) {
$results = $api->getSearchResults();
}
```
### Example PHP content file
```php
---
title: Page Overview
layout: content
## Guide (in Admin)
This guide is also built into the admin panel via `/admin/guide`, with support for Dutch and English.
---
## Other
### Templates
#### Template Variables
**Site Info** - `site_title`, `author_name`, `author_website`, `author_git`
**Page Info** - `page_title`, `content`, `file_info`, `is_homepage`
**Navigation** - `menu`, `breadcrumb`, `homepage`
**Theme (from theme.json)** - `header_color`, `header_font_color`, `header_height`, `navigation_color`, `navigation_font_color`, `nav_height`, `sidebar_background`, `sidebar_border`, `background_image_css`, `background_image_opacity`
**Language** - `current_lang`, `current_lang_upper`, `t_*` (translated strings)
#### Layout Options
Use YAML frontmatter to select layout:
```yaml
---
title: My Page
layout: sidebar-content
plugins: HTMLBlock
---
<h1>All Pages</h1>
<ul>
<?php foreach ($api->getAllPages() as $path => $title): ?>
<li><a href="<?= $api->buildUrl($path) ?>"><?= htmlspecialchars($title) ?></a></li>
<?php endforeach; ?>
</ul>
```
## Analytics & Tracking
#### Available Layouts
### MQTT Tracker
- `sidebar-content` - Sidebar left, content right (default)
- `content` - Content only (full width)
- `sidebar` - Sidebar only
- `content-sidebar` - Content left, sidebar right
- `content-sidebar-reverse` - Content right, sidebar left
- Real-time page tracking via MQTT broker
- Session management
- Business Intelligence data
- Privacy aware (GDPR compliant)
- MQTT integration for dashboards
- Optional: visitor tracking, page views, performance metrics, user flows
#### Meta Data
## Frequently Asked Questions
```yaml
---
title: Page Title
layout: content-sidebar
description: Page description
author: Author Name
date: 2025-11-26
plugins: HTMLBlock, MQTTTracker
---
```
### How do I set the homepage?
### URL Structure
#### Frontend Page URLs
- **Home**: `/` or `/en/`
- **Page**: `/en/folder/page`
- **Search**: `?search=query` (via search form)
#### Media URLs
- **Media**: `/-media/path/to/file.jpg` (from any content subdirectory)
- **Assets**: `/-assets/file.jpg` (from content/-assets/, backward compatible)
#### Admin URLs
- **Admin**: `/admin`
- **Dashboard**: `/admin/dashboard`
- **Content**: `/admin/content`
- **Configuration**: `/admin/config`
- **Security**: `/admin/security`
- **Statistics**: `/admin/statistics`
- **Theme**: `/admin/theme`
- **Plugins**: `/admin/plugins`
- **Users**: `/admin/users`
- **Logs**: `/admin/logs`
- **Update**: `/admin/update`
- **Guide**: `/admin/guide`
### SEO Optimization
#### Meta Tags
The CMS automatically adds meta tags:
```html
<meta name="generator" content="CodePress CMS">
<meta name="author" content="E. Noorlander">
<meta name="description" content="...">
<meta name="keywords" content="...">
```
#### Security Headers
```http
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; ...
```
### Frequently Asked Questions
#### How do I set the homepage?
1. Go to **Configuration** in the admin panel (`/admin/config`)
2. Select the desired page in the **Default/homepage** dropdown
3. Click **Save configuration**
### How does navigation work?
#### How does navigation work?
- **Directories** become dropdown menus
- **Files** become direct links
- **Sub-directories** become nested dropdowns
- Only files without a language prefix show in the menu
### How do I add new content?
#### How do I add new content?
1. Via the admin panel: `/admin/content-new`
2. Or upload files to the `content/` directory
3. Organize in logical directories
4. Use correct filenames and extensions
### How do I move a file or directory?
#### How do I move a file or directory?
1. Go to `/admin/content`
2. Click "Move" next to the item
3. Select the target directory
4. Confirm the move
### How do I create a new theme?
#### How do I exclude my own IP from statistics?
1. Go to `/admin/theme`
2. Enter a name and click "Create"
3. Adjust colors, heights and background
4. Activate the theme
1. Go to **Configuration** in the admin panel (`/admin/config`)
2. Scroll to the "IP Exclusions" field
3. Enter your IP address (one per line)
4. Click **Save configuration**
## Troubleshooting
### Troubleshooting
### Page not found (404)
#### Page not found (404)
1. Check filename and path
2. Check file extension (.md, .php, .html)
3. Check file permissions
4. Check if the file has the correct language prefix (`nl.` or `en.`)
### Navigation not updated
#### Navigation not updated
1. Reload the page
2. Check content directory structure
3. Check filenames (no spaces)
4. Files with language prefix only show in the correct language mode
### Admin panel not accessible
#### Admin panel not accessible
1. Check if the session is still valid
2. On lockout: wait 15 minutes or clear lockout data in `admin/config/admin.json`
3. Check CSRF token (reload the page)
## Security
- **CSRF protection** via tokens on all admin forms
- **Brute-force lockout** after 5 failed attempts (15 minute block)
- **Bcrypt password hashing** for user passwords
- **Path traversal prevention** via `realpath()` and prefix check
- **Direct content access** blocked (403 Forbidden)
- **Security headers** for all pages
- **PHP execution** in content directory blocked
- **File upload restrictions** on allowed extensions
## Version
Current version: **1.6.0** (codename: "Enhanced")
Release date: 2026-07-14
Current version: **1.9.1**
Release date: 2026-07-29
## Support
+385 -435
View File
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -6,12 +6,20 @@
*/
return [
'version' => '1.9.1',
'version' => '1.9.2',
'release_date' => '2026-07-29',
'codename' => 'Atlas',
'status' => 'stable',
'changelog' => [
'1.9.2' => [
'date' => '2026-07-29',
'changes' => [
'Admin sidebar restructured into logical groups: Algemeen, Content, Instellingen, Gegevens, Systeem, Help, Links',
'IP uitsluitingen toegevoegd aan configuratie: IP's niet meetellen in statistieken en overslaan bij beveiligingscontroles',
'Guide (NL/EN) volledig herschreven metzelfde logische indeling als sidebar',
]
],
'1.9.1' => [
'date' => '2026-07-29',
'changes' => [