Sidecar-less page bundles whose directory ends in a MediaType extension
(.txt/.css/.xml/.json/.js) now render raw (no HTML layout, autoescape off),
are served with that extension's Content-Type, and cache as a flat file
(public/cache/<path>) so Apache serves them directly via a new .htaccess
rule. They're excluded from the content index.
CSS becomes one of these: novaconium/pages/css/main.css/ holds index.twig
({{ sass('main.sass') }}), main.sass, and _colors.sass. App\SassExtension's
sass() Twig function resolves the entry file through the overlay and shells
out to Dart Sass on a cache miss; Lib\SassCompiler wraps the CLI. This
drops the committed App/css/main.css build artifact and the public/css
bind mount. Override styling by copying the whole bundle to App/pages/.
Also ship robots.txt and humans.txt as framework bundles, and drop the
php -S dev router (public/router.php) - Docker/Apache only now.
New: novaconium/src/MediaType.php, SassExtension.php, lib/SassCompiler.php.
Moved: novaconium/sass/ -> novaconium/pages/css/main.css/ (+ App/sass merged).
Docs: AGENTS.md, new /admin/docs/text-pages, and styling/caching/docker/
design-notes/getting-started/project-layout/config docs updated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Q9cAXC9xcXYnmP7qjsnw7
60 lines
4.6 KiB
Twig
60 lines
4.6 KiB
Twig
{% extends 'admin/docs/_layout/layout.twig' %}
|
|
|
|
{% block title %}Getting started{% endblock %}
|
|
|
|
{% block description %}Requirements, running locally, and deploying on Apache.{% endblock %}
|
|
|
|
{% block robots %}noindex, nofollow{% endblock %}
|
|
|
|
{% block docs_content %}
|
|
<h1>Getting started</h1>
|
|
|
|
<p><strong>Requirements:</strong> PHP 8.1+ (uses <code>readonly</code> constructor-promoted properties), Apache with <code>mod_rewrite</code> and <code>AllowOverride All</code>, and Dart Sass on <code>PATH</code> (the <code>/css/main.css</code> route compiles Sass on demand — see <a href="/admin/docs/styling">Styling</a>). All three are already set up in the Docker image, which is the only supported way to run Novaconium. The <a href="/admin/docs/database">Database</a>/<a href="/admin/docs/content-index">Content index</a>/<a href="/admin/docs/admin-auth">Admin authentication</a> features are optional and off by default — see <a href="/admin/docs">Overview</a> for the extensions they need (<code>pdo_sqlite</code>, optionally <code>pdo_mysql</code>/FTS5) if you turn them on.</p>
|
|
|
|
<h2>Run it</h2>
|
|
|
|
<pre><code>docker compose up</code></pre>
|
|
|
|
<p>The image (built from the repo <code>Dockerfile</code>) bundles Apache + <code>public/.htaccess</code>, PHP, and Dart Sass; <code>docker-compose.yml</code> bind-mounts <code>App/</code>, <code>public/cache/</code>, <code>public/uploads/</code>, and <code>data/</code> from the host. Then open <code>http://localhost:8080/</code>. See <a href="/admin/docs/docker">Docker</a> for the image/volume details and the plain <code>docker run</code> form.</p>
|
|
|
|
<h2>Deploy</h2>
|
|
|
|
<p>Run the same image behind your reverse proxy / on your host. If you deploy without Docker instead, point the vhost's document root at <code>public/</code>, enable <code>mod_rewrite</code>, set <code>AllowOverride All</code> so <code>public/.htaccess</code> takes effect, and make sure the <code>sass</code> binary is installed — no build step is required.</p>
|
|
|
|
<h2>Starting a new project</h2>
|
|
|
|
<p>Clone this repo and drop its Git history — that's it, there's no Composer scaffold or installer:</p>
|
|
|
|
<pre><code>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"</code></pre>
|
|
|
|
<p>Then replace the example content that ships under <code>App/pages/</code> (the <code>about</code>/<code>blog</code>/<code>contact</code> sample pages) with your own pages, lib classes, and config. Leave <code>novaconium/</code> and <code>public/</code> as-is.</p>
|
|
|
|
<h2>Updating the framework</h2>
|
|
|
|
<p>Because the framework core lives entirely under <code>novaconium/</code> — separate from your project's <code>App/</code> — picking up a new release is a matter of overwriting that one directory and committing the diff:</p>
|
|
|
|
<pre><code>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>"</code></pre>
|
|
|
|
<p>This is safe by construction: the override-by-path design means <code>App/</code> always wins over <code>novaconium/</code> for pages, lib classes, and Sass colors (see <a href="/admin/docs/project-layout">Project layout</a>), so an update can't clobber your project's customizations. Diff before committing to see what changed, and run <code>php novaconium/bin/clear-cache.php</code> afterward since a framework update can change rendered output.</p>
|
|
|
|
<h2>Adding a new page</h2>
|
|
|
|
<p>Create a directory under <code>App/pages/</code> with an <code>index.twig</code> — the directory path <em>is</em> the URL (see <a href="/admin/docs/routing">Routing</a>). <a href="/admin/docs/seo">SEO</a> has a ready-to-paste starter template with every overridable block (title, description, Open Graph, Twitter Card) plus a content stub — copy it in and fill in the blanks.</p>
|
|
|
|
<p>Or skip the copy-paste entirely:</p>
|
|
|
|
<pre><code>php novaconium/bin/create-static-page.php blog/my-new-post</code></pre>
|
|
|
|
<p>Scaffolds <code>App/pages/blog/my-new-post/index.twig</code> from that same starter template, with the title pre-filled from the last path segment ("my-new-post" → "My New Post"). The path can be given with or without a trailing <code>.twig</code> or <code>/index.twig</code> — refuses to run if the page already exists, or if any segment is reserved (starts with <code>_</code>, or is literally <code>404</code> — see <a href="/admin/docs/routing">Routing</a>).</p>
|
|
{% endblock %}
|