Files
CodePress/AGENTS.md
T

16 KiB

Agent Instructions for CodePress CMS

AI Model

  • Huidig model: GLM-5.2 max (Ollama cloud)
  • Sessie gestart: 16 feb 2026

Build & Run

  • Run Server: php -S localhost:8080 cms/router.php (router nodig voor clean URLs)
  • Lint PHP: find . -name "*.php" -not -path "./vendor/*" -not -path "./var/*" -exec php -l {} \;
  • Dependencies: Composer vereist voor CommonMark, Twig en scssphp. Geen NPM.
  • Admin Console: Toegankelijk op /admin (standaard login: admin / admin)

Project Structuur

codepress/
├── cms/                                # Core CMS engine
│   ├── core/
│   │   ├── class/
│   │   │   ├── CodePressCMS.php         # Hoofd CMS class (routing, rendering, breadcrumb, guide)
│   │   │   ├── ThemeManager.php         # Thema-resolver + Twig render + SCSS compile
│   │   │   ├── ContentAPI.php           # Read-only API voor PHP content bestanden
│   │   │   ├── ContentSecurityPolicy.php # CSP header management
│   │   │   ├── Analytics.php            # Bezoekersstatistieken
│   │   │   ├── BotGuard.php             # Bot/AI detectie
│   │   │   ├── Cache.php               # Cache systeem
│   │   │   ├── GeoIP.php                # GeoIP lookup (land, vlag)
│   │   │   ├── Logger.php               # Basis logging
│   │   │   ├── LogManager.php           # Dynamisch logging systeem (SQLite/syslog)
│   │   │   ├── RateLimiter.php          # Rate limiting per IP
│   │   │   ├── RequestLogger.php        # Request logging + visitor info
│   │   │   ├── SearchEngine.php         # Volledige tekst zoekfunctie
│   │   │   ├── SimpleTemplate.php       # Legacy Mustache-style engine (niet meer gebruikt)
│   │   │   └── AccessibilityManager.php # Accessibility features
│   │   ├── plugin/
│   │   │   ├── PluginManager.php         # Plugin loader (laadt, hooks, filters, sidebar)
│   │   │   └── CMSAPI.php                # API voor plugins (getPage, getConfig, etc.)
│   │   ├── config.php                   # Config loader (leest config.json)
│   │   └── index.php                    # Bootstrap (autoloader, requires)
│   ├── lang/                            # Taalbestanden (nl.php, en.php)
│   └── router.php                       # PHP dev server router (serveert themes/, admin/assets/, plugins/assets/)
├── themes/                              # Dynamische thema's (volledig zelfstandig)
│   ├── default/                         # Standaard thema
│   │   ├── theme.json                   # { title, config.default_template, template: layout→.twig mapping }
│   │   ├── base.twig                    # Hoofd layout (head, header, nav, breadcrumb, footer)
│   │   ├── full_content.twig            # Layout: volledige breedte
│   │   ├── left_sidebar.twig            # Layout: sidebar links
│   │   ├── right_sidebar.twig           # Layout: sidebar rechts
│   │   ├── custom1.twig                 # Layout: custom
│   │   ├── guide.twig                   # Layout: handleiding met sidebar (Navigation plugin)
│   │   ├── partials/                    # header.twig, navigation.twig, footer.twig
│   │   └── assets/
│   │       ├── scss/theme.scss           # SCSS bron (runtime gecompileerd)
│   │       ├── css/theme.css             # Gecompileerde CSS
│   │       ├── css/style.css             # Extra CSS (search fix, etc.)
│   │       ├── css/bootstrap.min.css     # Bootstrap 5
│   │       ├── css/bootstrap-icons.css   # Bootstrap Icons
│   │       ├── css/mobile.css            # Mobile styles
│   │       ├── js/app.js                 # Thema JavaScript
│   │       ├── js/bootstrap.bundle.min.js
│   │       ├── fonts/                     # bootstrap-icons.woff, woff2
│   │       └── img/                      # favicon, icon, world-map
│   └── demo/                            # Demo thema (zelfde structuur, andere look)
├── admin/                               # Admin paneel
│   ├── config/
│   │   ├── app.php                      # Admin app configuratie (paths, config_json, etc.)
│   │   └── admin.json                   # Gebruikers & security (file-based, .gitignore'd)
│   ├── src/
│   │   └── AdminAuth.php                # Authenticatie (sessies, bcrypt, CSRF, lockout, RBAC)
│   ├── theme/default/                   # Admin thema
│   │   ├── theme.json                   # Admin thema configuratie
│   │   ├── assets/
│   │   │   ├── css/
│   │   │   │   ├── style.css             # Admin styles (code blocks, guide nav)
│   │   │   │   ├── editor.css            # CodeMirror editor styles
│   │   │   │   ├── bootstrap.min.css
│   │   │   │   └── bootstrap-icons.css
│   │   │   ├── js/
│   │   │   │   ├── app.js
│   │   │   │   ├── editor-toolbar.js     # CodeMirror toolbar + shortcuts
│   │   │   │   ├── keyboard-navigation.js
│   │   │   │   └── bootstrap.bundle.min.js
│   │   │   ├── codemirror/               # CodeMirror editor (modes, addons)
│   │   │   ├── fonts/                    # bootstrap-icons.woff, woff2
│   │   │   └── img/                      # favicon, world-map
│   │   └── views/
│   │       ├── login.twig                # Login pagina
│   │       ├── layouts/
│   │       │   └── admin.twig            # Admin layout met sidebar (role-based zichtbaarheid)
│   │       └── pages/
│   │           ├── dashboard.twig        # Dashboard (role-based inhoud)
│   │           ├── content.twig          # Content beheer
│   │           ├── content-edit.twig     # Content bewerken (layout select, plugins, CodeMirror)
│   │           ├── content-new.twig      # Nieuwe content
│   │           ├── content-move-form.twig # Content verplaatsen
│   │           ├── content-dir-form.twig  # Map hernoemen
│   │           ├── config.twig           # Site configuratie
│   │           ├── security.twig         # Beveiliging instellingen
│   │           ├── theme.twig            # Thema beheer
│   │           ├── theme-new.twig        # Nieuw thema
│   │           ├── plugins.twig          # Plugin beheer (beschermd: essentiële plugins)
│   │           ├── plugins-edit.twig     # Plugin bewerken (CodeMirror)
│   │           ├── plugins-new.twig      # Nieuwe plugin
│   │           ├── plugin-config.twig    # Plugin configuratie
│   │           ├── users.twig            # Gebruikersbeheer (rollen, wachtwoord)
│   │           ├── statistics.twig       # Statistieken
│   │           ├── logs.twig             # Log viewer
│   │           ├── media.twig            # Media beheer
│   │           ├── guide.twig            # Handleiding (met Navigation sidebar)
│   │           ├── update.twig           # Update pagina
│   │           └── error.twig            # 403/404 fout pagina
│   └── storage/                         # Logs, cache, geoip
├── plugins/                             # CMS plugins
│   ├── Navigation/                       # Essentiële navigatie plugin (beschermd)
│   │   ├── Navigation.php               # Plugin code (guide + content navigatie)
│   │   ├── plugin.json                   # Plugin metadata
│   │   ├── assets/
│   │   │   ├── scss/navigation.scss      # SCSS bron
│   │   │   └── css/navigation.css        # Gecompileerde CSS
│   │   └── views/                        # Plugin Twig templates (toekomstig)
│   └── HTMLBlock/                        # Voorbeeld sidebar plugin
│       └── HTMLBlock.php
├── content/                             # Website content (.md, .php, .html)
├── public/                              # Web root
│   ├── index.php                        # Website entry point
│   ├── admin.php                        # Admin entry point + routing
│   ├── favicon.ico
│   └── robots.txt
├── guide/                               # Handleidingen (nl/en, gesplitst in mappen)
│   ├── nl/                              # Nederlandse handleidingen
│   │   ├── index.md                     # Index (verwijst naar onderwerpen)
│   │   ├── admin-beheerder.md           # Admin handleiding (inleiding)
│   │   ├── admin-beheerder/             # Sub-onderdelen
│   │   ├── content-beheerder.md
│   │   ├── content-beheerder/
│   │   ├── codepress-developer.md
│   │   ├── codepress-developer/
│   │   ├── theme-developer.md
│   │   └── theme-developer/
│   ├── en/                              # Engelse handleidingen (zelfde structuur als nl/)
│   └── README.md
├── cli/                                 # CLI scripts & tests
│   └── test/
│       ├── accessibility.sh             # WCAG 2.1 AA test suite
│       ├── enhanced-suite.sh            # Enhanced test suite
│       ├── functional/                   # Functionele testen
│       └── pentest/                      # Penetratietesten
├── var/                                 # Cache (twig) — .gitignore'd
├── config.json                          # Site configuratie — .gitignore'd
├── composer.json                        # PHP dependencies
├── version.php                          # Versie informatie (huidige: 2.5.1)
├── .gitignore                           # Negeert: var/, config.json, admin/config/admin.json, content/
└── AGENTS.md                            # Dit bestand

