# CodePress CMS Handleiding
## Inhoudsopgave
- [Overzicht](#overzicht)
- [Installatie](#installatie)
- [Projectstructuur](#projectstructuur)
- [Content](#content)
- [Content Structuur](#content-structuur)
- [Content API (voor PHP content)](#content-api-voor-php-content-bestanden)
- [Instellingen](#instellingen)
- [Configuratie](#configuratie)
- [Thema's](#themas)
- [Beveiliging](#beveiliging)
- [Gegevens](#gegevens)
- [Statistieken & Analytics](#statistieken--analytics)
- [Logging](#logging)
- [Systeem](#systeem)
- [Plugin Systeem](#plugin-systeem)
- [Gebruikersbeheer](#gebruikersbeheer)
- [Update](#update)
- [Handleiding](#handleiding-in-admin)
- [Overig](#overig)
- [Templates](#templates)
- [URL Structuur](#url-structuur)
- [SEO Optimalisatie](#seo-optimalisatie)
- [Veelgestelde Vragen](#veelgestelde-vragen)
- [Troubleshooting](#troubleshooting)
- [Versie](#versie)
- [Ondersteuning](#ondersteuning)
- [Licentie](#licentie)
## Overzicht
CodePress CMS is een lichtgewicht, file-based content management systeem gebouwd met PHP (>=8.0). Werkt zonder database.
## Installatie
1. Upload bestanden naar webserver
2. Stel permissies in voor webserver
3. Voer `composer install` uit voor CommonMark dependency
4. Configureer `config.json` indien nodig
5. Toegang tot website via browser
6. **PHP ontwikkelserver**: `php -S localhost:8080 -t public` (gebruikt `cms/router.php`)
## Projectstructuur
```
codepress/
├── cms/ # Core CMS engine
│ ├── core/
│ │ ├── class/
│ │ │ ├── CodePressCMS.php # Hoofd CMS class (content, navigatie, search)
│ │ │ ├── Logger.php # Gestructureerd logging systeem
│ │ │ ├── SimpleTemplate.php # Mustache-style template engine
│ │ │ ├── Analytics.php # Bezoekersstatistieken
│ │ │ ├── BotGuard.php # Bot/AI/scraper detectie
│ │ │ ├── GeoIP.php # Landbepaling op basis van IP
│ │ │ ├── Cache.php # File-based caching
│ │ │ └── RateLimiter.php # Snelheidsbeperking per IP
│ │ ├── plugin/
│ │ │ ├── PluginManager.php # Plugin lader en beheer
│ │ │ └── CMSAPI.php # API voor plugin developers
│ │ ├── config.php # Configuratie lader (merge met config.json)
│ │ └── index.php # Bootstrap (autoloader, requires)
│ ├── lang/ # Taalbestanden
│ │ ├── nl.php # Nederlandse vertalingen
│ │ └── en.php # Engelse vertalingen
│ ├── templates/ # Mustache templates
│ │ ├── layout.mustache # Hoofd layout (CSS, structuur)
│ │ ├── assets/ # Header, navigation, footer partials
│ │ ├── markdown_content.mustache
│ │ ├── php_content.mustache
│ │ └── html_content.mustache
│ └── router.php # PHP dev server router
├── admin/ # Admin paneel
│ ├── config/
│ │ ├── app.php # Admin app configuratie (paden, timezone)
│ │ └── admin.json # Gebruikers & security (bcrypt hashes)
│ ├── src/
│ │ └── AdminAuth.php # Authenticatie (sessies, bcrypt, CSRF, lockout)
│ ├── templates/
│ │ ├── login.php # Login pagina
│ │ ├── layout.php # Admin layout met sidebar navigatie
│ │ └── pages/
│ │ ├── dashboard.php # Dashboard met statistieken
│ │ ├── content.php # Content overzicht met bestanden uploaden
│ │ ├── content-edit.php # CodeMirror editor met toolbar en rename
│ │ ├── content-new.php # Nieuwe content aanmaken
│ │ ├── content-dir-form.php # Map aanmaken/bewerken
│ │ ├── content-move-form.php # Content verplaatsen
│ │ ├── config.php # Configuratie editor
│ │ ├── security.php # Beveiligingsinstellingen
│ │ ├── statistics.php # Statistieken dashboard
│ │ ├── plugins.php # Plugin overzicht
│ │ ├── plugins-edit.php # Plugin PHP broncode editor
│ │ ├── plugins-new.php # Nieuwe plugin aanmaken
│ │ ├── plugin-config.php # Plugin configuratie editor
│ │ ├── theme.php # Thema beheer
│ │ ├── users.php # Gebruikersbeheer
│ │ ├── logs.php # Log viewer
│ │ ├── update.php # Systeem update
│ │ └── guide.php # Handleiding
│ └── storage/logs/ # Admin logs
├── cli/ # CLI scripts & tests
├── content/ # Content bestanden
│ ├── -assets/ # Geuploade mediabestanden
│ ├── index.md # Standaard homepage
│ └── ... # Overige content
├── plugins/ # CMS plugins
│ ├── HTMLBlock/ # Custom HTML blokken in sidebar
│ └── MQTTTracker/ # Real-time analytics en tracking
├── public/ # Web root
│ ├── index.php # Website entry point (media serving + CMS)
│ ├── admin.php # Admin entry point + routing
│ ├── .htaccess # Apache rewrite/security rules
│ ├── assets/ # CSS, JS, favicons
│ │ ├── codemirror/ # CodeMirror editor (minified JS/CSS)
│ │ └── css/js/ # Bootstrap, icons, app CSS/JS
│ ├── themes/ # Geuploade theme achtergronden
│ └── manifest.json / sw.js # PWA ondersteuning
├── themes/ # Thema definities
│ ├── default/ # Standaard thema
│ │ └── theme.json # Kleuren, hoogtes, achtergrond
│ └── ... # Andere thema's
├── config.json # Site configuratie
├── version.php # Versie informatie
└── vendor/ # Composer dependencies
```
---
## Content
### Content Structuur
#### Bestandsstructuur
```
content/
├── map1/
│ ├── submap1/
│ │ ├── nl.pagina1.md
│ │ └── en.pagina1.md
│ └── pagina3.html
├── map2/
│ └── pagina4.md
├── index.md
└── -assets/
├── afbeelding.jpg
└── document.pdf
```
#### Bestandsnamen
- Gebruik lowercase bestandsnamen
- Geen spaties - gebruik `-` of `_`
- Logische extensies - `.md`, `.php`, `.html`
- Unieke namen - geen duplicaten
- Language prefixes - `nl.bestand.md` en `en.bestand.md`
#### Media Bestanden
Media bestanden (afbeeldingen, PDFs, video, audio) kunnen in elke `content/` subdirectory worden geplaatst en worden geserveerd via:
- **`/-media/pad/bestand.jpg`** - Media uit elke content subdirectory
- **`/-assets/bestand.jpg`** - Backward compatibility (oude URLs)
- Uploads via het admin paneel gaan naar `content/-assets/`
### Content API (voor PHP content bestanden)
PHP content bestanden (`.php` in de `content/` map) hebben toegang tot een `$api` variabele met de volgende methodes:
#### Pagina's opvragen
```php
// Alle pagina's met titels ophalen
$pages = $api->getAllPages();
// Resultaat: ['index' => 'Home', 'over-ons' => 'Over ons', ...]
// specifieke pagina inhoud ophalen
$page = $api->getPage('over-ons');
// $page['title'], $page['content'], $page['path'], $page['layout'], $page['metadata']
// Controleren of een pagina bestaat
if ($api->pageExists('contact')) {
// ...
}
```
#### Navigatie
```php
// Menu structuur ophalen
$menu = $api->getMenu();
// Bevat geneste array met 'title', 'path', 'url', 'children'
```
#### Configuratie
```php
// Configuratie waarde opvragen (punt-notatie)
$title = $api->getConfig('site_title');
$lang = $api->getConfig('language.default');
$seoDesc = $api->getConfig('seo.description', 'Standaard beschrijving');
```
#### Huidige pagina
```php
// Huidige pagina titel
$pageTitle = $api->getCurrentPageTitle();
// Huidige pagina pad
$pagePath = $api->getCurrentPagePath();
// Check of dit de homepage is
if ($api->isHomepage()) {
echo 'Welkom!';
}
```
#### URLs en taal
```php
// URL bouwen voor een pagina
$url = $api->buildUrl('over-ons', 'nl');
// Huidige taal
$lang = $api->getCurrentLanguage();
// Beschikbare talen
$languages = $api->getAvailableLanguages();
// Site titel
$title = $api->getSiteTitle();
```
#### Vertalingen en zoeken
```php
// Vertaling ophalen
$label = $api->t('home');
// Zoekresultaten (als er gezocht wordt)
if ($api->isSearching()) {
$results = $api->getSearchResults();
}
```
#### Voorbeeld PHP content bestand
```php
---
title: Pagina Overzicht
layout: content
---
Alle Pagina's
```
---
## Instellingen
### Configuratie
De site configuratie wordt beheerd via het **admin paneel** op `/admin/config`. Het formulier bevat de volgende secties:
- **Algemene instellingen** - Site titel en startpagina (dropdown met beschikbare pagina's)
- **Taal** - Standaard taal en beschikbare talen
- **SEO** - Meta beschrijving en keywords
- **Auteur** - Naam en website
- **Features** - Auto-link pagina's, zoekfunctie, breadcrumbs, versie tonen
- **IP Uitsluitingen** - IP-adressen uitsluiten van statistieken en beveiligingscontroles
De configuratie wordt opgeslagen in `config.json`. Je kunt dit bestand ook handmatig bewerken voor geavanceerde opties.
#### IP Uitsluitingen
Onder **Configuratie** in het admin paneel vind je het veld "IP-adressen uitsluiten". IP's die hier worden ingevuld worden:
- Niet opgenomen in de bezoekersstatistieken
- Overgeslagen bij alle beveiligingscontroles (bot-detectie, rate limiting, IP blocklist)
Dit is handig voor je eigen IP-adres of dat van interne monitoring tools.
#### Voorbeeld `config.json`
```json
{
"site_title": "CodePress",
"content_dir": "content",
"templates_dir": "cms\/templates",
"default_page": "index",
"active_theme": "default",
"language": {
"default": "nl",
"available": ["nl", "en"]
},
"seo": {
"description": "CodePress CMS - Lightweight file-based content management system",
"keywords": "cms, php, content management, file-based"
},
"author": {
"name": "E. Noorlander",
"website": "https:\/\/noorlander.info"
},
"features": {
"auto_link_pages": true,
"search_enabled": true,
"breadcrumbs_enabled": true
},
"analytics": {
"enabled": true,
"excluded_ips": ["127.0.0.1", "::1"]
},
"security": {
"block_ai_bots": true,
"block_scrapers": true,
"block_empty_user_agent": true,
"rate_limit_enabled": true
}
}
```
### Thema's
Thema's worden beheerd via het admin paneel op `/admin/theme`. Je kunt thema's aanmaken, activeren, kleuren aanpassen, achtergrondafbeeldingen uploaden en verwijderen.
#### Thema Configuratie (`themes//theme.json`)
```json
{
"name": "Standaard",
"header_color": "#0a369d",
"header_font_color": "#ffffff",
"header_height": "56",
"navigation_color": "#2754b4",
"navigation_font_color": "#ffffff",
"nav_height": "42",
"sidebar_background": "#f8f9fa",
"sidebar_border": "#dee2e6",
"background_image": "",
"background_image_opacity": "100"
}
```
#### Een nieuw thema maken
1. Ga naar `/admin/theme`
2. Voer een naam in en klik "Aanmaken"
3. Pas kleuren, hoogtes en achtergrond aan
4. Activeer het thema
### Beveiliging
Beveiligingsinstellingen worden beheerd via `/admin/security`. Hier vind je:
#### Bot, AI & Scraper Blokkering
Bij binnenkomende requests detecteert het systeem bekende bots en AI-crawlers op basis van de User-Agent header. Gedetecteerde bots krijgen een **403 Forbidden**.
| Categorie | Voorbeelden |
|---|---|
| AI Crawlers | GPTBot, ChatGPT-User, Claude-Web, ClaudeBot, Google-Extended, CCBot, PerplexityBot |
| Search Engines | Googlebot, Bingbot, BingPreview, DuckDuckBot, YandexBot, Baiduspider |
| Scrapers | HTTrack, Scrapy, PhantomJS |
#### Snelheidsbeperking (Rate Limiting)
Voorkomt dat IP's de site overbelasten. Bij overschrijding wordt HTTP 429 geretourneerd.
#### IP Lijsten
- **IP Whitelist** - IP's op de whitelist worden nooit geblokkeerd
- **IP Blocklist** - IP's op de blocklist krijgen altijd een 403 Forbidden
#### Dynamische robots.txt
Het systeem genereert automatisch een `robots.txt` op basis van je beveiligingsinstellingen, beschikbaar op `/robots.txt`.
---
## Gegevens
### Statistieken & Analytics
Het statistieken dashboard is beschikbaar op `/admin/statistics` en biedt:
- **KPI-kaarten** - Paginaweergaven, unieke bezoekers, mens/bot verhouding, geblokkeerde verzoeken
- **Wereldkaart** - Visuele weergave van bezoekers per land met kleurintensiteit
- **Landenlijst** - Top 25 landen met percentage
- **Meest gelezen pagina's** - Top 25 pagina's
- **Dagelijkse grafiek** - Staafdiagram van bezoekers per dag
- **Verwijzende sites** - Top 15 referrers
#### Periodes en export
Filter op 7, 30, 90 dagen of alles. Exporteer data als CSV of JSON.
#### GeoIP
Landbepaling kan via drie bronnen:
- **Lokaal (DB-IP Lite)** - Offline, privacy-vriendelijk, automatisch bijgewerkt
- **MaxMind database (.mmdb)** - Eigen MMDB bestand
- **Externe API** - Eigen API URL en sleutel
### Logging
De admin console houdt twee logs bij, te bekijken via `/admin/logs`:
- **Activiteiten log** (`admin/storage/logs/admin.log`) — admin acties zoals pagina's aanmaken, bewerken, verwijderen, plugin in/uitschakelen, configuratie wijzigen.
- **Requests log** (`admin/storage/logs/requests.log`) — elke pageview op de website, met IP, pagina, domein, taal, user-agent en referrer.
Het dashboard toont de laatste 20 entries van elk log. Klik "Bekijk alle →" voor de volledige lijst, waar je ook kunt downloaden of wissen.
---
## Systeem
### Plugin Systeem
#### Plugin Structuur
```
plugins/
├── HTMLBlock/
│ ├── HTMLBlock.php # Plugin class (verplicht)
│ ├── config.json # Configuratie (optioneel)
│ └── README.md # Documentatie (optioneel)
├── MQTTTracker/
│ ├── MQTTTracker.php
│ ├── config.json
│ └── README.md
```
#### Plugin Ontwikkeling
- **API toegang** via `CMSAPI` class - geeft toegang tot CMS configuratie, templates, menu
- **Sidebar content** met `getSidebarContent()` - retourneert HTML voor sidebar
- **Metadata toegang** uit YAML frontmatter via `CMSAPI`
- **Configuratie** via `config.json` - bewerkbaar via admin paneel
- **viewable** veld in config.json bepaalt of plugin zichtbaar is in sidebar
- **Per-page zichtbaarheid** - via de editor plugin selector per pagina
#### Plugin Boilerplate
```php
config = [
'viewable' => true,
];
}
public function setAPI(CMSAPI $api): void
{
$this->api = $api;
}
public function getSidebarContent(): string
{
return '';
}
public function getConfig(): array
{
return $this->config;
}
public function setConfig(array $config): void
{
$this->config = array_merge($this->config, $config);
}
}
```
#### Bekende Issue: MQTTTracker Credentials
De MQTTTracker plugin slaat `broker_host`, `broker_port`, `client_id`, `username` en `password` op in plain text in `plugins/MQTTTracker/config.json`. Dit is een bekend openstaand security punt - bij een productieomgeving wordt aangeraden deze gegevens te externaliseren naar omgevingsvariabelen of een aparte credentials manager.
### Gebruikersbeheer
Gebruikers worden beheerd via `/admin/users`. Functionaliteiten:
- Gebruiker toevoegen met gebruikersnaam, wachtwoord en rol
- Gebruiker verwijderen
- Wachtwoord wijzigen voor andere gebruikers (admin)
- Eigen wachtwoord wijzigen (vereist huidig wachtwoord)
Wachtwoorden worden opgeslagen als bcrypt-hashes in `admin/config/admin.json`.
### Update
Via `/admin/update` kan het systeem in één klik worden bijgewerkt via Git pull. De pagina toont de huidige versie en git branch, en voert na bevestiging `git pull origin ` uit.
---
## Handleiding (in Admin)
Deze handleiding is ook ingebouwd in het admin paneel via `/admin/guide`, met ondersteuning voor Nederlands en Engels.
---
## Overig
### Templates
#### Template Variabelen
**Site Info** - `site_title`, `author_name`, `author_website`, `author_git`
**Page Info** - `page_title`, `content`, `file_info`, `is_homepage`
**Navigation** - `menu`, `breadcrumb`, `homepage`
**Theme (uit theme.json)** - `header_color`, `header_font_color`, `header_height`, `navigation_color`, `navigation_font_color`, `nav_height`, `sidebar_background`, `sidebar_border`, `background_image_css`, `background_image_opacity`
**Language** - `current_lang`, `current_lang_upper`, `t_*` (vertaalde strings)
#### Layout Opties
Gebruik YAML frontmatter om layout te selecteren:
```yaml
---
title: Mijn Pagina
layout: sidebar-content
plugins: HTMLBlock
---
```
#### Beschikbare Layouts
- `sidebar-content` - Sidebar links, content rechts (standaard)
- `content` - Alleen content (volle breedte)
- `sidebar` - Alleen sidebar
- `content-sidebar` - Content links, sidebar rechts
- `content-sidebar-reverse` - Content rechts, sidebar links
#### Meta Data
```yaml
---
title: Pagina Titel
layout: content-sidebar
description: Pagina beschrijving
author: Auteur Naam
date: 2025-11-26
plugins: HTMLBlock, MQTTTracker
---
```
### URL Structuur
#### Frontend Pagina URLs
- **Home**: `/` of `/nl/`
- **Pagina**: `/nl/map/pagina`
- **Zoeken**: `?search=zoekterm` (via zoekformulier)
#### Media URLs
- **Media**: `/-media/pad/naar/bestand.jpg` (uit elke content subdirectory)
- **Assets**: `/-assets/bestand.jpg` (uit content/-assets/, backward compatible)
#### Admin URLs
- **Admin**: `/admin`
- **Dashboard**: `/admin/dashboard`
- **Content**: `/admin/content`
- **Configuratie**: `/admin/config`
- **Beveiliging**: `/admin/security`
- **Statistieken**: `/admin/statistics`
- **Thema**: `/admin/theme`
- **Plugins**: `/admin/plugins`
- **Gebruikers**: `/admin/users`
- **Logs**: `/admin/logs`
- **Update**: `/admin/update`
- **Handleiding**: `/admin/guide`
### SEO Optimalisatie
#### Meta Tags
De CMS voegt automatisch meta tags toe:
```html
```
#### Security Headers
```http
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; ...
```
### Veelgestelde Vragen
#### Hoe stel ik de homepage in?
1. Ga naar **Configuratie** in het admin paneel (`/admin/config`)
2. Selecteer de gewenste pagina in het **Standaard/startpagina** dropdown
3. Klik op **Configuratie opslaan**
#### Hoe werkt de navigatie?
- **Mappen** worden dropdown menus
- **Bestanden** worden directe links
- **Sub-mappen** worden geneste dropdowns
- Alleen bestanden zonder taalprefix tonen in het menu
#### Hoe voeg ik nieuwe content toe?
1. Via het admin paneel: `/admin/content-new`
2. Of upload bestanden naar de `content/` map
3. Organiseer in logische mappen
4. Gebruik juiste bestandsnamen en extensies
#### Hoe verplaats ik een bestand of map?
1. Ga naar `/admin/content`
2. Klik op "Verplaatsen" naast het item
3. Selecteer de doelmap
4. Bevestig de verplaatsing
#### Hoe sluit ik mijn eigen IP uit van statistieken?
1. Ga naar **Configuratie** in het admin paneel (`/admin/config`)
2. Scroll naar het veld "IP-adressen uitsluiten"
3. Voer je IP-adres in (één per regel)
4. Klik op **Configuratie opslaan**
### Troubleshooting
#### Pagina niet gevonden (404)
1. Controleer bestandsnaam en pad
2. Controleer bestandsextensie (.md, .php, .html)
3. Controleer permissies van bestanden
4. Controleer of het bestand de juiste taalprefix heeft (`nl.` of `en.`)
#### Navigatie niet bijgewerkt
1. Herlaad de pagina
2. Controleer content map structuur
3. Controleer bestandsnamen (geen spaties)
4. Bestanden met taalprefix worden alleen getoond in de juiste taalmodus
#### Admin paneel niet toegankelijk
1. Controleer of de sessie nog geldig is
2. Bij lockout: wacht 15 minuten of wis `admin/config/admin.json` lockout data
3. Controleer CSRF token (herlaad de pagina)
## Versie
Huidige versie: **1.9.1**
Release datum: 2026-07-29
## Ondersteuning
Voor technische ondersteuning:
- **Git**: https://git.noorlander.info/E.Noorlander/CodePress
- **Website**: https://noorlander.info
- **Issues**: Rapporteer problemen via Git issues
## Licentie
CodePress CMS is open-source software onder dual-license: AGPL v3 voor open-source gebruik, commerciële licentie voor proprietary gebruik.