# CodePress CMS Guide

## Overview

CodePress CMS is a lightweight, file-based content management system built with PHP (>=8.0). Works without a database.

## Features

### Navigation
- Tab-style navigation with Bootstrap 5 styling
- Dropdown menus for folders and sub-folders
- Home button with icon
- Automatic menu generation based on directory structure
- Responsive design
- Breadcrumb navigation with sidebar toggle
- Active state marking
- **Sidebar toggle** - Button placed left of HOME in the breadcrumb to open/close the sidebar. The icon changes between open and closed state. The choice is preserved during the session

### Content Types
- **Markdown (.md)** - CommonMark support via `league/commonmark`
- **PHP (.php)** - Dynamic content
- **HTML (.html)** - Static HTML pages
- **Directory listings** - Automatic directory overviews
- **Language-specific content** - `en.` and `nl.` prefixes

### Search Functionality
- Full-text search through all content
- Results with snippets and highlighting
- Direct navigation to found pages
- SEO-friendly search results
- Search URL: `?search=query`

### Configuration
- **JSON configuration** in `config.json`
- Dynamic homepage setting (`default_page`)
- SEO settings (description, keywords)
- Author information with links
- Theme configuration via `themes/` directory
- Language settings
- Feature toggles (auto_link_pages, search_enabled, breadcrumbs_enabled)

### Layout & Design
- Flexbox layout for responsive structure
- Fixed header with logo and search
- Breadcrumb navigation
- Fixed footer with file info and links
- Bootstrap 5 styling
- Mustache templates (`cms/templates/`)
- Semantic HTML5 structure
- **Dynamic layouts** with YAML frontmatter
- **Sidebar support** with plugin integration and toggle function via breadcrumb
- **Theme support** via `themes/` directory with theme.json per theme

### Admin Console
- Built-in admin panel at `/admin.php`
- **Dashboard** with statistics (pages, directories, plugins) and quick actions
- **Content management** - Browse files, upload, create, edit, rename, move and delete
- **CodeMirror editor** with toolbar (bold, italic, heading, link, image, list, media insert)
- **Media browser modal** in the editor for selecting images/files
- **Directory management** - Create, rename and delete directories (empty only)
- **Configuration editor** - Edit `config.json` with JSON validation
- **Theme management** - Create, activate, edit (colors, background) and delete themes
- **Plugin management** - Overview, create, edit, configure, enable/disable and delete
- **Media management** - Upload and delete media files in `content/-assets/`
- **User management** - Add, remove users, change passwords
- Session-based authentication with bcrypt hashing
- CSRF protection, brute-force lockout (5 attempts, 15 min)
- Default login: `admin` / `admin` (change immediately after installation)

## Installation

1. Upload files to web server
2. Set permissions for web server
3. Run `composer install` for CommonMark dependency
4. Configure `config.json` if needed
5. Access website via browser
6. **PHP development server**: `php -S localhost:8080 -t public` (uses `cms/router.php`)

## Project Structure