Code Style & Conventions

  • PHP Standards: Follow PSR-12. Use 4 spaces for indentation.
  • Naming: Classes PascalCase (e.g., CodePressCMS), methods camelCase (e.g., renderMenu), variables camelCase, config keys snake_case.
  • Architecture:
    • Core CMS logic in cms/core/class/CodePressCMS.php
    • Bootstrap/requires in cms/core/index.php
    • Configuration loaded from config.json via cms/core/config.php
    • Public website entry point: public/index.php
    • Admin entry point + routing: public/admin.php
    • Admin authentication + RBAC: admin/src/AdminAuth.php
    • Admin theme: admin/theme/default/ (views + assets)
    • Plugin assets: plugins/<Name>/assets/ (served via router /plugins/<Name>/assets/)
  • Content: Stored in content/. Supports .md (Markdown), .php (Dynamic), .html (Static).
  • Templating: Twig templates in themes/<naam>/. ThemeManager rendert via Twig en compileert assets/scss/theme.scss runtime naar assets/css/theme.css. Layout gekozen via frontmatter layout: key; onbekende layouts vallen terug op config.default_template in theme.json.
  • Plugin CSS: Plugins hebben eigen assets/scss/ en assets/css/. Plugin CSS wordt automatisch geladen na theme CSS (in base.twig), zodat thema's plugin styling kunnen overschrijven. Plugin assets worden geserveerd via cms/router.php op URL /plugins/<Name>/assets/....
  • Navigation: Auto-generated from directory structure. Folders require an index file to be clickable in breadcrumbs. Breadcrumb is dynamisch: Home > [submappen] > [pagina]. Homepage toont altijd het pad.
  • Security:
    • Always use htmlspecialchars() for outputting user/content data
    • Use realpath() + prefix-check for path traversal prevention
    • Admin forms require CSRF tokens via AdminAuth::verifyCsrf()
    • Passwords stored as bcrypt hashes in admin/config/admin.json
    • Role-based access control (RBAC) via AdminAuth::hasPermission()
  • Git: main is the clean CMS core. development is de actieve development branch. e.noorlander bevat persoonlijke content. Niet mixen.

