Slim down README: features to a blog post, docs pointer, ASCII banner
Features section becomes a "Novaconium Features" blog post (App/pages/blog/novaconium-features/), demonstrating the framework's own content model rather than living as a long bullet list in README.md. Getting started is trimmed to the minimum needed to run the site and reach /admin/docs, which is now the single canonical source for every topic (Docker, deploying, project layout, etc.) instead of being mirrored into README.md. Third-party section kept as-is. AGENTS.md's documentation-duplication rule updated to describe this new split so future changes don't re-bloat the README. Also adds an ASCII art banner above the title. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,19 +12,30 @@ query the graph instead of expecting this file to carry that context — this
|
|||||||
file is kept intentionally short and only lists things that will cause a
|
file is kept intentionally short and only lists things that will cause a
|
||||||
bug or a broken convention if you don't know them going in.
|
bug or a broken convention if you don't know them going in.
|
||||||
|
|
||||||
## Documentation is duplicated on purpose — keep all copies in sync
|
## Docs live in one place: `/admin/docs` — README stays thin
|
||||||
|
|
||||||
Every topic (routing, sidecars, libraries, layouts, caching, SEO, Matomo,
|
Every topic (routing, sidecars, libraries, layouts, caching, SEO, Matomo,
|
||||||
admin auth, styling, Docker, project layout, third-party) exists in two
|
admin auth, styling, Docker, project layout, third-party) has exactly one
|
||||||
places: a page under `novaconium/pages/admin/docs/<topic>/index.twig`
|
canonical writeup: a page under `novaconium/pages/admin/docs/<topic>/index.twig`.
|
||||||
(canonical) and a mention in `README.md`. Any change to framework behavior
|
`README.md` deliberately does **not** mirror this content — it's a short
|
||||||
or a new feature must update both in the same change:
|
GitHub-facing pitch (what this is, minimal steps to get it running, a
|
||||||
|
pointer into `/admin/docs`) plus the Third-party section, nothing more. The
|
||||||
|
full feature list lives as a blog post, `App/pages/blog/novaconium-features/`
|
||||||
|
(sample content, replaceable like any other post), not in the README. This
|
||||||
|
was a deliberate change (2026-07-15) away from an earlier "keep README and
|
||||||
|
docs in sync" convention that had made the README long and hard to scan —
|
||||||
|
don't re-add a feature list or per-topic bullet list to README.md.
|
||||||
|
|
||||||
|
Any change to framework behavior or a new feature:
|
||||||
|
|
||||||
1. Update/add the docs page, and if new, link it from both
|
1. Update/add the docs page, and if new, link it from both
|
||||||
`admin/docs/index.twig` and the nav in `admin/docs/_layout/layout.twig`.
|
`admin/docs/index.twig` and the nav in `admin/docs/_layout/layout.twig`.
|
||||||
2. Update `README.md` if it affects the feature list, getting-started
|
2. Update `App/pages/blog/novaconium-features/index.twig` (and its entry in
|
||||||
steps, or the docs index there.
|
`App/pages/blog/index.php`) if it affects the feature tour.
|
||||||
3. Update this file only if it affects a convention an agent needs to know
|
3. Update `README.md` only if it affects the one-paragraph pitch, the
|
||||||
|
minimal getting-started steps, or the Third-party section — not a
|
||||||
|
per-feature bullet.
|
||||||
|
4. Update this file only if it affects a convention an agent needs to know
|
||||||
before editing code.
|
before editing code.
|
||||||
|
|
||||||
## What this is
|
## What this is
|
||||||
|
|||||||
@@ -40,5 +40,11 @@ return [
|
|||||||
'excerpt' => 'How syntax highlighting works on this site, with worked examples in bash, HTML, CSS, YAML, Python, JavaScript, JSON, and INI/env.',
|
'excerpt' => 'How syntax highlighting works on this site, with worked examples in bash, HTML, CSS, YAML, Python, JavaScript, JSON, and INI/env.',
|
||||||
'published' => '2026-07-14',
|
'published' => '2026-07-14',
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'slug' => 'novaconium-features',
|
||||||
|
'title' => 'Novaconium Features',
|
||||||
|
'excerpt' => 'A tour of what ships with novaconium out of the box: routing, sidecars, caching, admin auth, access control, media manager, database, search, RSS, and more.',
|
||||||
|
'published' => '2026-07-15',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
{% extends layout %}
|
||||||
|
|
||||||
|
{% import '_layout/icons.twig' as icons %}
|
||||||
|
|
||||||
|
{% block title %}Novaconium Features{% endblock %}
|
||||||
|
{% block description %}A tour of what ships with novaconium out of the box: routing, sidecars, caching, admin auth, access control, media manager, database, search, RSS, and more.{% endblock %}
|
||||||
|
|
||||||
|
{% block robots %}index, follow{% endblock %}
|
||||||
|
{% block tags %}features, meta{% endblock %}
|
||||||
|
{% block canonical %}{{ request_path|default('/') }}{% endblock %}
|
||||||
|
|
||||||
|
{% block og_type %}article{% endblock %}
|
||||||
|
{% block og_title %}{{ block('title') }}{% endblock %}
|
||||||
|
{% block og_description %}{{ block('description') }}{% endblock %}
|
||||||
|
{% block og_url %}{{ block('canonical') }}{% endblock %}
|
||||||
|
|
||||||
|
{% block twitter_card %}summary{% endblock %}
|
||||||
|
{% block twitter_title %}{{ block('title') }}{% endblock %}
|
||||||
|
{% block twitter_description %}{{ block('description') }}{% endblock %}
|
||||||
|
|
||||||
|
{% block blog_content %}
|
||||||
|
<h1>Novaconium Features</h1>
|
||||||
|
|
||||||
|
<p>A tour of what ships with novaconium out of the box. Every topic below has a full writeup at <a class="icon-link" href="/admin/docs">{{ icons.book() }}/admin/docs</a> on any running instance — this post is the overview.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong>File-based routing</strong> — a directory under <code>App/pages/</code> <em>is</em> a route (Hugo-style page bundles). No route table to maintain.</li>
|
||||||
|
<li><strong><code>[param]</code> segments</strong> — a directory literally named <code>[param]</code> (e.g. <code>App/pages/products/[id]/</code>) captures any single URL segment into <code>$params['param']</code> for clean URLs, no query strings.</li>
|
||||||
|
<li><strong>Optional PHP "sidecars"</strong> — drop an <code>index.php</code> next to any <code>index.twig</code> to supply Twig context data, or return a <code>Response</code> (redirect/JSON/XML/HTML) to short-circuit templating entirely.</li>
|
||||||
|
<li><strong>Static caching, zero config</strong> — sidecar-less pages render once and are written to <code>public/cache/</code>; <code>.htaccess</code> serves the cached file directly on every later hit, skipping PHP and Twig entirely.</li>
|
||||||
|
<li><strong>Override-by-path</strong> — <code>App/</code> (your project) is checked before <code>novaconium/</code> (the framework defaults) for every page, layout, <code>Lib\</code> class, and even the Sass color palette (<code>App/sass/_colors.sass</code>). Drop a file at the same relative path to override it; nothing needs duplicating to get a working site.</li>
|
||||||
|
<li><strong>Layout inheritance</strong> — <code>_layout/layout.twig</code> directories are resolved by walking upward from the matched page, so you can override the layout for a whole subtree.</li>
|
||||||
|
<li><strong>SEO boilerplate out of the box</strong> — the default layout ships meta description, canonical link, robots, Open Graph, and Twitter Card tags, all overridable per-page via Twig blocks.</li>
|
||||||
|
<li><strong>Built-in Matomo analytics</strong> — set <code>matomo_url</code> and <code>matomo_site_id</code> in <code>App/config.php</code> to enable tracking site-wide, including automatic 404 tracking. Off by default.</li>
|
||||||
|
<li><strong>Admin authentication</strong> — gate every <code>/admin/*</code> route behind a session login with multi-user management: a SQLite-backed <code>users</code> table, <code>/admin/login</code>/<code>/admin/logout</code>, and an <code>/admin/users</code> page to create, disable, delete, group, promote/demote, and change the email or password of accounts (plus a <code>novaconium/bin/create-admin-user.php</code> CLI for the first user or deploy scripts). Two roles: the first user created is the admin; everyone after is a registered user with an optional group. Enabled with a single <code>admin_auth_enabled</code> flag in <code>App/config.php</code>; off by default.</li>
|
||||||
|
<li><strong>Access control</strong> — assign a page (or a section, one line per page) to a user or group from its sidecar: <code>Access::require('group:members')</code> returns <code>null</code> or a ready-made <code>Response</code> (login redirect with a return path, or a 404 for the wrong account). Public is the default — a sidecar that never calls it is untouched, and static (sidecar-less, cached) pages are always public by construction.</li>
|
||||||
|
<li><strong>Draft pages</strong> — list a route under <code>draft_routes</code> in <code>App/config.php</code> to make it visible only to an authenticated admin; anyone else gets a plain 404, not a login prompt.</li>
|
||||||
|
<li><strong>Media manager</strong> — <code>/admin/media</code>, an upload/browse/delete UI for files under <code>public/uploads/</code>, covered by the existing <code>/admin/*</code> auth gate with no separate flag needed. Extension allowlist and max upload size are configurable.</li>
|
||||||
|
<li><strong>Dark/light theme toggle</strong> — a nav button flips a <code>data-theme</code> attribute (persisted to <code>localStorage</code>) that swaps every color via CSS custom properties.</li>
|
||||||
|
<li><strong>Self-hosted spam prevention & form validation</strong> — <code>Lib\SpamGuard</code> (honeypot + submission-timing check, no external CAPTCHA), <code>Lib\FormValidator</code>, and <code>Lib\Validate</code>, demonstrated on the contact form.</li>
|
||||||
|
<li><strong>Form security by default</strong> — <code>Lib\Input</code> (cleaning accessor for <code>$_POST</code>/<code>$_GET</code>) and <code>Lib\Csrf</code> (standalone session-token CSRF protection), wired into the contact form and every admin form.</li>
|
||||||
|
<li><strong>SQLite/MySQL database, zero setup</strong> — <code>Lib\Db</code>, a thin PDO wrapper (no ORM) supporting multiple named connections open at once, each with its own plain-SQL migration convention, applied automatically on first use or via <code>php novaconium/bin/migrate.php</code>.</li>
|
||||||
|
<li><strong>Sessions with flash data</strong> — <code>Lib\Session</code>, a thin wrapper around native PHP sessions with CodeIgniter-style flash values for post/redirect/GET flows.</li>
|
||||||
|
<li><strong>Content index: sitemap, search, tags</strong> — <code>/sitemap.xml</code>, full-text <code>/search</code> (SQLite FTS5), and blog tag browsing all share one crawler. Off by default; reindexes lazily on demand or via <code>php novaconium/bin/index-content.php</code>.</li>
|
||||||
|
<li><strong>Blog RSS feed</strong> — <code>/blog/feed</code>, built from the same hand-written post list <code>App/pages/blog/index.php</code> itself renders from, so it works with no database at all.</li>
|
||||||
|
<li><strong>Syntax-highlighted code blocks</strong> — vendored <a href="https://highlightjs.org/">highlight.js</a> colors PHP/Bash/HTML code blocks site-wide, auto-detected with no per-block markup.</li>
|
||||||
|
<li><strong>No build step, no Composer</strong> — clone it, point Apache (or <code>php -S</code>) at <code>public/</code>, and it runs. Twig is vendored as source.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Full details on every one of these live at <a class="icon-link" href="/admin/docs">{{ icons.book() }}/admin/docs</a>, rendered live from this same running instance — routing, sidecars, libraries, database, session, content index, XML sitemap, RSS feeds, layouts, static caching, SEO, Matomo, admin authentication, access control, draft pages, media manager, styling, project layout, and third-party notices.</p>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,133 +1,34 @@
|
|||||||
|
```
|
||||||
|
_ __ _____ ____ _ ___ ___ _ __ (_)_ _ _ __ ___
|
||||||
|
| '_ \ / _ \ \ / / _` |/ __/ _ \| '_ \| | | | | '_ ` _ \
|
||||||
|
| | | | (_) \ V / (_| | (_| (_) | | | | | |_| | | | | | |
|
||||||
|
|_| |_|\___/ \_/ \__,_|\___\___/|_| |_|_|\__,_|_| |_| |_|
|
||||||
|
```
|
||||||
|
|
||||||
# novaconium
|
# novaconium
|
||||||
|
|
||||||
A tiny, Hugo-flavored PHP micro-framework. Routes are directories on disk, pages render with [Twig](https://twig.symfony.com/), and any page that needs real logic gets an optional PHP "sidecar" file. Pages without a sidecar are pre-rendered once and served as static HTML straight from Apache afterwards. No Composer — Twig is vendored directly into the repo as plain source files.
|
A tiny, Hugo-flavored PHP micro-framework. Routes are directories on disk, pages render with [Twig](https://twig.symfony.com/), and any page that needs real logic gets an optional PHP "sidecar" file. Pages without a sidecar are pre-rendered once and served as static HTML straight from Apache afterwards. No Composer — Twig is vendored directly into the repo as plain source files.
|
||||||
|
|
||||||
## Features
|
For a full tour of what's included — routing, sidecars, caching, admin auth, access control, media manager, database, search, RSS, and more — see the [Novaconium Features](http://127.0.0.1:8000/blog/novaconium-features) post once the site is running, or `/admin/docs` (see Documentation below).
|
||||||
|
|
||||||
- **File-based routing** — a directory under `App/pages/` *is* a route (Hugo-style page bundles). No route table to maintain.
|
|
||||||
- **`[param]` segments** — a directory literally named `[param]` (e.g. `App/pages/products/[id]/`) captures any single URL segment into `$params['param']` for clean URLs, no query strings.
|
|
||||||
- **Optional PHP "sidecars"** — drop an `index.php` next to any `index.twig` to supply Twig context data, or return a `Response` (redirect/JSON/XML/HTML) to short-circuit templating entirely.
|
|
||||||
- **Static caching, zero config** — sidecar-less pages render once and are written to `public/cache/`; `.htaccess` serves the cached file directly on every later hit, skipping PHP and Twig entirely.
|
|
||||||
- **Override-by-path** — `App/` (your project) is checked before `novaconium/` (the framework defaults) for every page, layout, `Lib\` class, and even the Sass color palette (`App/sass/_colors.sass`). Drop a file at the same relative path to override it; nothing needs duplicating to get a working site.
|
|
||||||
- **Layout inheritance** — `_layout/layout.twig` directories are resolved by walking upward from the matched page, so you can override the layout for a whole subtree.
|
|
||||||
- **SEO boilerplate out of the box** — the default layout ships meta description, canonical link, robots, Open Graph, and Twitter Card tags, all overridable per-page via Twig blocks.
|
|
||||||
- **Built-in Matomo analytics** — set `matomo_url` and `matomo_site_id` in `App/config.php` to enable tracking site-wide, including automatic 404 tracking. Off by default.
|
|
||||||
- **Admin authentication** — gate every `/admin/*` route behind a session login with multi-user management: a SQLite-backed `users` table, `/admin/login`/`/admin/logout`, and an `/admin/users` page to create, disable, delete, group, promote/demote, and change the email or password of accounts (plus a `novaconium/bin/create-admin-user.php` CLI for the first user or deploy scripts). Two roles: the first user created is the admin; everyone after is a registered user with an optional group. Every account has a unique, normalized email address — groundwork for email verification later. Enabled with a single `admin_auth_enabled` flag in `App/config.php`; off by default, and reusable for any admin page a project adds later.
|
|
||||||
- **Access control** — assign a page (or a section, one line per page) to a user or group from its sidecar: `Access::require('group:members')` returns `null` or a ready-made `Response` (login redirect with a return path, or a 404 for the wrong account). Public is the default — a sidecar that never calls it is untouched, and static (sidecar-less, cached) pages are always public by construction. Gated pages stay out of `/search` and `/sitemap.xml` automatically.
|
|
||||||
- **Draft pages** — list a route under `draft_routes` in `App/config.php` to make it visible only to an authenticated admin; anyone else gets a plain 404, not a login prompt. Reuses the admin auth check directly, and is excluded from static caching so a cached copy can't leak the draft to the public. See `/admin/docs/drafts`.
|
|
||||||
- **Media manager** — `/admin/media`, an upload/browse/delete UI for files under `public/uploads/`, covered by the existing `/admin/*` auth gate with no separate flag needed. Extension allowlist and max upload size are configurable (`media_upload_extensions`/`media_upload_max_bytes` in `App/config.php`), filenames are sanitized and de-duplicated on upload, and deletes are re-verified to resolve inside the upload directory before touching disk. See `/admin/docs/media-manager`.
|
|
||||||
- **Dark/light theme toggle** — a nav button flips a `data-theme` attribute (persisted to `localStorage`) that swaps every color via CSS custom properties; both palettes live in `App/sass/_colors.sass`, same override mechanism as everything else.
|
|
||||||
- **Self-hosted spam prevention & form validation** — `Lib\SpamGuard`, a reusable class for any form: a CSS-hidden honeypot field plus a submission-timing check, no external CAPTCHA service, site key, or outbound API call. Pairs with `Lib\FormValidator` (accumulating required-field/email/length checks) and `Lib\Validate` (the underlying validation primitives — email, length, phone, postal/zip, spam-word checks). All three ship in `novaconium/lib/`, demonstrated on the contact form.
|
|
||||||
- **Form security by default** — `Lib\Input`, a cleaning accessor for `$_POST`/`$_GET` (defense-in-depth against HTML/script injection, not a substitute for parameterized queries), and `Lib\Csrf`, standalone session-token CSRF protection called directly from a sidecar. Both ship in `novaconium/lib/`, wired into the contact form, `/admin/clear-cache`, `/admin/login`, and `/admin/users`.
|
|
||||||
- **SQLite/MySQL database, zero setup** — `Lib\Db`, a thin PDO wrapper (no ORM) supporting multiple named connections open at once — e.g. this site's own SQLite data plus a MySQL connection to a legacy database, usable in the same sidecar — each with its own plain-SQL migration convention, applied automatically on first use or via `php novaconium/bin/migrate.php`. SQLite data lives in a project-owned top-level `data/` directory, outside both `public/` and `novaconium/`. See `/admin/docs/database`.
|
|
||||||
- **Sessions with flash data** — `Lib\Session`, a thin wrapper around native PHP sessions with CodeIgniter-style flash values (set now, readable on exactly the next request) for post/redirect/GET flows without a query-string flag. Lazy-start, same mechanism `Lib\Csrf` already uses. See `/admin/docs/session`.
|
|
||||||
- **Content index: sitemap, search, tags** — `/sitemap.xml`, full-text `/search` (SQLite FTS5), and blog tag browsing all share one crawler that renders every page and harvests `keywords`/`tags`/`changefreq`/`priority` Twig blocks via Twig's own `renderBlock()` — no front-matter, no separate metadata files. Off by default (depends on SQLite); reindexes lazily on demand or via `php novaconium/bin/index-content.php`. See `/admin/docs/content-index`.
|
|
||||||
- **Blog RSS feed** — `/blog/feed`, built from the same hand-written post list `App/pages/blog/index.php` itself renders from, so it works with no database at all. `Lib\Rss` (a small RSS 2.0 envelope builder) also backs a per-tag feed, `/blog/tag/<tag>/feed`, once the content index above is enabled. Auto-discovered via a `<link rel="alternate">` on `/blog/*` pages.
|
|
||||||
- **Syntax-highlighted code blocks** — vendored [highlight.js](https://highlightjs.org/) colors PHP/Bash/HTML code blocks site-wide, auto-detected with no per-block markup, swapping between dark (`ir-black`) and light (`github`) themes along with the existing dark/light toggle. Twig-syntax samples (which highlight.js can't parse) are left plain rather than colored wrong. See `/admin/docs/upgrading-highlightjs`.
|
|
||||||
- **No build step, no Composer** — clone it, point Apache (or `php -S`) at `public/`, and it runs. Twig is vendored as source; see `/admin/docs/upgrading-twig` for upgrading it.
|
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
**Requirements:** PHP 8.1+ (uses `readonly` constructor-promoted properties) with the `pdo_sqlite` extension (bundled with PHP, just needs to be enabled — no separate install; add `pdo_mysql` too if using a MySQL connection), and, for production, Apache with `mod_rewrite` and `AllowOverride All`. The content index's search (`/admin/docs/content-index`) additionally needs SQLite's FTS5 extension, bundled with `pdo_sqlite` on virtually every modern PHP build — only relevant if `content_index_enabled` is turned on.
|
**Requirements:** PHP 8.1+ (uses `readonly` constructor-promoted properties) and, for production, Apache with `mod_rewrite` and `AllowOverride All`. A few optional features (database, content index/search, admin authentication) need the `pdo_sqlite` extension — see `/admin/docs` for details once running.
|
||||||
|
|
||||||
### Run it locally (no Apache needed)
|
Run it locally, no Apache needed:
|
||||||
|
|
||||||
```
|
```
|
||||||
php -S 127.0.0.1:8000 -t public public/router.php
|
php -S 127.0.0.1:8000 -t public public/router.php
|
||||||
```
|
```
|
||||||
|
|
||||||
`public/router.php` is a dev-only script that mimics the `.htaccess` rules (canonical redirects + static cache lookup) so you can develop without Apache. It is never used in production — Apache reads `public/.htaccess` directly.
|
Visit `http://127.0.0.1:8000/` — click around the example pages, then open `http://127.0.0.1:8000/admin/docs` for the complete documentation, rendered live from this same instance.
|
||||||
|
|
||||||
Visit `http://127.0.0.1:8000/` for the static home page, then click around — `/about`, `/blog/hello-world`, `/contact`, and `/admin` (cache clearing + these same docs, rendered live) are all included as working examples.
|
|
||||||
|
|
||||||
### Deploy on Apache
|
|
||||||
|
|
||||||
Point the vhost's document root at `public/`, make sure `mod_rewrite` is enabled and `AllowOverride All` is set for that directory so `public/.htaccess` takes effect, and it just works — no build step required.
|
|
||||||
|
|
||||||
### Run it in Docker
|
|
||||||
|
|
||||||
```
|
|
||||||
docker compose up --build
|
|
||||||
```
|
|
||||||
|
|
||||||
Builds an Arch Linux-based Apache/PHP image and serves the site at `http://localhost:8080/`. Three named volumes (`cache`, `uploads`, `data`) keep the page cache, media manager uploads, and SQLite database out of paths the "Updating the framework" workflow below would wipe; `App/` is baked into the image but can be bind-mounted for edits without a rebuild. See [Docker](http://127.0.0.1:8000/admin/docs/docker) for details.
|
|
||||||
|
|
||||||
### Starting a new project
|
|
||||||
|
|
||||||
Clone this repo and drop its Git history — no Composer scaffold or installer:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone --depth 1 <novaconium-repo-url> my-new-project
|
|
||||||
cd my-new-project
|
|
||||||
rm -rf .git && git init && git add -A && git commit -m "Initial commit from novaconium template"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then replace the example content under `App/pages/` with your own; leave `novaconium/` and `public/` alone.
|
|
||||||
|
|
||||||
### Updating the framework
|
|
||||||
|
|
||||||
Since the framework core lives entirely under `novaconium/`, pick up a new release by overwriting just that directory against a tag and committing the diff:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone --depth 1 --branch <release-tag> <novaconium-repo-url> /tmp/nova-update
|
|
||||||
rm -rf novaconium && cp -r /tmp/nova-update/novaconium ./novaconium && rm -rf /tmp/nova-update
|
|
||||||
git add novaconium && git commit -m "Update novaconium framework to <release-tag>"
|
|
||||||
```
|
|
||||||
|
|
||||||
Safe by construction — `App/` always overrides `novaconium/`, so an update can't clobber project customizations. See [Getting started](http://127.0.0.1:8000/admin/docs/getting-started) for the full write-up.
|
|
||||||
|
|
||||||
### Add a page
|
|
||||||
|
|
||||||
Create a directory under `App/pages/` with an `index.twig` — the directory path *is* the URL:
|
|
||||||
|
|
||||||
```
|
|
||||||
App/pages/pricing/index.twig -> /pricing
|
|
||||||
```
|
|
||||||
|
|
||||||
Add an `index.php` next to it if the page needs data or logic. See [Sidecars](http://127.0.0.1:8000/admin/docs/sidecars) in the docs for the full contract, or [SEO](http://127.0.0.1:8000/admin/docs/seo) for a ready-to-paste starter template with every overridable block — or skip the copy-paste and scaffold it:
|
|
||||||
|
|
||||||
```
|
|
||||||
php novaconium/bin/create-static-page.php blog/my-new-post
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
The full framework documentation — routing, sidecars, libraries, database, session, content index, XML sitemap, RSS feeds, layouts, static caching, SEO, Matomo analytics, admin authentication, draft pages, styling, project layout, and third-party notices — lives at `/admin/docs` on any running instance (so it travels with the code, no internet connection needed). Highlights:
|
The full framework documentation lives inside the framework itself, at `/admin/docs` on any running instance — so it travels with the code, no internet connection needed. That's the canonical reference for everything: requirements, running locally, deploying on Apache or Docker, starting a new project, updating the framework, adding a page, routing, sidecars, libraries, database, session, content index, XML sitemap, RSS feeds, layouts, static caching, SEO, Matomo analytics, admin authentication, access control, draft pages, media manager, styling, and project layout.
|
||||||
|
|
||||||
- [Getting started](http://127.0.0.1:8000/admin/docs/getting-started)
|
|
||||||
- [Docker](http://127.0.0.1:8000/admin/docs/docker)
|
|
||||||
- [Routing](http://127.0.0.1:8000/admin/docs/routing)
|
|
||||||
- [Sidecars](http://127.0.0.1:8000/admin/docs/sidecars)
|
|
||||||
- [Libraries](http://127.0.0.1:8000/admin/docs/libraries)
|
|
||||||
- [Database](http://127.0.0.1:8000/admin/docs/database)
|
|
||||||
- [Session](http://127.0.0.1:8000/admin/docs/session)
|
|
||||||
- [Content index](http://127.0.0.1:8000/admin/docs/content-index)
|
|
||||||
- [XML sitemap](http://127.0.0.1:8000/admin/docs/sitemap)
|
|
||||||
- [RSS feeds](http://127.0.0.1:8000/admin/docs/rss)
|
|
||||||
- [Layouts](http://127.0.0.1:8000/admin/docs/layouts)
|
|
||||||
- [Static caching](http://127.0.0.1:8000/admin/docs/caching)
|
|
||||||
- [SEO](http://127.0.0.1:8000/admin/docs/seo)
|
|
||||||
- [Matomo](http://127.0.0.1:8000/admin/docs/matomo)
|
|
||||||
- [Admin authentication](http://127.0.0.1:8000/admin/docs/admin-auth)
|
|
||||||
- [Access control](http://127.0.0.1:8000/admin/docs/access-control)
|
|
||||||
- [Draft pages](http://127.0.0.1:8000/admin/docs/drafts)
|
|
||||||
- [Media manager](http://127.0.0.1:8000/admin/docs/media-manager)
|
|
||||||
- [Styling](http://127.0.0.1:8000/admin/docs/styling)
|
|
||||||
- [Project layout](http://127.0.0.1:8000/admin/docs/project-layout)
|
|
||||||
- [Third-party](http://127.0.0.1:8000/admin/docs/third-party)
|
|
||||||
|
|
||||||
`AGENTS.md` is the short, agent-facing version for coding assistants working in this repo, and `novaconium/ISSUES.md` is the roadmap/backlog.
|
`AGENTS.md` is the short, agent-facing version for coding assistants working in this repo, and `novaconium/ISSUES.md` is the roadmap/backlog.
|
||||||
|
|
||||||
## Project layout
|
|
||||||
|
|
||||||
```
|
|
||||||
App/ your project — pages/ (routes), lib/ (Lib\ classes), sass/ (color overrides) — the only directory you're expected to edit
|
|
||||||
public/ Apache document root — front controller, .htaccess, static cache, compiled CSS
|
|
||||||
novaconium/ the framework itself — router, renderer, vendored Twig, default pages/lib/sass — not edited per-project
|
|
||||||
```
|
|
||||||
|
|
||||||
See [Project layout](http://127.0.0.1:8000/admin/docs/project-layout) for the full tree with every file explained.
|
|
||||||
|
|
||||||
## Third-party
|
## Third-party
|
||||||
|
|
||||||
[Twig](https://twig.symfony.com/) is vendored in source form under `novaconium/vendor/twig/` (no Composer — see `/admin/docs/upgrading-twig` for how to upgrade it). It's BSD-3-Clause licensed; the full license text ships alongside it at `novaconium/vendor/twig/LICENSE`.
|
[Twig](https://twig.symfony.com/) is vendored in source form under `novaconium/vendor/twig/` (no Composer — see `/admin/docs/upgrading-twig` for how to upgrade it). It's BSD-3-Clause licensed; the full license text ships alongside it at `novaconium/vendor/twig/LICENSE`.
|
||||||
|
|||||||
Reference in New Issue
Block a user