```
codepress/
├── cms/                            # Core CMS engine
│   ├── core/
│   │   ├── class/
│   │   │   ├── CodePressCMS.php    # Main CMS class (content, navigation, search)
│   │   │   ├── Logger.php          # Structured logging system
│   │   │   └── SimpleTemplate.php  # Mustache-style template engine
│   │   ├── plugin/
│   │   │   ├── PluginManager.php   # Plugin loader and manager
│   │   │   └── CMSAPI.php          # API for plugin developers
│   │   ├── config.php              # Configuration loader (merge with config.json)
│   │   └── index.php               # Bootstrap (autoloader, requires)
│   ├── lang/                       # Language files
│   │   ├── nl.php                  # Dutch translations
│   │   └── en.php                  # English translations
│   ├── logs/                       # CMS logs
│   ├── templates/                  # Mustache templates
│   │   ├── layout.mustache         # Main layout (CSS, structure)
│   │   ├── assets/                 # Header, navigation, footer partials
│   │   ├── markdown_content.mustache
│   │   ├── php_content.mustache
│   │   └── html_content.mustache
│   └── router.php                  # PHP dev server router
├── admin/                          # Admin panel
│   ├── config/
│   │   ├── app.php                 # Admin app configuration (paths, timezone)
│   │   └── admin.json              # Users & security (bcrypt hashes)
│   ├── src/
│   │   └── AdminAuth.php           # Authentication (sessions, bcrypt, CSRF, lockout)
│   ├── templates/
│   │   ├── login.php               # Login page
│   │   ├── layout.php              # Admin layout with sidebar navigation
│   │   └── pages/
│   │       ├── dashboard.php       # Dashboard with statistics
│   │       ├── content.php         # Content overview with file upload
│   │       ├── content-edit.php    # CodeMirror editor with toolbar and rename
│   │       ├── content-new.php     # Create new content
│   │       ├── content-dir-form.php    # Create/edit directory
│   │       ├── content-move-form.php   # Move content
│   │       ├── config.php          # Configuration editor (JSON)
│   │       ├── plugins.php         # Plugin overview
│   │       ├── plugins-edit.php    # Plugin PHP source code editor
│   │       ├── plugins-new.php     # Create new plugin
│   │       ├── plugin-config.php   # Plugin configuration editor
│   │       ├── theme.php           # Theme management (create, activate, edit)
│   │       ├── media.php           # Media management (upload, delete)
│   │       └── users.php           # User management
│   └── storage/logs/               # Admin logs
├── cli/                            # CLI scripts & tests
├── content/                        # Content files
│   ├── -assets/                    # Uploaded media files
│   ├── index.md                    # Default homepage
│   └── ...                         # Other content
├── plugins/                        # CMS plugins
│   ├── HTMLBlock/                  # Custom HTML blocks in sidebar
│   ├── MQTTTracker/                # Real-time analytics and tracking
│   └── test/                       # Test plugin
├── 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/                     # Uploaded theme backgrounds
│   └── manifest.json / sw.js       # PWA support
├── themes/                         # Theme definitions
│   ├── default/                    # Default theme
│   │   └── theme.json              # Colors, heights, background
│   └── test/                       # Test theme
│       └── theme.json
├── config.json                     # Site configuration
├── version.php                     # Version information (1.5.0)
└── vendor/                         # Composer dependencies
```

## Configuration

### Basic Configuration (`config.json`)

```json
{
    "site_title": "CodePress",
    "content_dir": "content",
    "templates_dir": "cms\/templates",
    "default_page": "index",
    "active_theme": "default",
    "language": {
        "default": "en",
        "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
    }
}
```

- `active_theme` - Determines which theme from `themes/` is active
- `templates_dir` - Directory with Mustache templates (`cms/templates`)
- `default_page` - Default page (e.g. `index`)
- `content_dir` - Directory with content files (usually not changed)

### Theme Configuration (`themes/<name>/theme.json`)

```json
{
    "name": "Default",
    "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"
}
```

Themes can be managed via the admin panel: create, activate, adjust colors, upload background image and delete.

## Content Structure

### File Structure

```
content/
├── folder1/
│   ├── subfolder1/
│   │   ├── nl.page1.md
│   │   └── en.page1.md
│   └── page3.html
├── folder2/
│   └── page4.md
├── index.md
└── -assets/
    ├── image.jpg
    └── document.pdf
```

### File Naming
- Use lowercase filenames
- No spaces - use `-` or `_`
- Logical extensions - `.md`, `.php`, `.html`
- Unique names - no duplicates
- Language prefixes - `nl.file.md` and `en.file.md`

### Media Files

Media files (images, PDFs, video, audio) can be placed in any `content/` subdirectory and are served via:

- **`/-media/path/file.jpg`** - Media from any content subdirectory
- **`/-assets/file.jpg`** - Backward compatibility (old URLs)
- Uploads via the admin panel go to `content/-assets/`

## Admin Console

### Access

- **URL**: `/admin.php`
- **Default login**: `admin` / `admin`

### Routes