Admin Console

  • File-based: Geen database. Gebruikers opgeslagen in admin/config/admin.json
  • Routing: Via clean URLs /admin/<route> (omgezet naar ?route= door cms/router.php)
  • Routes: login, logout, dashboard, content, content-edit, content-new, content-delete, content-dir-create, content-dir-rename, content-dir-delete, content-move, config, security, theme, theme-new, plugins, plugins-new, plugins-edit, plugins-config, plugins-toggle, plugins-delete, users, statistics, logs, media, guide, update
  • Auth: Session-based. AdminAuth class handelt login, logout, CSRF, brute-force lockout af
  • Templates: Twig templates in admin/theme/default/views/pages/. Layout in admin/theme/default/views/layouts/admin.twig
  • Essentiële plugins: Gedefinieerd in getProtectedPlugins() in public/admin.php. Deze plugins kunnen niet worden gedeactiveerd, bewerkt of verwijderd. Huidige essentiële plugins: Navigation.

Gebruikersrollen (RBAC)

Gedefinieerd in AdminAuth::ROLE_PERMISSIONS als een mapping van rol → toegestane routes.

Rol Label Permissies
admin Admin Alles (*)
content-manager Content Beheerder Content beheer, handleiding
bi-manager BI Beheerder Statistieken, logs, handleiding
site-admin Site Admin Thema, plugins, statistieken, logs, update, handleiding
  • Sidebar items worden conditioneel getoond via has_permission() Twig function
  • Dashboard inhoud is role-based (statistieken, content stats, systeem info, quick actions)
  • Route access control in public/admin.php: onbevoegde routes geven 403 error

Guide Systeem

  • Handleidingen in guide/<lang>/ met sub-onderdelen in aparte mappen
  • NL en EN hebben identieke structuur (bestandsnamen zijn gelijk voor fallback)
  • getGuidePage() in CodePressCMS.php laadt guide content en injecteert plugins: Navigation in metadata
  • Navigation plugin genereert zijbalk navigatie vanuit de mapstructuur (guide + content)
  • Guide titles worden uit H1 van markdown bestanden gehaald (via getTitleFromFile())
  • Admin guide laadt Navigation plugin direct in handleGuide() in public/admin.php

Important: Title vs File/Directory Name Logic

  • CRITICAL: When user asks for "title" corrections, they usually mean FILE/DIRECTORY NAME WITHOUT LANGUAGE PREFIX AND EXTENSIONS, not the HTML title from content!
  • Examples:
    • nl.test.md → display as "Test" (not content title)
    • nl.test/ directory → display as "Test" (not H1 content)
    • en.php-testen → display as "Php Testen" (not "ICT")
  • Method: Use formatDisplayName() to process file/directory names correctly
  • Priority: Directory names take precedence over file names when both exist
  • Language prefixes: Dynamisch verwijderd op basis van beschikbare talen via getAvailableLanguages()

Bekende aandachtspunten

  • LSP errors over "Undefined function" in PHP files zijn vals-positief (standaard PHP functies worden niet herkend door de LSP). Negeer deze.
  • Zie TODO.md voor alle openstaande verbeteringen en nieuwe features.
  • vendor/ map bevat Composer dependencies (CommonMark, Twig, scssphp). Niet handmatig wijzigen.
  • admin/config/admin.json bevat wachtwoord-hashes. Niet committen met echte productie-wachtwoorden.
  • config.json staat in .gitignore. Niet committen.
  • var/ (Twig cache) staat in .gitignore. Kan veilig worden gewist: rm -rf var/cache/twig/*
  • content/ staat in .gitignore. Content wordt lokaal beheerd.
  • Pad-referenties vanuit public/admin.php: gebruik __DIR__ . "/../themes/..." (één niveau omhoog), NIET ../../ (twee niveaus).