# Stopp lidelsen - Site built on FolderWeb Advocacy site for medical cannabis patients in Norway. Built on FolderWeb (minimal file-based CMS). ## 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: read `app/docs/` when needed for understanding routing, hooks, templates, etc. - Site-specific docs: read `docs/` in this repo for guidance on this site's features and customizations. ## Philosophy Minimal PHP for modern conveniences. Decade-scale maintainability. No volatile dependencies. Only essential code. ## Core Constraints **Stack:** HTML5, PHP 8.4+, CSS. no frameworks, no build tools, no package managers. **Frontend:** Classless semantic HTML5. Modern CSS (nesting, `oklch()`, grid, `clamp()`, logical props). Responsive via fluid typography + flexible layouts. Comments only for major sections. **Security:** Path traversal protection, document root restriction, strict MIME types, escape all UGC, CSV injection prevention. ## Code Style **PHP:** Arrow functions, null coalescing, match. Type hints where practical. Single-purpose functions. **CSS:** Variables, native nesting, grid. `clamp()` over `@media`. Relative units. Margin-top only (reset: `* { margin-bottom: 0 }`). **Templates:** `` for UGC. `` for pre-rendered HTML. ## 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 ``` ## Key Features **Content:** Folders = URLs. `metadata.ini` controls titles, slugs, menu order, templates, feeds. **Languages:** Norwegian (default), English available. Language plugin via `[en]` sections in metadata. **Templates:** base.php wraps all pages. List templates: list.php, list-card-grid.php, list-faq.php, list-grid.php. Selected via `page_template` in metadata. **Atom feeds:** Enabled per-section via `feed = true` in metadata. URL: `/{section}/feed.xml`. Feed link auto-added to `` when `$feedUrl` is set. **Petition system:** GDPR-compliant, CSV-based, double opt-in email confirmation, file locking, rate limiting. See `docs/petition-system.md`. **Newsletter:** Listmonk integration via public API. Hero and small themes. See `docs/newsletter-plugin.md`. ## Knowledge Base Read these docs on-demand when working on related areas: | Topic | File | Read When | |---|---|---| | Templates & variables | `docs/templates.md` | Modifying templates, understanding available variables | | Content & metadata | `docs/content-system.md` | Adding/modifying content, metadata fields, feeds | | Petition system | `docs/petition-system.md` | Modifying petition form, CSV format, email flow | | Newsletter plugin | `docs/newsletter-plugin.md` | Modifying newsletter signup, Listmonk integration | | Framework internals | `app/docs/` | Understanding routing, hooks, plugins, rendering pipeline | ## Development Environment Host has no PHP. Always use `podman compose` with `compose.yaml`. **Dev server:** `localhost:4040` **Testing:** `curl localhost:4040/path` to fetch pages; `curl -X POST -d "field=value" localhost:4040/path` for forms **Container isolation:** ALL test data (CSV, temp files) MUST stay inside container filesystem, never in mounted volumes **Test data paths:** Use `/tmp/` or `/var/test/` inside container **Running tests:** `podman exec stopplidelsen.no php /path/to/test.php` or `podman-compose run --rm custom php /tmp/test-script.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