| Route | Description |
|---|---|
| `login` | Login page |
| `logout` | Logout |
| `dashboard` | Dashboard with statistics |
| `content` | Content overview (browse, upload) |
| `content-edit` | Edit content (CodeMirror editor) |
| `content-new` | Create new content |
| `content-delete` | Delete content |
| `content-move` | Move content to another directory |
| `content-dir-form` | Create or edit directory |
| `content-dir-rename` | Rename directory |
| `content-dir-create` | Create directory (POST) |
| `content-dir-delete` | Delete directory (empty only) |
| `config` | Configuration editor (`config.json`) |
| `theme` | Theme management |
| `plugins` | Plugin overview |
| `plugins-new` | Create new plugin |
| `plugins-edit` | Edit plugin PHP source code |
| `plugins-config` | Edit plugin configuration |
| `plugins-toggle` | Enable/disable plugin |
| `plugins-delete` | Delete plugin |
| `media` | Media management (upload, delete) |
| `media-list` | JSON list of all media (for editor modal) |
| `users` | User management |

### Editor Features

The content editor (`content-edit`, `content-new`) includes:

- **CodeMirror** syntax highlighting for Markdown/PHP/HTML
- **Toolbar** with buttons for: bold, italic, heading, link, image, list, media insert
- **Media browser modal** - Open via the "Media" button to select images/files
- **Inline filename rename** - Inline filename input with extension badge
- **Layout selector** - Choose from available layouts
- **Plugin per-page visibility** - Select which plugins to show on this page
- **Upload and "Create" buttons** are disabled until input is provided
- **"Cancel" button** (instead of "Back") for unsaved changes

## Templates

### Template Variables

#### Site Info
- `site_title` - Website title
- `author_name` - Author name
- `author_website` - Author website
- `author_git` - Git repository link

#### Page Info
- `page_title` - Page title
- `content` - Content (HTML)
- `file_info` - File information
- `is_homepage` - Boolean: is this the homepage?

#### Navigation
- `menu` - Navigation menu
- `breadcrumb` - Breadcrumb navigation
- `homepage` - Homepage link

#### Theme (from theme.json)
- `header_color` - Header background color
- `header_font_color` - Header text color
- `header_height` - Header height in pixels
- `navigation_color` - Navigation background color
- `navigation_font_color` - Navigation text color
- `nav_height` - Navigation height in pixels
- `sidebar_background` - Sidebar background color
- `sidebar_border` - Sidebar border color
- `background_image_css` - CSS for background image
- `background_image_opacity` - Overlay opacity

#### Language
- `current_lang` - Current language (en/nl)
- `current_lang_upper` - Current language (EN/NL)
- `t_*` - Translated strings

### Layout Options

Use YAML frontmatter to select layout:

```yaml
---
title: My Page
layout: sidebar-content
plugins: HTMLBlock
---
```

### Available Layouts

- `sidebar-content` - Sidebar left, content right (default)
- `content` - Content only (full width)
- `sidebar` - Sidebar only
- `content-sidebar` - Content left, sidebar right
- `content-sidebar-reverse` - Content right, sidebar left

### Meta Data

```yaml
---
title: Page Title
layout: content-sidebar
description: Page description
author: Author Name
date: 2025-11-26
plugins: HTMLBlock, MQTTTracker
---
```

## URL Structure

### Frontend Page URLs
- **Home**: `/` or `?page=index&lang=en`
- **Page**: `?page=folder/page&lang=en`
- **Search**: `?search=query`
- **Guide**: `?guide`
- **Language switch**: `?lang=nl` or `?lang=en`

### Media URLs
- **Media**: `/-media/path/to/file.jpg` (from any content subdirectory)
- **Assets**: `/-assets/file.jpg` (from content/-assets/, backward compatible)

### Admin URLs
- **Admin**: `admin.php?route=dashboard`
- **Edit content**: `admin.php?route=content-edit&file=page.md`
- **New content**: `admin.php?route=content-new&dir=folder`
- **Edit theme**: `admin.php?route=theme&edit=themename`

## SEO Optimization

### Meta Tags

The CMS automatically adds meta tags:
```html
<meta name="generator" content="CodePress CMS">
<meta name="author" content="E. Noorlander">
<meta name="description" content="...">
<meta name="keywords" content="...">
```

