- Content bestanden met dezelfde naam maar ander type (md/php/html) worden correct geserveerd: URL met extensie opent dat bestand, URL zonder extensie valt terug op md > php > html (resolveContentByType helper) - Admin content editor accepteert bestanden met dezelfde naam (ander type); preview-knop linkt per extensie - Frontend navigatie/directory listing/search tonen elk bestandstype apart - getAllPages() array structuur gewijzigd naar list van ['path','title','type'] met type 'md'/'php'/'html'/'folder' - Verberg-prefix logica: _ is geen verberg-prefix meer, alleen . (en -); admin toont wél alle . bestanden/mappen - ContentAPI getPage()/pageExists() respecteren expliciete extensie - Handleiding content-api.md (NL+EN) herschreven - File-tree unificatie: _file-tree.twig + _editor-styles.twig includes - Versie verhoogd naar 2.6.3
355 lines
10 KiB
Markdown
355 lines
10 KiB
Markdown
# CodePress CMS
|
|
|
|
**[🇳🇱 Dutch](README.md) | [🇬🇧 English](#)**
|
|
|
|
A lightweight, file-based content management system built with PHP (≥8.0).
|
|
|
|
**Version:** 2.6.3 | **License:** AGPL v3 / Commercial
|
|
|
|
## ✨ Features
|
|
|
|
- 📝 **Multi-format Content** - Markdown, PHP and HTML files
|
|
- 🧭 **Dynamic Navigation** - Automatic menu generation
|
|
- 🌍 **Multi-language** - NL/EN/DE support
|
|
- 🔍 **Search** - Full-text search
|
|
- 📱 **Responsive** - Bootstrap 5 themes
|
|
- 🔒 **Security** - 100/100 pentest score
|
|
- 🛡️ **Admin Console** - CodeMirror editor, media management, themes, plugins
|
|
- 👥 **User Roles** - Admin, Content Manager, BI Manager, Site Admin
|
|
- 📊 **Analytics** - Visitor statistics with GeoIP
|
|
- 🤖 **BotGuard** - Bot/AI protection
|
|
- 📈 **Logging** - Comprehensive logging system
|
|
- 🔌 **Plugin System** - Sidebar plugins with own CSS/SCSS, Twig templates
|
|
|
|
## 🚀 Quick Start
|
|
|
|
```bash
|
|
# Install dependencies
|
|
composer install
|
|
|
|
# Start server with router for clean URLs (local only)
|
|
php -S localhost:8080 cms/router.php
|
|
```
|
|
|
|
**Website:** `http://localhost:8080`
|
|
**Admin:** `http://localhost:8080/admin` (login: `admin` / `admin`)
|
|
|
|
## 📦 Installation
|
|
|
|
### Requirements
|
|
|
|
- **PHP** ≥ 8.0 with extensions: `json`, `mbstring`
|
|
- **Composer** (PHP dependency manager)
|
|
- Web server: **Apache 2.4+** with `mod_rewrite` or **Nginx** with PHP-FPM
|
|
- Optional: `opcache` (recommended for performance), `git` (for content versioning), `zip` extension (for ZIP backup/restore)
|
|
|
|
### Step 1 — Code and dependencies
|
|
|
|
```bash
|
|
git clone <repository-url> codepress
|
|
cd codepress
|
|
composer install
|
|
```
|
|
|
|
### Step 2 — Configuration
|
|
|
|
```bash
|
|
cp config.json.example config.json
|
|
cp admin/config/admin.json.example admin/config/admin.json
|
|
```
|
|
|
|
Edit `config.json` with your site title, language and plugins. Change the admin password in `admin/config/admin.json` (default `admin`/`admin`).
|
|
|
|
### Step 3a — Apache 2.4+
|
|
|
|
The webroot is the `public/` directory. Example vhost (`/etc/apache2/sites-available/codepress.conf`):
|
|
|
|
```apache
|
|
<VirtualHost *:80>
|
|
ServerName example.com
|
|
DocumentRoot /var/www/codepress/public
|
|
|
|
<Directory /var/www/codepress/public>
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
|
|
ErrorLog ${APACHE_LOG_DIR}/codepress_error.log
|
|
CustomLog ${APACHE_LOG_DIR}/codepress_access.log combined
|
|
</VirtualHost>
|
|
```
|
|
|
|
Required Apache modules:
|
|
|
|
```bash
|
|
sudo a2enmod rewrite headers
|
|
sudo systemctl restart apache2
|
|
```
|
|
|
|
- `mod_rewrite` — for clean URLs (`/nl/page`) and asset-serving
|
|
- `mod_headers` — for security headers
|
|
- `AllowOverride All` — so the `.htaccess` in `public/` is applied
|
|
|
|
### Step 3b — Nginx
|
|
|
|
Example server block (`/etc/nginx/sites-available/codepress`):
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name example.com;
|
|
root /var/www/codepress/public;
|
|
index index.php;
|
|
|
|
# Clean URLs: language-prefixed pages
|
|
location ~ ^/(nl|en|de)(/(.+))?$ {
|
|
try_files $uri /index.php?lang=$1&page=$2;
|
|
}
|
|
|
|
# Admin routes
|
|
location /admin {
|
|
try_files $uri /admin.php?$args;
|
|
}
|
|
|
|
# Asset-serving via asset.php (themes/plugins/admin outside webroot)
|
|
location ~ ^/(themes|plugins)/([^/]+)/assets/(.+)$ {
|
|
try_files $uri /asset.php;
|
|
}
|
|
location ~ ^/admin/assets/(.+)$ {
|
|
try_files $uri /asset.php;
|
|
}
|
|
|
|
# PHP via FPM
|
|
location ~ \.php$ {
|
|
fastcgi_pass unix:/run/php/php8.0-fpm.sock;
|
|
fastcgi_index index.php;
|
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
include fastcgi_params;
|
|
}
|
|
|
|
# Security: block access to sensitive directories
|
|
location ~ ^/(content|cms|admin/src|admin/config|admin/storage|var|vendor)/ {
|
|
deny all;
|
|
return 403;
|
|
}
|
|
|
|
location ~ /\.(git|htaccess) {
|
|
deny all;
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** Nginx does not use `.htaccess`. Security headers must be set in the Nginx config:
|
|
|
|
```nginx
|
|
add_header X-Content-Type-Options nosniff;
|
|
add_header X-Frame-Options SAMEORIGIN;
|
|
add_header X-XSS-Protection "1; mode=block";
|
|
add_header Referrer-Policy strict-origin-when-cross-origin;
|
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';";
|
|
```
|
|
|
|
### Step 4 — Directory permissions
|
|
|
|
Make sure the web server has write access to the runtime directories:
|
|
|
|
```bash
|
|
chown -R www-data:www-data var/ admin/storage/ content/
|
|
chmod -R 755 .
|
|
```
|
|
|
|
### Step 5 — Test
|
|
|
|
Open the website in your browser. With an empty content directory you'll see a welcome page. The admin console is available at `/admin` (login `admin`/`admin`).
|
|
|
|
## 📚 Documentation
|
|
|
|
See **[guide/](guide/)** for extensive documentation per role:
|
|
|
|
| Role | Guide |
|
|
|------|-------|
|
|
| 📝 Content Editor | [Content Manager](guide/en/content-beheerder.md) |
|
|
| ⚙️ Administrator | [Admin Manager](guide/en/admin-beheerder.md) |
|
|
| 🎨 Theme Developer | [Theme Developer](guide/en/theme-developer.md) |
|
|
| 💻 Developer | [CodePress Developer](guide/en/codepress-developer.md) |
|
|
|
|
Each guide has sub-topics in separate folders with sidebar navigation.
|
|
|
|
## 👥 User Roles
|
|
|
|
| Role | Permissions |
|
|
|------|------------|
|
|
| **Admin** | Full access (everything) |
|
|
| **Content Manager** | Content management, guide |
|
|
| **BI Manager** | Statistics, logs, guide |
|
|
| **Site Admin** | Theme, plugins, statistics, logs, update, guide |
|
|
|
|
## 📁 Project Structure
|
|
|
|
```
|
|
codepress/
|
|
├── cms/ # Core CMS engine
|
|
│ ├── core/class/ # CMS classes (CodePressCMS, ThemeManager, etc.)
|
|
│ ├── core/plugin/ # Plugin system (PluginManager, CMSAPI)
|
|
│ └── router.php # PHP dev server router (clean URLs)
|
|
├── language/ # Translation files (nl/, en/, de/ — each with site.php + admin.php)
|
|
├── admin/ # Admin console
|
|
│ ├── config/ # Admin configuration (admin.json)
|
|
│ ├── src/AdminAuth.php # Authentication, roles, permissions
|
|
│ ├── static/ # Static files (404.html)
|
|
│ ├── storage/ # Logs, cache, geoip
|
|
│ └── theme/default/ # Admin theme
|
|
│ ├── assets/ # CSS, JS, fonts, codemirror
|
|
│ ├── views/ # Twig templates (layouts, pages)
|
|
│ └── theme.json # Admin theme configuration
|
|
├── themes/ # Website themes
|
|
│ ├── default/ # Default theme
|
|
│ │ ├── theme.json # Layout mapping, colors
|
|
│ │ ├── base.twig # Main layout
|
|
│ │ ├── *.twig # Layout templates
|
|
│ │ ├── partials/ # Header, navigation, footer
|
|
│ │ └── assets/ # SCSS, CSS, JS, img
|
|
├── plugins/ # Plugins
|
|
│ ├── HTMLBlock/ # Example sidebar plugin
|
|
│ └── Navigation/ # Essential navigation plugin (protected)
|
|
│ ├── Navigation.php # Plugin code
|
|
│ ├── plugin.json # Plugin metadata
|
|
│ ├── assets/scss/ # Plugin SCSS source
|
|
│ └── assets/css/ # Plugin CSS
|
|
├── content/ # Website content (.md, .php, .html)
|
|
├── public/ # Web root
|
|
│ ├── index.php # Website entry point
|
|
│ └── admin.php # Admin entry point + routing
|
|
├── guide/ # Documentation (nl/en)
|
|
│ ├── nl/ # Dutch guides
|
|
│ └── en/ # English guides
|
|
├── cli/test/ # Test suites
|
|
├── var/ # Cache (twig)
|
|
├── config.json # Site configuration
|
|
├── composer.json # PHP dependencies
|
|
└── version.php # Version information
|
|
```
|
|
|
|
## ⚙️ Configuration
|
|
|
|
### config.json
|
|
|
|
```json
|
|
{
|
|
"site_title": "CodePress",
|
|
"active_theme": "default",
|
|
"default_page": "auto",
|
|
"language": {
|
|
"default": "nl",
|
|
"available": ["nl", "en"]
|
|
},
|
|
"enabled_plugins": ["HTMLBlock", "Navigation"],
|
|
"features": {
|
|
"search_enabled": true,
|
|
"breadcrumbs_enabled": true
|
|
},
|
|
"security": {
|
|
"block_ai_bots": true,
|
|
"rate_limit_enabled": true
|
|
},
|
|
"analytics": { "enabled": true },
|
|
"logging": { "enabled": true }
|
|
}
|
|
```
|
|
|
|
## 🔧 Dependencies
|
|
|
|
- **PHP ≥8.0** with extensions: json, mbstring
|
|
- **Composer** packages:
|
|
- twig/twig (templating)
|
|
- scssphp/scssphp (SCSS compilation)
|
|
- league/commonmark (Markdown with HeadingPermalinks)
|
|
- maxmind-db/reader (GeoIP)
|
|
|
|
## 🔐 Security
|
|
|
|
- ✅ XSS prevention (htmlspecialchars)
|
|
- ✅ CSRF tokens (admin forms)
|
|
- ✅ Path traversal prevention (realpath checks)
|
|
- ✅ Secure cookies (HttpOnly, SameSite)
|
|
- ✅ Security headers (X-Frame-Options, CSP)
|
|
- ✅ Bot/AI protection (BotGuard)
|
|
- ✅ Rate limiting per IP
|
|
- ✅ Role-based access control (RBAC)
|
|
|
|
## 🔌 Plugins
|
|
|
|
### Plugin structure
|
|
|
|
```
|
|
plugins/MyPlugin/
|
|
├── MyPlugin.php # Plugin code (name = plugin name)
|
|
├── plugin.json # Plugin metadata
|
|
├── assets/scss/ # Plugin SCSS source
|
|
└── assets/css/ # Plugin CSS (after compilation)
|
|
```
|
|
|
|
### Essential plugins
|
|
|
|
The **Navigation** plugin is an essential plugin and cannot be disabled, edited, or deleted. This plugin automatically generates sidebar navigation for guides and content.
|
|
|
|
### Plugin CSS
|
|
|
|
Plugin CSS is automatically loaded after theme CSS, so themes can override plugin styling.
|
|
|
|
## 📝 Content Examples
|
|
|
|
### Markdown with frontmatter
|
|
|
|
```markdown
|
|
---
|
|
layout: full_content
|
|
plugins: HTMLBlock, Navigation
|
|
---
|
|
|
|
# Page title
|
|
|
|
Content in Markdown format...
|
|
```
|
|
|
|
### PHP content
|
|
|
|
```php
|
|
<?php
|
|
/** @var ContentAPI $api */
|
|
$pages = $api->getAllPages();
|
|
echo "<h1>My Page</h1>";
|
|
echo "<p>Number of pages: " . count($pages) . "</p>";
|
|
```
|
|
|
|
## 🧪 Testing
|
|
|
|
```bash
|
|
# Penetration tests
|
|
cli/test/pentest/security-test.sh
|
|
|
|
# Accessibility tests (WCAG 2.1 AA)
|
|
cli/test/accessibility.sh
|
|
|
|
# Functional tests
|
|
cli/test/functional/*.sh
|
|
```
|
|
|
|
## 📞 Support
|
|
|
|
- **Documentation:** [guide/](guide/)
|
|
- **Issues:** Git repository
|
|
- **Contact:** commercial@noorlander.info
|
|
|
|
## 📄 License
|
|
|
|
**Dual-licensed:**
|
|
|
|
- **AGPL v3** - For open-source projects
|
|
- **Commercial** - For proprietary use
|
|
|
|
See [LICENSE](LICENSE) for details.
|
|
|
|
---
|
|
|
|
**CodePress CMS** - Built by E.Noorlander / CodePress Development Team |