# Agent Instructions for CodePress CMS ## AI Model - **Huidig model**: `claude-opus-4-6` (OpenCode / `opencode/claude-opus-4-6`) - Sessie gestart: 16 feb 2026 ## Build & Run - **Run Server**: `php -S localhost:8080 -t public` - **Lint PHP**: `find . -name "*.php" -not -path "./vendor/*" -exec php -l {} \;` - **Dependencies**: Composer vereist voor CommonMark. Geen NPM. - **Admin Console**: Toegankelijk op `/admin.php` (standaard login: `admin` / `admin`) ## Project Structuur ``` codepress/ ├── engine/ │ ├── core/ │ │ ├── class/ │ │ │ ├── CodePressCMS.php # Hoofd CMS class │ │ │ ├── Logger.php # Logging systeem │ │ │ └── SimpleTemplate.php # Mustache-style template engine │ │ ├── plugin/ │ │ │ ├── PluginManager.php # Plugin loader │ │ │ └── CMSAPI.php # API voor plugins │ │ ├── config.php # Config loader (leest config.json) │ │ └── index.php # Bootstrap (autoloader, requires) │ ├── lang/ # Taalbestanden (nl.php, en.php) │ └── templates/ # Mustache templates │ ├── layout.mustache # Hoofd layout (bevat inline CSS) │ ├── assets/ │ │ ├── header.mustache │ │ ├── navigation.mustache │ │ └── footer.mustache │ ├── markdown_content.mustache │ ├── php_content.mustache │ └── html_content.mustache ├── admin-console/ # Admin paneel │ ├── config/ │ │ ├── app.php # Admin app configuratie │ │ └── admin.json # Gebruikers & security (file-based) │ ├── src/ │ │ └── AdminAuth.php # Authenticatie (sessies, bcrypt, CSRF, lockout) │ ├── templates/ │ │ ├── login.php # Login pagina │ │ ├── layout.php # Admin layout met sidebar │ │ └── pages/ │ │ ├── dashboard.php │ │ ├── content.php │ │ ├── content-edit.php │ │ ├── content-new.php │ │ ├── config.php │ │ ├── plugins.php │ │ └── users.php │ └── storage/logs/ # Admin logs ├── plugins/ # CMS plugins │ ├── HTMLBlock/ │ └── MQTTTracker/ ├── public/ # Web root │ ├── assets/css/js/ │ ├── index.php # Website entry point │ └── admin.php # Admin entry point + router ├── content/ # Content bestanden ├── guide/ # Handleidingen (nl/en) ├── config.json # Site configuratie ├── TODO.md # Openstaande verbeteringen └── 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 `engine/core/class/CodePressCMS.php` - Bootstrap/requires in `engine/core/index.php` - Configuration loaded from `config.json` via `engine/core/config.php` - Public website entry point: `public/index.php` - Admin entry point + routing: `public/admin.php` - Admin authenticatie: `admin-console/src/AdminAuth.php` - **Content**: Stored in `content/`. Supports `.md` (Markdown), `.php` (Dynamic), `.html` (Static). - **Templating**: Mustache-style `{{placeholder}}` in `templates/layout.mustache` via `SimpleTemplate.php`. - **Navigation**: Auto-generated from directory structure. Folders require an index file to be clickable in breadcrumbs. - **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.json` - **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-console/config/admin.json` - **Routing**: Via `?route=` parameter in `public/admin.php` - **Routes**: `login`, `logout`, `dashboard`, `content`, `content-edit`, `content-new`, `content-delete`, `config`, `plugins`, `users` - **Auth**: Session-based. `AdminAuth` class handelt login, logout, CSRF, brute-force lockout af - **Templates**: Pure PHP templates in `admin-console/templates/pages/`. Layout in `layout.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, Mustache). Niet handmatig wijzigen. - `admin-console/config/admin.json` bevat wachtwoord-hashes. Niet committen met echte productie-wachtwoorden.