### 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'; ...
```

## Plugin System

### Plugin Structure

```
plugins/
├── HTMLBlock/
│   ├── HTMLBlock.php         # Plugin class (required)
│   ├── config.json            # Configuration (optional)
│   └── README.md              # Documentation (optional)
├── MQTTTracker/
│   ├── MQTTTracker.php
│   ├── config.json
│   └── README.md
└── test/
    ├── test.php
    ├── config.json
    └── README.md
```

### Plugin Development

- **API access** via `CMSAPI` class - gives access to CMS configuration, templates, menu
- **Sidebar content** with `getSidebarContent()` - returns HTML for sidebar
- **Metadata access** from YAML frontmatter via `CMSAPI`
- **Configuration** via `config.json` - editable through admin panel
- **viewable** field in config.json determines if plugin is visible in sidebar
- **Per-page visibility** - via the editor plugin selector per page

### Plugin Boilerplate

```php
<?php

class MyPlugin
{
    private ?CMSAPI $api = null;
    private array $config;

    public function __construct()
    {
        $this->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);
    }
}
```

### Available Plugins

- **HTMLBlock** - Custom HTML blocks in sidebar
- **MQTTTracker** - Real-time analytics and tracking via MQTT
- **test** - Example/test plugin

### Known Issue: MQTTTracker Credentials

The MQTTTracker plugin stores `broker_host`, `broker_port`, `client_id`, `username` and `password` in plain text in `plugins/MQTTTracker/config.json`. This is a known open security issue - in a production environment it is recommended to externalize these credentials to environment variables or a separate credential manager.

## Analytics & Tracking

### MQTT Tracker

- Real-time page tracking via MQTT broker
- Session management
- Business Intelligence data
- Privacy aware (GDPR compliant)
- MQTT integration for dashboards
- Optional: visitor tracking, page views, performance metrics, user flows

## Frequently Asked Questions

### How do I set the homepage?

1. **Automatic**: Set `"default_page": "index"` in `config.json` (or omit the field)
2. **Manual**: Set `"default_page": "page-name"` in `config.json`

### How does navigation work?

- **Directories** become dropdown menus
- **Files** become direct links
- **Sub-directories** become nested dropdowns
- Only files without a language prefix show in the menu

### How do I add new content?

1. Via the admin panel: `admin.php?route=content-new`
2. Or upload files to the `content/` directory
3. Organize in logical directories
4. Use correct filenames and extensions

### How do I move a file or directory?

1. Go to `admin.php?route=content`
2. Click "Move" next to the item
3. Select the target directory
4. Confirm the move

### How do I create a new theme?

1. Go to `admin.php?route=theme`
2. Enter a name and click "Create"
3. Adjust colors, heights and background
4. Activate the theme

## Troubleshooting

### Page not found (404)

1. Check filename and path
2. Check file extension (.md, .php, .html)
3. Check file permissions
4. Check if the file has the correct language prefix (`nl.` or `en.`)

### Navigation not updated

1. Reload the page
2. Check content directory structure
3. Check filenames (no spaces)
4. Files with language prefix only show in the correct language mode

### Admin panel not accessible

1. Check if the session is still valid
2. On lockout: wait 15 minutes or clear lockout data in `admin/config/admin.json`
3. Check CSRF token (reload the page)

## Security

- **CSRF protection** via tokens on all admin forms
- **Brute-force lockout** after 5 failed attempts (15 minute block)
- **Bcrypt password hashing** for user passwords
- **Path traversal prevention** via `realpath()` and prefix check
- **Direct content access** blocked (403 Forbidden)
- **Security headers** for all pages
- **PHP execution** in content directory blocked
- **File upload restrictions** on allowed extensions

## Version

Current version: **1.5.0** (codename: "Enhanced")
Release date: 2025-11-26

## Support

For technical support:
- **Git**: https://git.noorlander.info/E.Noorlander/CodePress
- **Website**: https://noorlander.info
- **Issues**: Report problems via Git issues

## License

CodePress CMS is open-source software under dual-license: AGPL v3 for open-source use, commercial license for proprietary use.
