innhold/AGENT.md
Ruben b8e6d2537d Add browser and unit test suite with Pest + Playwright
Add comprehensive test coverage for core site features (content,
navigation, language, FAQ, news, petition, newsletter) using Pest
browser tests and unit tests for custom plugins. Includes test
infrastructure (Containerfile.test, compose.test.yaml), test
documentation, and test files covering petition form logic, CSV
handling, translation, date formatting, rate limiting, and map data
building.
2026-03-17 16:43:39 +01:00

69 lines
3.3 KiB
Markdown

# Stopp lidelsen - Site built on FolderWeb
Advocacy site for medical cannabis patients in Norway. Built on FolderWeb (minimal file-based CMS). Decade-scale maintainability, no volatile dependencies, only essential code.
## Edit instructions
All edits to this AGENT.md file should be done in a compressed shortform for LLM consumption.
## Two Repos, One Site
- `app/` is a **symlink** to the FolderWeb framework (`folderweb/app`). **NEVER modify files in `app/`.**
- Only modify files in `custom/`, `content/`, and project root.
- Framework docs: `../folderweb/docs/04-development/` (architecture, context API, hooks/plugins, rendering, templates, etc.)
- Site-specific docs: `docs/` in this repo.
## Standards
**Stack:** HTML5, PHP 8.4+, CSS. No frameworks, no build tools, no package managers.
**PHP:** Arrow functions, null coalescing, match. Type hints where practical. Single-purpose functions, avoid side effects.
**CSS:** Variables, native nesting, grid. `clamp()` over `@media`. Relative units. `oklch()`, `light-dark()`, logical props. Margin-top only (reset: `* { margin-bottom: 0 }`).
**HTML/Templates:** Classless semantic HTML5. `<?= htmlspecialchars($var) ?>` for UGC. `<?= $content ?>` for pre-rendered HTML.
**Security:** Path traversal protection, document root restriction, strict MIME types, escape all UGC, CSV injection prevention.
## Project Structure
```
content/ # Site content (folders = URLs)
custom/
config.ini # Site config (languages, plugins)
templates/ # Template overrides (base, list, page, list-card-grid, list-faq, list-grid)
styles/ # CSS overrides
plugins/page/ # Page plugins (petition-form, newsletter-signup)
languages/ # Translation files (no.ini, en.ini)
data/ # Runtime data (petition CSVs, rate limits, SMTP logs)
vendor/ # PHPMailer.Lite
app/ -> symlink # FolderWeb framework (DO NOT EDIT)
docs/ # Site-specific LLM documentation
```
Content: folders = URLs, numbered file prefixes control order, `cover.jpg` for list item images, `metadata.ini` controls titles/slugs/menu order/templates/feeds.
## Knowledge Base
Read on-demand:
| Topic | File |
|---|---|
| Templates & variables | `docs/templates.md` |
| Content & metadata | `docs/content-system.md` |
| Petition system | `docs/petition-system.md` |
| Newsletter plugin | `docs/newsletter-plugin.md` |
| Framework internals | `../folderweb/docs/04-development/` |
| Test suite | `tests/README.md` | **Required before modifying `custom/` or `content/`** — workflow, how to run, how to write tests |
Site features: Norwegian (default) + English via `[en]` metadata sections. Atom feeds via `feed = true` in metadata. Petition: GDPR, CSV, double opt-in, rate limiting. Newsletter: Listmonk API, hero/small themes.
## Development Environment
Host has no PHP. Always use `podman compose` with `compose.yaml`.
**Dev server:** `localhost:4040`
**Verification:** `curl localhost:4040/path`; `curl -X POST -d "field=value" localhost:4040/path` for forms
**Container isolation:** ALL test data MUST stay inside container filesystem, never in mounted volumes. Use `/tmp/` or `/var/test/`.
**Running scripts:** `podman exec stopplidelsen.no php /path/to/test.php`
**Syntax checks:** `podman exec stopplidelsen.no php -l /var/www/custom/file.php`
**Cleanup:** `podman-compose down && podman-compose up -d` between test runs