- Bug: dashboard toonde 0 content (AdminPluginAPI::getContentDir() gaf relatief pad terug zonder normalisatie) - Dynamische pad-resolutie: PluginAPIInterface uitgebreid met getProjectRoot/getContentDir/getPluginsDir/getVersionInfo; CMSAPI en AdminPluginAPI implementeren deze universeel - public/index.php media-serving gebruikt $config['content_dir'] i.p.v. hardcoded /content - Navigation en Logs plugins halen paden via de API i.p.v. hardcoded dirname(__DIR__) - WordPress-stijl docblocks toegevoegd voor alle classes, methods, properties en functies (~450 docblocks, @since 2.6.5) - Security: hardcoded plaintext-wachtwoord 'admin' verwijderd uit AdminAuth.php; bij eerste installatie wordt een cryptografisch veilig wachtwoord gegenereerd (random_bytes, 16 tekens) en eenmalig op het inlogscherm getoond - Security: git-geschiedenis schoongemaakt (admin.json, admin.json.example, admin-console/config/admin.json verwijderd uit alle commits; filter-branch over alle branches + tags, gc --prune --aggressive) - README.md, README.en.md, AGENTS.md bijgewerkt - Test-scripts bijgewerkt naar clean-URL structuur + actuele ARIA-waarden - Versie verhoogd naar 2.6.5 - Tests: pentest 29/29, WCAG 25/25, functioneel 16/16, enhanced 25/25
12 KiB
CodePress CMS
Een lichtgewicht, file-based content management systeem gebouwd met PHP (≥8.0).
Versie: 2.6.5 | Licentie: AGPL v3 / Commercial
✨ Features
- 📝 Multi-format Content - Markdown, PHP en HTML bestanden
- 🧭 Dynamic Navigation - Automatische menu generatie
- 🌍 Multi-language - NL/EN/DE ondersteuning
- 🔍 Search - Volledige tekst zoekfunctie
- 📱 Responsive - Bootstrap 5 thema's
- 🔒 Security - 100/100 pentest score
- 🛡️ Admin Console - CodeMirror editor, media beheer, thema's, plugins
- 👥 Gebruikersrollen - Admin, Content Beheerder, BI Beheerder, Site Admin
- 📊 Analytics - Bezoekersstatistieken met GeoIP
- 🤖 BotGuard - Bot/AI bescherming
- 📈 Logging - Uitgebreid logging systeem
- 🔌 Plugin Systeem - Sidebar plugins met eigen CSS/SCSS, Twig templates
🚀 Quick Start
# Installeer dependencies
composer install
# Start server met router voor schone URLs (alleen lokaal)
php -S localhost:8080 cms/router.php
Website: http://localhost:8080
Admin: http://localhost:8080/admin (login: admin / admin)
📦 Installatie
Vereisten
- PHP ≥ 8.0 met extensies:
json,mbstring - Composer (PHP dependency manager)
- Webserver: Apache 2.4+ met
mod_rewriteof Nginx met PHP-FPM - Optioneel:
opcache(aanbevolen voor performance),git(voor content versioning),zipextensie (voor ZIP backup/restore)
Stap 1 — Code en dependencies
git clone <repository-url> codepress
cd codepress
composer install
Stap 2 — Configuratie
cp config.json.example config.json
Pas config.json aan met je site titel, taal en plugins. Bij de eerste keer dat je /admin opent wordt admin/config/admin.json automatisch aangemaakt met een willekeurig wachtwoord dat op het inlogscherm wordt getoond. Sla dit wachtwoord veilig op en wijzig het direct na login.
Stap 3a — Apache 2.4+
De webroot is de public/ map. Voorbeeld vhost (/etc/apache2/sites-available/codepress.conf):
<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>
Benodigde Apache modules:
sudo a2enmod rewrite headers
sudo systemctl restart apache2
mod_rewrite— voor clean URLs (/nl/pagina) en asset-servingmod_headers— voor security headersAllowOverride All— zodat.htaccessinpublic/wordt toegepast
Stap 3b — Nginx
Voorbeeld server block (/etc/nginx/sites-available/codepress):
server {
listen 80;
server_name example.com;
root /var/www/codepress/public;
index index.php;
# Clean URLs: taal-prefixed pagina's
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 buiten 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;
}
# Beveiliging: blokkeer toegang tot gevoelige mappen
location ~ ^/(content|cms|admin/src|admin/config|admin/storage|var|vendor)/ {
deny all;
return 403;
}
location ~ /\.(git|htaccess) {
deny all;
}
}
Let op: Nginx gebruikt geen .htaccess. De security headers moeten in de Nginx config worden gezet:
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';";
Stap 4 — Mappen rechten
Zorg dat de webserver schrijfrechten heeft op de runtime mappen:
chown -R www-data:www-data var/ admin/storage/ content/
chmod -R 755 .
Stap 5 — Test
Open de website in je browser. Bij een lege content-map zie je een welkomstpagina. De admin console is bereikbaar via /admin (login admin/admin).
📚 Handleidingen
Zie guide/ voor uitgebreide documentatie per rol:
| Rol | Handleiding |
|---|---|
| 📝 Redacteur | Content Beheerder |
| ⚙️ Administrator | Admin Beheerder |
| 🎨 Theme bouwer | Theme Developer |
| 💻 Developer | CodePress Developer |
Elke handleiding heeft sub-onderdelen in aparte mappen met een zijbalknavigatie.
👥 Gebruikersrollen
| Rol | Permissies |
|---|---|
| Admin | Volledige toegang (alles) |
| Content Beheerder | Content beheer, handleiding |
| BI Beheerder | Statistieken, logs, handleiding |
| Site Admin | Thema, plugins, statistieken, logs, update, handleiding |
📁 Project Structuur
codepress/
├── cms/ # Core CMS engine
│ ├── core/class/ # CMS classes (CodePressCMS, ThemeManager, etc.)
│ ├── core/plugin/ # Plugin systeem (PluginManager, CMSAPI)
│ └── router.php # PHP dev server router (schone URLs)
├── language/ # Taalbestanden (nl/, en/, de/ — elk met site.php + admin.php)
├── admin/ # Admin console
│ ├── config/ # Admin configuratie (admin.json)
│ ├── src/AdminAuth.php # Authenticatie, rollen, permissies
│ ├── static/ # Statische bestanden (404.html)
│ ├── storage/ # Logs, cache, geoip
│ └── theme/default/ # Admin thema
│ ├── assets/ # CSS, JS, fonts, codemirror
│ ├── views/ # Twig templates (layouts, pages)
│ └── theme.json # Admin thema configuratie
├── themes/ # Website thema's
│ ├── default/ # Standaard thema
│ │ ├── theme.json # Layout mapping, kleuren
│ │ ├── base.twig # Hoofd layout
│ │ ├── *.twig # Layout templates
│ │ ├── partials/ # Header, navigation, footer
│ │ └── assets/ # SCSS, CSS, JS, img
├── plugins/ # Plugins
│ ├── Dashboard/ # Systeem plugin (admin taal)
│ ├── HTMLBlock/ # Content plugin (content taal)
│ ├── Navigation/ # Essentiële navigatie plugin (beschermd)
│ └── Statistics/ # Systeem plugin (admin taal)
│ ├── Statistics.php # Plugin code
│ ├── plugin.json # Plugin metadata + instellingen
│ ├── README.md # Plugin documentatie
│ ├── assets/ # Plugin CSS/JS/SCSS
│ └── language/ # Plugin vertalingen (nl/, en/)
├── content/ # Website content (.md, .php, .html)
├── public/ # Web root
│ ├── index.php # Website entry point
│ └── admin.php # Admin entry point + routing
├── guide/ # Handleidingen (nl/en)
│ ├── nl/ # Nederlandse handleidingen
│ └── en/ # Engelse handleidingen
├── cli/test/ # Test suites
├── var/ # Cache (twig)
├── config.json # Site configuratie
├── composer.json # PHP dependencies
└── version.php # Versie informatie
⚙️ Configuratie
config.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 met extensies: json, mbstring
- Composer packages:
- twig/twig (templating)
- scssphp/scssphp (SCSS compilatie)
- league/commonmark (Markdown met HeadingPermalinks)
- maxmind-db/reader (GeoIP)
🔐 Security
- ✅ XSS preventie (htmlspecialchars)
- ✅ CSRF tokens (admin formulieren)
- ✅ Path traversal preventie (realpath checks)
- ✅ Secure cookies (HttpOnly, SameSite)
- ✅ Security headers (X-Frame-Options, CSP)
- ✅ Bot/AI bescherming (BotGuard)
- ✅ Rate limiting per IP
- ✅ Role-based access control (RBAC)
🔌 Plugins
Plugin structuur
Elke plugin heeft een uniforme structuur:
plugins/MijnPlugin/
├── MijnPlugin.php # Plugin code (naam = pluginnaam)
├── plugin.json # Plugin metadata + instellingen
├── README.md # Plugin documentatie
├── assets/scss/ # Plugin SCSS bron
├── assets/css/ # Plugin CSS (na compilatie)
└── language/ # Plugin vertalingen (i18n)
├── nl/admin.php # NL admin labels (systeem plugins)
└── en/admin.php # EN admin labels
- Systeem plugins volgen de admin-taal (
language/<lang>/admin.php) - Content plugins volgen de content-taal (
language/<lang>/site.php) - Fallback chain: geselecteerde taal → plugin
default_language→ CMS site default
Zie guide/nl/codepress-developer/plugin-development.md voor uitgebreide documentatie.
Plugin editor
De admin plugin-editor (/admin/plugins-edit) biedt een volledige bestandsbeheer-omgeving:
- Geneste bestandsbrowser zijbalk (alle bestanden in de plugin-map)
- Nieuw bestand aanmaken, uploaden naar assets/, verwijderen en verplaatsen
- CodeMirror editor voor .php, .json, .md, .html, .css, .scss, .js bestanden
Essentiële plugins
De Navigation plugin is een essentiële plugin en kan niet worden gedeactiveerd, bewerkt of verwijderd. Deze plugin genereert automatisch de zijbalknavigatie voor handleidingen en content.
Plugin CSS
Plugin CSS wordt automatisch geladen na thema CSS, zodat thema's plugin styling kunnen overschrijven.
📝 Content Voorbeelden
Markdown met frontmatter
---
layout: full_content
plugins: HTMLBlock, Navigation
---
# Pagina titel
Content in Markdown formaat...
PHP content
<?php
/** @var ContentAPI $api */
$pages = $api->getAllPages();
echo "<h1>Mijn Pagina</h1>";
echo "<p>Aantal pagina's: " . count($pages) . "</p>";
🧪 Testen
# Penetration tests
cli/test/pentest/security-test.sh
# Accessibility tests (WCAG 2.1 AA)
cli/test/accessibility.sh
# Functionele tests
cli/test/functional/*.sh
📞 Ondersteuning
- Documentatie: guide/
- Issues: Git repository
- Contact: commercial@noorlander.info
📄 Licentie
Dual-licensed:
- AGPL v3 - Voor open-source projecten
- Commercial - Voor propriëtair gebruik
Zie LICENSE voor details.
CodePress CMS - Gebouwd door E.Noorlander / CodePress Development Team