Add syntax highlighting on code blocks, plus a Code Highlighting post
Colors <pre><code> blocks site-wide via vendored highlight.js v11.11.1
(pinned to that stable tag, not main, which tracks an in-progress
11.0.0-beta1), auto-detected and restricted to
configure({ languages: ['php', 'bash', 'xml', 'css', 'python',
'javascript', 'yaml', 'json', 'ini'] }) - no per-block markup needed for
the ~60 existing code blocks across the site. css/python/javascript ship
in the core bundle; yaml/json/ini (ini covers .env-style files too)
don't and are vendored as separate per-language files.
Themes swap with the existing dark/light toggle: ir-black (dark) +
github (light, resolving the entry's own open question), via the same
data-theme-driven mechanism as the main palette
(syntax-highlight-init.twig/syntax-highlight.twig, mirroring
theme-init.twig/nav.twig's split) - a MutationObserver swaps the theme
link live without touching the existing toggle button's click handler.
Twig-syntax code blocks have no highlight.js grammar and are marked
class="nohighlight" by hand (15 blocks across 9 files, found by grepping
for literal {% %}/{{ }} syntax rather than guessing) rather than
force-matched into the restricted candidate set, which would color them
wrong instead of leaving them plain.
One correction to the original backlog entry's suggested approach: it
suggested vendoring highlight.js under novaconium/vendor/ next to Twig.
That would have silently 404ed on every request - Twig is server-side
PHP, never fetched by a browser, but highlight.js's .js/.css files are,
and only public/ is web-reachable. Vendored to public/vendor/highlightjs/
instead; documented in AGENTS.md and a new upgrading-highlightjs doc,
since public/ isn't touched by the usual novaconium/-swap framework
update workflow, so a future highlight.js bump won't propagate to
existing projects automatically the way it does for everything else
under novaconium/.
Caught two real bugs via testing rather than review: hljs.highlightAll()
silently no-ops if called before the document finishes parsing rather
than deferring itself, and a bash example starting with the word "php"
auto-detects as PHP, not bash.
Also adds App/pages/blog/code-highlighting/ - a new blog post
demonstrating the feature with a verified worked example in each of the
nine languages, plus how to force a language via an explicit
language-<name> class when auto-detection isn't enough.
Closes the "Syntax highlighting on code blocks" backlog item in
novaconium/ISSUES.md.
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
<h2>Output & variables</h2>
|
||||
<p>Twig prints an expression with <code>{{ '{{ ... }}' }}</code>. Sidecar data, route params, and a handful of framework-provided variables (<code>request_path</code>, <code>layout</code>, <code>site_name</code>) are all just variables in scope:</p>
|
||||
<pre><code>{% verbatim %}{{ title }}
|
||||
<pre><code class="nohighlight">{% verbatim %}{{ title }}
|
||||
{{ params.slug }}
|
||||
{{ post.title }}{% endverbatim %}</code></pre>
|
||||
<p>Dot notation (<code>post.title</code>) works whether <code>post</code> is an array key or an object property — Twig tries both, so templates don't need to care which.</p>
|
||||
@@ -46,29 +46,29 @@
|
||||
|
||||
<h2>Control structures</h2>
|
||||
<p>The two workhorses are <code>{% verbatim %}{% if %}{% endverbatim %}</code> and <code>{% verbatim %}{% for %}{% endverbatim %}</code>:</p>
|
||||
<pre><code>{% verbatim %}{% if sent %}
|
||||
<pre><code class="nohighlight">{% verbatim %}{% if sent %}
|
||||
<p>Thanks — your message has been sent.</p>
|
||||
{% endif %}{% endverbatim %}</code></pre>
|
||||
<pre><code>{% verbatim %}{% for post in posts %}
|
||||
<pre><code class="nohighlight">{% verbatim %}{% for post in posts %}
|
||||
<li><a href="/blog/{{ post.slug }}">{{ post.title }}</a></li>
|
||||
{% endfor %}{% endverbatim %}</code></pre>
|
||||
<p>This exact loop is what renders the <a href="/blog">blog listing page</a> you probably followed a link from to get here.</p>
|
||||
|
||||
<h2>Comments</h2>
|
||||
<p>Anything between <code>{% verbatim %}{# and #}{% endverbatim %}</code> is stripped entirely from the output — unlike an HTML comment, it never reaches the browser:</p>
|
||||
<pre><code>{% verbatim %}{# Open Graph / Facebook #}{% endverbatim %}</code></pre>
|
||||
<pre><code class="nohighlight">{% verbatim %}{# Open Graph / Facebook #}{% endverbatim %}</code></pre>
|
||||
<p>That one's real — it's the comment sitting above the Open Graph block in <code>novaconium/pages/_layout/layout.twig</code>.</p>
|
||||
|
||||
<h2>Template inheritance & includes</h2>
|
||||
<p><code>{% verbatim %}{% extends %}{% endverbatim %}</code> is how every page on this site gets its <code><html></code>/<code><head></code>/nav/footer for free — a child template only fills in named <code>{% verbatim %}{% block %}{% endverbatim %}</code> slots the parent declares:</p>
|
||||
<pre><code>{% verbatim %}{% extends layout %}
|
||||
<pre><code class="nohighlight">{% verbatim %}{% extends layout %}
|
||||
|
||||
{% block title %}Blog{% endblock %}
|
||||
{% block blog_content %}
|
||||
...
|
||||
{% endblock %}{% endverbatim %}</code></pre>
|
||||
<p><code>{% verbatim %}{% include %}{% endverbatim %}</code> pulls in a whole template inline (used for <code>_layout/nav.twig</code> and <code>_layout/matomo.twig</code>), while <code>{% verbatim %}{% import %}{% endverbatim %}</code> pulls in reusable <strong>macros</strong> — parameterized snippets like the icons used throughout this page:</p>
|
||||
<pre><code>{% verbatim %}{% import '_layout/icons.twig' as icons %}
|
||||
<pre><code class="nohighlight">{% verbatim %}{% import '_layout/icons.twig' as icons %}
|
||||
{{ icons.book() }}{% endverbatim %}</code></pre>
|
||||
<p>See <a class="icon-link" href="/admin/docs/layouts">{{ icons.book() }}Layouts</a> for how <code>{% verbatim %}{% extends %}{% endverbatim %}</code> resolution walks the <code>App/</code>-over-<code>novaconium/</code> override chain.</p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user