E.Noorlander f7e8837a1c v2.6.6 (Lyra): Essential plugins altijd laden (forceer in core)
Bug: beschermde/essentiële plugins (Dashboard, Navigation) konden niet
meer geactiveerd worden als ze uit enabled_plugins raakten. Core forceert
nu laden van essential plugins (plugin.json essential: true); admin-UI
toont ze altijd als Actief; toggle-handler staat aanzetten wél toe,
uitzetten blijft geblokkeerd; isProtectedPlugin() dekt nu ook essential.
2026-08-27 19:43:42 +00:00

CodePress CMS

🇳🇱 Dutch | 🇬🇧 English

A lightweight, file-based content management system built with PHP (≥8.0).

Version: 2.6.5 | 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

# 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

git clone <repository-url> codepress
cd codepress
composer install

Step 2 — Configuration

cp config.json.example config.json

Edit config.json with your site title, language and plugins. On the first visit to /admin, admin/config/admin.json is created automatically with a random password that is shown on the login screen. Save this password safely and change it immediately after login.

Step 3a — Apache 2.4+

The webroot is the public/ directory. Example 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>

Required Apache modules:

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):

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:

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:

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/ for extensive documentation per role:

Role Guide
📝 Content Editor Content Manager
⚙️ Administrator Admin Manager
🎨 Theme Developer Theme Developer
💻 Developer CodePress Developer

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

{
    "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

---
layout: full_content
plugins: HTMLBlock, Navigation
---

# Page title

Content in Markdown format...

PHP content

<?php
/** @var ContentAPI $api */
$pages = $api->getAllPages();
echo "<h1>My Page</h1>";
echo "<p>Number of pages: " . count($pages) . "</p>";

🧪 Testing

# 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

📄 License

Dual-licensed:

  • AGPL v3 - For open-source projects
  • Commercial - For proprietary use

See LICENSE for details.


CodePress CMS - Built by E.Noorlander / CodePress Development Team

S
Description
No description provided
Readme
10 MiB
Languages
PHP 67.6%
Twig 21.3%
JavaScript 5.9%
Shell 3.5%
SCSS 1.3%
Other 0.4%