Files
novaconium/novaconium/pages/admin/docs/project-layout/index.twig
T
code b882c304b1 Replace Basic Auth with multi-user login, roles, groups, and Lib\Access
Admin login & user management (novaconium/ISSUES.md): session-based
login against a SQLite users table replaces the single-user HTTP Basic
Auth stopgap (admin_username/admin_password_hash and /admin/password-hash
are gone; one admin_auth_enabled flag, off by default with zero DB
footprint). New /admin/login, /admin/logout (POST-only, real page), and
/admin/users pages plus bin/create-admin-user.php.

First user created is the admin; everyone after is registered with a
unique normalized email and an optional group. /admin/* and drafts are
admin-only; Lib\Access gates page content from sidecars
(Access::require('group:members')) with login-redirect/404 responses —
public by default, static pages always public by construction. User
management covers disable/enable, delete, promote/demote, group, email,
and password, with last-active-admin lockout guards.

Also: Session::regenerate() against fixation, friendly missing-PDO-driver
errors in Lib\Db, docs at /admin/docs/access-control and updates across
admin-auth/drafts/sidecars/config/libraries and README/AGENTS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 00:17:54 +00:00

56 lines
5.4 KiB
Twig

{% extends 'admin/docs/_layout/layout.twig' %}
{% block title %}Project layout{% endblock %}
{% block description %}A map of the whole project tree.{% endblock %}
{% block robots %}noindex, nofollow{% endblock %}
{% block docs_content %}
<h1>Project layout</h1>
<pre><code>public/ Apache document root
index.php thin front controller — just requires novaconium/bootstrap.php
.htaccess cache short-circuit, canonical redirects, rewrite to index.php
router.php dev-only helper for `php -S` (not used in production)
cache/ generated static HTML (safe to delete anytime)
css/ compiled CSS output
App/ your project — the only directory you're expected to edit
pages/ your routes — directory tree = URL tree, checked before novaconium/pages/ so you can add or override pages/layouts
lib/ your PHP classes (Lib\), checked before novaconium/lib/ so you can override defaults
sass/ your Sass overrides — _colors.sass, checked before novaconium/sass/defaults/
config.php your config overrides — ships as an empty, commented placeholder; shallow-merged over novaconium/config.php
novaconium/ the framework itself — boilerplate, not meant to be edited per-project
pages/ default pages: _layout/layout.twig (root layout) and 404/index.twig (used when App/pages/ doesn't override them)
sass/ Sass source: main.sass (structure) + defaults/_colors.sass (default palette, overridable from App/sass/)
lib/ default Lib\ classes (used when App/lib/ doesn't override them)
src/ Router, Route, Renderer, Response, Cache, Overlay (the App/-over-novaconium/ lookup used for both pages and lib)
vendor/twig/ vendored Twig source (no Composer)
bin/
clear-cache.php standalone CLI entry point — `php novaconium/bin/clear-cache.php`
create-static-page.php scaffolds a new page from the SEO starter template — `php novaconium/bin/create-static-page.php <path>`
autoload.php manual PSR-4 autoloader
config.php paths and settings
bootstrap.php wires everything together for each request</code></pre>
<h2>How a request flows through these files</h2>
<p>There's no framework "kernel" class — just a plain chain of <code>require</code>s, each handing off to the next, deliberately kept flat enough to read top-to-bottom in one sitting:</p>
<ol>
<li><strong><code>public/.htaccess</code></strong> runs first, before PHP does anything. If <code>public/cache/&lt;path&gt;/index.html</code> exists for the requested URL, Apache serves that file directly and nothing below this line ever executes — see <a href="/admin/docs/caching">Static caching</a>. Otherwise it strips a trailing slash (301 redirect) and rewrites everything else to <code>public/index.php</code>.</li>
<li><strong><code>public/index.php</code></strong> is intentionally one line: <code>require __DIR__ . '/../novaconium/bootstrap.php';</code>. (Running locally via <code>php -S</code> instead of Apache? <code>public/router.php</code> mimics the same three <code>.htaccess</code> rules in PHP, then requires <code>index.php</code> the same way — see <a href="/admin/docs/getting-started">Getting started</a>.)</li>
<li><strong><code>novaconium/bootstrap.php</code></strong> is where the real wiring happens, top-to-bottom:
<ol>
<li>Requires <strong><code>novaconium/autoload.php</code></strong>, registering the <code>Twig\</code>/<code>App\</code>/<code>Lib\</code> class autoloader (see <a href="/admin/docs/libraries">Libraries</a>) before anything below tries to instantiate a class.</li>
<li>Requires <strong><code>novaconium/config.php</code></strong>, then shallow-merges <strong><code>App/config.php</code></strong> over it if that file exists — see <a href="/admin/docs/config">Configuration</a>.</li>
<li>Constructs a <strong><code>Router</code></strong> (<code>novaconium/src/Router.php</code>) and calls <code>resolve()</code> to turn the URL into a <strong><code>Route</code></strong> (<code>novaconium/src/Route.php</code>) — see <a href="/admin/docs/routing">Routing</a>.</li>
<li>If the resolved route is under <code>admin</code>/<code>admin/*</code> (except <code>admin/login</code> itself), calls <strong><code>AdminAuth::requireLogin()</code></strong> (<code>novaconium/src/AdminAuth.php</code>), reading that same <code>Route</code>.</li>
<li>Constructs a <strong><code>Cache</code></strong> (<code>novaconium/src/Cache.php</code>) and a <strong><code>Renderer</code></strong> (<code>novaconium/src/Renderer.php</code>), then calls <code>renderNotFound()</code> or <code>render($route, ...)</code> depending on <code>$route-&gt;found</code> — see <a href="/admin/docs/sidecars">Sidecars</a> for what happens inside <code>Renderer</code> itself (running the matched directory's <code>index.php</code>, if any; resolving the nearest layout; rendering <code>index.twig</code>; writing the static cache for sidecar-less pages).</li>
</ol>
</li>
</ol>
<p>Every step after step 1 is plain PHP you can read start to finish in <code>novaconium/bootstrap.php</code> itself — the comments there walk through the same five sub-steps in more detail than this page does.</p>
{% endblock %}