From 642f654a85f85822bb2f5893c6cfdd04f4a1e47c Mon Sep 17 00:00:00 2001 From: Nick Yeoman Date: Wed, 30 Sep 2026 16:04:27 +0000 Subject: [PATCH] fixed company name --- App/config.php | 1 + novaconium/bootstrap.php | 2 +- novaconium/config.php | 10 ++++++++++ novaconium/pages/admin/docs/config/index.twig | 16 +++++++++++++++- novaconium/pages/admin/docs/sidecars/index.twig | 4 ++-- novaconium/src/ContentIndexer.php | 2 +- novaconium/src/Renderer.php | 9 +++++++++ 7 files changed, 39 insertions(+), 5 deletions(-) diff --git a/App/config.php b/App/config.php index d173efc..ddaf8b0 100644 --- a/App/config.php +++ b/App/config.php @@ -10,6 +10,7 @@ return [ // 'debug' => false, // 'site_name' => 'My Site', + // 'twig_globals' => ['company_name' => 'My Company'], // Docs: /admin/docs/matomo // 'matomo_url' => 'https://matomo.example.com/', diff --git a/novaconium/bootstrap.php b/novaconium/bootstrap.php index 76225c5..b2f01a5 100644 --- a/novaconium/bootstrap.php +++ b/novaconium/bootstrap.php @@ -62,7 +62,7 @@ if ($config['debug']) { $cache->clear(); } -$renderer = new Renderer($config['pages_dirs'], $cache, $adminAuthEnabled, $matomoUrl, $config['matomo_site_id'], $config['site_name'], $config['content_index_enabled'], $config['debug']); +$renderer = new Renderer($config['pages_dirs'], $cache, $adminAuthEnabled, $matomoUrl, $config['matomo_site_id'], $config['site_name'], $config['content_index_enabled'], $config['debug'], $config['twig_globals'] ?? []); // Every route under /admin/* — clear-cache, docs, users, and any admin // page a project adds later — is gated here, once, rather than in each diff --git a/novaconium/config.php b/novaconium/config.php index 7f0580e..4ac714a 100644 --- a/novaconium/config.php +++ b/novaconium/config.php @@ -20,6 +20,16 @@ return [ // footer copyright line in novaconium/pages/_layout/layout.twig. 'site_name' => 'Novaconium Website', + // Extra project-specific values exposed to every Twig template as + // globals, e.g. 'twig_globals' => ['company_name' => 'Acme Ltd.'] makes + // {{ company_name }} available everywhere. Only keys listed here reach + // Twig — the rest of this config (API secrets, DB paths) never does. A + // key that collides with a framework global (site_name, matomo_url, + // matomo_site_id, admin_auth_enabled, content_index_enabled, is_404) + // is ignored; set those through their own config keys instead. See + // /admin/docs/config. + 'twig_globals' => [], + // Matomo analytics. Leave both empty (the default) to disable tracking // entirely — the layout emits no tracking script at all in that case. // Set both via App/config.php to enable, e.g.: diff --git a/novaconium/pages/admin/docs/config/index.twig b/novaconium/pages/admin/docs/config/index.twig index 2cc338e..8155e80 100644 --- a/novaconium/pages/admin/docs/config/index.twig +++ b/novaconium/pages/admin/docs/config/index.twig @@ -10,7 +10,7 @@ {% block docs_content %}

Configuration

-

novaconium/config.php holds the framework defaults — pages_dirs, cache_dir, debug, site_name, matomo_url, matomo_site_id, admin_auth_enabled, db_connections, draft_routes — and is not meant to be edited per-project, same as everything else under novaconium/.

+

novaconium/config.php holds the framework defaults — pages_dirs, cache_dir, debug, site_name, matomo_url, matomo_site_id, admin_auth_enabled, db_connections, draft_routes, twig_globals — and is not meant to be edited per-project, same as everything else under novaconium/.

App/config.php ships with the skeleton as an empty, commented placeholder — uncomment (or add) whichever keys you want to change, returning an array of just those:

@@ -54,6 +54,20 @@ return [

See SEO for the full list of overridable meta blocks. Pages that were already statically cached before this changes need php novaconium/bin/clear-cache.php to pick it up.

+

Custom template globals

+ +

twig_globals (default []) is how a project makes its own values available in every template. Any key you add to App/config.php is not visible to Twig on its own — only the framework's fixed globals (site_name, matomo_url, matomo_site_id, admin_auth_enabled, content_index_enabled, is_404) are. List anything else under twig_globals:

+ +
<?php
+// App/config.php
+return [
+    'twig_globals' => [
+        'company_name' => 'Acme Ltd.',
+    ],
+];
+ +

Every template, layout, and sidecar-rendered page can then use {% verbatim %}{{ company_name }}{% endverbatim %}. The whole config array is deliberately not exposed, since it holds secrets such as mailjet_api_secret. A key that collides with a framework global is ignored — set site_name and the rest through their own config keys. As with site_name, already-cached pages need php novaconium/bin/clear-cache.php to pick up a change.

+

Admin authentication

admin_auth_enabled (default false) gates every /admin/* route behind a session login against the users table — see Admin authentication for the full write-up, including roles (the first user is the admin; the rest are registered) and how the first user gets created. The same flag powers Access control (Lib\Access) for member/group-gated content. When left off, /admin/* is open, the login/users routes 404, and Access::require() allows everything.

diff --git a/novaconium/pages/admin/docs/sidecars/index.twig b/novaconium/pages/admin/docs/sidecars/index.twig index ad9988a..4b8a67c 100644 --- a/novaconium/pages/admin/docs/sidecars/index.twig +++ b/novaconium/pages/admin/docs/sidecars/index.twig @@ -228,7 +228,7 @@ Response::html(string $html, int $status = 200): self // type 'html', Cont

Renderer is the last thing a request touches, in novaconium/bootstrap.php: Router::resolve() produces a Route, AdminAuth optionally gates it, and then Renderer reads that same Route to actually produce output. It never talks back to Router or AdminAuth — by the time it runs, routing and auth are already decided, and its only inputs are the Route and the raw request URI:

-
$renderer = new Renderer($config['pages_dirs'], $cache, $adminAuthEnabled, $matomoUrl, $config['matomo_site_id'], $config['site_name']);
+    
$renderer = new Renderer($config['pages_dirs'], $cache, $adminAuthEnabled, $matomoUrl, $config['matomo_site_id'], $config['site_name'], $config['content_index_enabled'], $config['debug'], $config['twig_globals'] ?? []);
 
 if (!$route->found) {
     $renderer->renderNotFound($requestUri);
@@ -239,7 +239,7 @@ $renderer->render($route, $requestUri);

Constructing it

-

The first two constructor arguments are the same pagesDirs override-root list every other class here takes, plus a Cache instance (novaconium/src/Cache.php) it writes sidecar-less pages' output to. The remaining four — admin-auth-enabled flag, Matomo URL/site ID, site name — aren't used for routing or rendering logic at all; they're registered as Twig globals ($this->twig->addGlobal(...)) purely so every template can read matomo_url, site_name, etc. without a sidecar having to pass them through manually. A fifth global, is_404, defaults to false here and is overridden per-render — see below.

+

The first two constructor arguments are the same pagesDirs override-root list every other class here takes, plus a Cache instance (novaconium/src/Cache.php) it writes sidecar-less pages' output to. The remaining four — admin-auth-enabled flag, Matomo URL/site ID, site name — aren't used for routing or rendering logic at all; they're registered as Twig globals ($this->twig->addGlobal(...)) purely so every template can read matomo_url, site_name, etc. without a sidecar having to pass them through manually. A fifth global, is_404, defaults to false here and is overridden per-render — see below. The last argument, twigGlobals, carries the project's twig_globals config (see Configuration); those are registered first, so a colliding name can never replace one of the framework's own globals.

What render() actually does, in order

diff --git a/novaconium/src/ContentIndexer.php b/novaconium/src/ContentIndexer.php index 64bbce4..d8c1bbb 100644 --- a/novaconium/src/ContentIndexer.php +++ b/novaconium/src/ContentIndexer.php @@ -243,7 +243,7 @@ final class ContentIndexer */ private static function renderer(array $config): Renderer { - return new Renderer($config['pages_dirs'], new Cache($config['cache_dir'])); + return new Renderer($config['pages_dirs'], new Cache($config['cache_dir']), twigGlobals: $config['twig_globals'] ?? []); } /** diff --git a/novaconium/src/Renderer.php b/novaconium/src/Renderer.php index 80571e5..8fc7a26 100644 --- a/novaconium/src/Renderer.php +++ b/novaconium/src/Renderer.php @@ -23,6 +23,8 @@ final class Renderer /** * @param string[] $pagesDirs ordered override roots, most specific first + * @param array $twigGlobals project-defined globals from + * the twig_globals config key; framework globals take precedence */ public function __construct( private readonly array $pagesDirs, @@ -33,6 +35,7 @@ final class Renderer string $siteName = 'My Site', bool $contentIndexEnabled = false, private readonly bool $debug = false, + array $twigGlobals = [], ) { $loader = new FilesystemLoader($this->pagesDirs); // 'debug' also drives PHP error display (see bootstrap.php). When on, @@ -59,6 +62,12 @@ final class Renderer $this->twig->addExtension(new DebugExtension()); } $this->twig->addExtension(new SassExtension($this->pagesDirs)); + // Project globals go in first so the framework's own addGlobal() + // calls below overwrite any colliding name — a project can't + // accidentally clobber is_404 or matomo_url via twig_globals. + foreach ($twigGlobals as $name => $value) { + $this->twig->addGlobal((string) $name, $value); + } $this->twig->addGlobal('admin_auth_enabled', $adminAuthEnabled); $this->twig->addGlobal('matomo_url', $matomoUrl); $this->twig->addGlobal('matomo_site_id', $matomoSiteId);