mirror of
https://github.com/andwati/andwati.com.git
synced 2026-10-18 01:12:53 +00:00
Migrate templates to Zola 0.23 / Tera v2
bin/update-zola always installs the latest release, which as of
v0.23.0 rewrote the template engine to Tera v2. That broke the whole
site: removed filters (slice, concat, escape), test calls now require
named args, shortcodes are gone in favor of Tera components, and
content itself is now Tera-templated before markdown runs.
- slice(end=n) -> native [:n] slicing; concat(with=x) -> spread [...arr, x]
- escape -> escape_html; starting_with/containing -> named `pat` arg
- get_taxonomy_url `name` -> `term` (old name is deprecated)
- %+ date format no longer recognized; replaced with explicit RFC3339 pattern
- shortcodes (note/tip/warning/danger/youtube) rewritten as components;
content call sites updated to component invocation syntax
- {% include %} no longer inherits for-loop-local variables (only ambient
page/section context) - post-card.html converted to a component that
takes page/index explicitly instead of relying on implicit `page`/`loop`
- two content code blocks with literal Jinja-style {{ }} syntax (Netlify
CMS config, a Flask template snippet) wrapped in {% raw %} so Tera
doesn't try to render them, since content is now templated too
- fixed a real content corruption bug along the way: the youtube
shortcode's multi-line <iframe> tag had a conditional that could
collapse to a whitespace-only line, which prematurely closed the
HTML block under CommonMark rules and got the rest of the tag
syntax-highlighted as code instead of rendered
Verified with a clean `zola build` and `zola serve` on v0.23.1, plus a
spot-check of the rendered HTML for both callouts and the video embed.
`zola check` only reports pre-existing external link rot, unrelated to
this change.
This commit is contained in:
@@ -7,7 +7,7 @@ date = 2026-04-08
|
||||
tags = ["assembly", "rev", "pwn"]
|
||||
+++
|
||||
|
||||
{{ youtube(id="KbH239zvDtM") }}
|
||||
{{<youtube id="KbH239zvDtM" page={page} config={config} />}}
|
||||
|
||||
Before diving into how to break a program, we need to understand what the computer is actually executing. When you write a C program, the processor doesn't understand a single line of it. The C language exists for *our* benefit, allowing us to write logic without having to manually shuffle bits around in the processor.
|
||||
|
||||
@@ -78,9 +78,9 @@ In x64 Linux, when a function is called, the arguments are passed directly into
|
||||
5. `r8` (Fifth argument)
|
||||
6. `r9` (Sixth argument)
|
||||
|
||||
{% note() %}
|
||||
{% <note> %}
|
||||
In older x86 32-bit binaries, arguments aren't passed in registers at all; they are pushed onto the stack. When a function finishes and returns a value, that return value is almost always placed in the **`rax`** register (or `eax` in 32-bit).
|
||||
{% end %}
|
||||
{% </note> %}
|
||||
|
||||
### **Register Sizes and "Words"**
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ The first file, `admin/index.html`, is the entry point for the Netlify CMS admin
|
||||
Now let’s move to the configuration section. These are the configurations that go into the `config.yml` file. This process is different for every site. I followed the guidelines on the website and made minor adjustments. It worked on my website. The configuration options are available at the [docs](<https://www.netlifycms.org/docs/add-to-your-site/#:~:text=%2C%20MyTemplate)-,Configuration,-Configuration%20is%20different>). This is how I configured my config.yml file:
|
||||
|
||||
```yaml
|
||||
{% raw %}
|
||||
backend:
|
||||
name: git-gateway
|
||||
branch: netlify-cms # Branch to update (optional; defaults to master)
|
||||
@@ -104,6 +105,7 @@ collections:
|
||||
- { label: 'Categories', name: 'categories', widget: 'list' }
|
||||
- { label: 'Comments', name: 'comment', widget: 'boolean', default: true }
|
||||
- { label: 'Table of Contents', name: 'toc', widget: 'boolean', default: true }
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
**Step 5**
|
||||
|
||||
@@ -41,6 +41,7 @@ upload.html
|
||||
display.html
|
||||
|
||||
```html
|
||||
{% raw %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -60,6 +61,7 @@ display.html
|
||||
<p><a href="/">Upload another image</a></p>
|
||||
</body>
|
||||
</html>
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
`[app.py](http://app.py)`
|
||||
|
||||
+8
-8
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"version": "https://jsonfeed.org/version/1.1",
|
||||
"title": "{{ config.title | escape }}",
|
||||
"home_page_url": "{{ config.base_url | escape }}",
|
||||
"feed_url": "{{ feed_url | escape }}",
|
||||
"description": "{{ config.description | escape }}",
|
||||
"title": "{{ config.title | escape_html }}",
|
||||
"home_page_url": "{{ config.base_url | escape_html }}",
|
||||
"feed_url": "{{ feed_url | escape_html }}",
|
||||
"description": "{{ config.description | escape_html }}",
|
||||
"authors": [
|
||||
{
|
||||
"name": "{{ config.extra.author | escape }}"
|
||||
"name": "{{ config.extra.author | escape_html }}"
|
||||
}
|
||||
],
|
||||
"items": [
|
||||
{%- for page in pages %}
|
||||
{
|
||||
"id": "{{ page.permalink | escape }}",
|
||||
"url": "{{ page.permalink | escape }}",
|
||||
"title": "{{ page.title | escape }}",
|
||||
"id": "{{ page.permalink | escape_html }}",
|
||||
"url": "{{ page.permalink | escape_html }}",
|
||||
"title": "{{ page.title | escape_html }}",
|
||||
"content_html": {{ page.content | json_encode | safe }},
|
||||
"date_published": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"
|
||||
}{% if not loop.last %},{% endif %}
|
||||
|
||||
@@ -27,8 +27,8 @@ block og_url %}{{ config.base_url }}/{% endblock og_url %} {% block head %}
|
||||
"@type": "Person",
|
||||
"@id": "{{ config.base_url | safe }}/#author"
|
||||
}
|
||||
{% if page.date %},"datePublished": "{{ page.date | date(format="%+") }}"{% endif %}
|
||||
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%+") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%+") }}"{% endif %}
|
||||
{% if page.date %},"datePublished": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %}
|
||||
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
@@ -41,7 +41,7 @@ block og_url %}{{ config.base_url }}/{% endblock og_url %} {% block head %}
|
||||
|
||||
<div class="post-feed-list">
|
||||
{% set post_limit = config.extra.homepage_post_limit | default(value=3) %}
|
||||
{% for page in section.pages | slice(end=post_limit) %} {% include "partials/post-card.html" %} {% endfor %}
|
||||
{% for page in section.pages[:post_limit] %} {{<post_card page={page} index={loop.index} />}} {% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="view-all-posts">
|
||||
|
||||
+8
-8
@@ -8,12 +8,12 @@
|
||||
{% block og_title %}{{ page.title }}{% endblock og_title %}
|
||||
{% block og_description %}{{ page.description | default(value=config.description) }}{% endblock og_description %}
|
||||
{% block og_url %}{{ page.permalink }}{% endblock og_url %}
|
||||
{% block og_type %}{% if page.ancestors is containing("posts/_index.md") %}article{% else %}website{% endif %}{% endblock og_type %}
|
||||
{% block og_type %}{% if "posts/_index.md" in page.ancestors %}article{% else %}website{% endif %}{% endblock og_type %}
|
||||
{% block og_image %}{{ config.base_url }}{{ page.extra.image | default(value="/images/og-image.png") }}{% endblock og_image %}
|
||||
{% block og_extra %}
|
||||
{% if page.ancestors is containing("posts/_index.md") %}
|
||||
{% if page.date %}<meta property="article:published_time" content="{{ page.date | date(format="%+") }}">{% endif %}
|
||||
{% if page.updated %}<meta property="article:modified_time" content="{{ page.updated | date(format="%+") }}">{% endif %}
|
||||
{% if "posts/_index.md" in page.ancestors %}
|
||||
{% if page.date %}<meta property="article:published_time" content="{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}">{% endif %}
|
||||
{% if page.updated %}<meta property="article:modified_time" content="{{ page.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}">{% endif %}
|
||||
<meta property="article:author" content="{{ config.extra.author }}">
|
||||
{% if page.taxonomies.tags %}
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
@@ -29,7 +29,7 @@
|
||||
{% block twitter_image %}{{ config.base_url }}{{ page.extra.image | default(value="/images/og-image.png") }}{% endblock twitter_image %}
|
||||
|
||||
{% block head %}
|
||||
{% if page.ancestors is containing("posts/_index.md") %}
|
||||
{% if "posts/_index.md" in page.ancestors %}
|
||||
<!-- SEO: BlogPosting JSON-LD -->
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
@@ -45,8 +45,8 @@
|
||||
"image": "{{ config.base_url | safe }}{% if page.extra.image %}{{ page.extra.image | safe }}{% else %}/images/og-image.png{% endif %}",
|
||||
"url": "{{ page.permalink | safe }}",
|
||||
"inLanguage": "en-US",
|
||||
{% if page.date %}"datePublished": "{{ page.date | date(format="%+") }}",{% endif %}
|
||||
{% if page.updated %}"dateModified": "{{ page.updated | date(format="%+") }}",{% else %}{% if page.date %}"dateModified": "{{ page.date | date(format="%+") }}",{% endif %}{% endif %}
|
||||
{% if page.date %}"datePublished": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}",{% endif %}
|
||||
{% if page.updated %}"dateModified": "{{ page.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}",{% else %}{% if page.date %}"dateModified": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}",{% endif %}{% endif %}
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"@id": "{{ config.base_url | safe }}/#author",
|
||||
@@ -193,7 +193,7 @@
|
||||
<div class="post-tags">
|
||||
{% if page.taxonomies.tags %}
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
<a href="{{ get_taxonomy_url(kind="tags", name=tag) }}" class="tag">#{{ tag }}</a>
|
||||
<a href="{{ get_taxonomy_url(kind="tags", term=tag) }}" class="tag">#{{ tag }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{% if config.extra.menu %}
|
||||
{% for item in config.extra.menu %}
|
||||
{% set current = current_path | default(value="") %}
|
||||
{% set is_active = item.match and current is starting_with(item.match) %}
|
||||
{% set is_active = item.match and current is starting_with(pat=item.match) %}
|
||||
<a href="{{ get_url(path=item.url) }}" class="nav-item{% if is_active %} is-active{% endif %}"{% if is_active %} aria-current="page"{% endif %}>{{ item.name }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% component post_card(page, index) %}
|
||||
<article class="feed-item card hover-scale">
|
||||
<span class="item-index">{% if loop.index < 10 %}0{{ loop.index }}{% else %}{{ loop.index }}{% endif %}</span>
|
||||
<span class="item-index">{% if index < 10 %}0{{ index }}{% else %}{{ index }}{% endif %}</span>
|
||||
|
||||
<div class="item-body">
|
||||
<h2 class="item-title">
|
||||
@@ -28,10 +29,11 @@
|
||||
{% if page.taxonomies.tags %}
|
||||
<div class="item-tags">
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
<a href="{{ get_taxonomy_url(kind="tags", name=tag) }}" class="tag">{{ tag }}</a>
|
||||
<a href="{{ get_taxonomy_url(kind="tags", term=tag) }}" class="tag">{{ tag }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{% endcomponent post_card %}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
{% endfor %}
|
||||
|
||||
{% if has_common_tag %}
|
||||
{% set_global related_pages = related_pages | concat(with=other_page) %}
|
||||
{% set_global related_pages = [...related_pages, other_page] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -27,10 +27,8 @@
|
||||
<div class="related-posts-section">
|
||||
<h3>{{ config.extra.related_posts_title | default(value="Related Posts") }}</h3>
|
||||
<div class="related-posts-grid">
|
||||
{% for related_page in related_pages | slice(end=related_limit) %}
|
||||
{# We can use a simplified card or the existing post-card.html #}
|
||||
{% set page = related_page %}
|
||||
{% include "partials/post-card.html" %}
|
||||
{% for related_page in related_pages[:related_limit] %}
|
||||
{{<post_card page={related_page} index={loop.index} />}}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{% set_global series_pages = [] %}
|
||||
{% for p in section_data.pages %}
|
||||
{% if p.extra.series and p.extra.series == page.extra.series %}
|
||||
{% set_global series_pages = series_pages | concat(with=p) %}
|
||||
{% set_global series_pages = [...series_pages, p] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set series_sorted = series_pages | sort(attribute="extra.series_index") %}
|
||||
|
||||
@@ -36,8 +36,8 @@ og_description %}{{ config.extra.posts_page_subtitle | default(value="Exploring
|
||||
"@type": "Person",
|
||||
"@id": "{{ config.base_url | safe }}/#author"
|
||||
}
|
||||
{% if page.date %},"datePublished": "{{ page.date | date(format="%+") }}"{% endif %}
|
||||
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%+") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%+") }}"{% endif %}
|
||||
{% if page.date %},"datePublished": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %}
|
||||
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% component danger(title = "") %}
|
||||
<aside class="callout callout-danger">
|
||||
<div class="callout-header">
|
||||
<svg class="callout-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
|
||||
@@ -7,3 +8,4 @@
|
||||
{{ body | markdown | safe }}
|
||||
</div>
|
||||
</aside>
|
||||
{% endcomponent danger %}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% component note(title = "") %}
|
||||
<aside class="callout callout-note">
|
||||
<div class="callout-header">
|
||||
<svg class="callout-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
|
||||
@@ -7,3 +8,4 @@
|
||||
{{ body | markdown | safe }}
|
||||
</div>
|
||||
</aside>
|
||||
{% endcomponent note %}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% component tip(title = "") %}
|
||||
<aside class="callout callout-tip">
|
||||
<div class="callout-header">
|
||||
<svg class="callout-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M12 8v4"></path><path d="M12 16h.01"></path></svg>
|
||||
@@ -7,3 +8,4 @@
|
||||
{{ body | markdown | safe }}
|
||||
</div>
|
||||
</aside>
|
||||
{% endcomponent tip %}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% component warning(title = "") %}
|
||||
<aside class="callout callout-warning">
|
||||
<div class="callout-header">
|
||||
<svg class="callout-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
||||
@@ -7,3 +8,4 @@
|
||||
{{ body | markdown | safe }}
|
||||
</div>
|
||||
</aside>
|
||||
{% endcomponent warning %}
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
<div class="youtube-wrapper">
|
||||
<iframe
|
||||
src="https://www.youtube-nocookie.com/embed/{{ id }}{% if autoplay %}?autoplay=1{% endif %}"
|
||||
{% if title %}title="{{ title }}"{% endif %}
|
||||
loading="lazy"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
{% component youtube(id: string, page, config, title = "", autoplay = false) %}
|
||||
<div class="youtube-wrapper"><iframe src="https://www.youtube-nocookie.com/embed/{{ id }}{% if autoplay %}?autoplay=1{% endif %}"{% if title %} title="{{ title }}"{% endif %} loading="lazy" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
|
||||
<!-- SEO: VideoObject JSON-LD (confirms this page hosts the embedded video) -->
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "VideoObject",
|
||||
"name": {{ title | default(value=page.title) | json_encode | safe }},
|
||||
"name": {% if title %}{{ title | json_encode | safe }}{% else %}{{ page.title | json_encode | safe }}{% endif %},
|
||||
"description": {{ page.description | default(value=config.description) | json_encode | safe }},
|
||||
"thumbnailUrl": "https://i.ytimg.com/vi/{{ id | safe }}/sddefault.jpg"
|
||||
{% if page.date %},"uploadDate": "{{ page.date | date(format="%+") }}"{% endif %},
|
||||
{% if page.date %},"uploadDate": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %},
|
||||
"embedUrl": "https://www.youtube-nocookie.com/embed/{{ id | safe }}",
|
||||
"contentUrl": "https://www.youtube.com/watch?v={{ id | safe }}"
|
||||
}
|
||||
</script>
|
||||
{% endcomponent youtube %}
|
||||
|
||||
@@ -32,8 +32,8 @@ term.permalink }}{% endblock og_url %} {% block head %}
|
||||
"@type": "Person",
|
||||
"@id": "{{ config.base_url | safe }}/#author"
|
||||
}
|
||||
{% if page.date %},"datePublished": "{{ page.date | date(format="%+") }}"{% endif %}
|
||||
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%+") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%+") }}"{% endif %}
|
||||
{% if page.date %},"datePublished": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %}
|
||||
{% if page.updated %},"dateModified": "{{ page.updated | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% elif page.date %},"dateModified": "{{ page.date | date(format="%Y-%m-%dT%H:%M:%S%:z") }}"{% endif %}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user