v1.9.2: Admin sidebar groepen, IP-uitsluitingen, guides herschreven
This commit is contained in:
+29
-16
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+9
-1
@@ -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' => [
|
||||
|
||||
Reference in New Issue
Block a user