Skip to content

al-folio v1.2

Latest

Choose a tag to compare

@github-actions github-actions released this 09 Aug 11:52
b95d6d6

v1.2 is a feature release: three new plugins, two dead third-party services retired, and a batch of fixes for things that were failing silently — a script 404, a favicon 404, a flickering theme switch.

As in v1.1, most of the change is in the gems rather than in this repo.

bundle update on its own will not upgrade you. The Gemfile pins every plugin to an exact version, and Bundler honours the pin already in your Gemfile — so a v1.1 site runs bundle update and stays exactly where it is, with no error. You must edit the pins first — see Upgrading at the bottom.

gem v1.1 v1.2
al_folio_core 1.0.12 1.0.15
al_cookie 1.0.0 1.0.1
al_email_protect 1.0.1
al_marimo 1.0.0
al_rtl 1.0.0

✨ Three new plugins

All three are off by default and cost nothing until a page or a flag opts in.

al_rtl — right-to-left languages (closes #3544, from #946)
Set lang: fa (or ar, he, ur, ps, sd, ug, yi, …) in a page's front matter and it renders right-to-left. Direction is set with dir on <html> rather than on a wrapper div as the original proposal did — that is what makes the navbar, footer, scrollbar placement and the browser's own bidi algorithm mirror, not just the article text. Code, shell transcripts, BibTeX and rendered maths are deliberately held left-to-right inside RTL prose, since letting them inherit rtl reorders operators and punctuation into nonsense. See the demo post, يک نوشتهٔ راست‌چين.

al_marimo — runnable Python notebooks (closes #3541, from #3517)
Add marimo: true to a post and fenced Python blocks wrapped in .al-marimo-inline become an interactive marimo notebook; {% al_marimo_embed %} embeds a hosted one. The marimo-snippets runtime is vendored at a pinned version with its digest recorded, rather than pulled from a CDN at an unpinned major as the source PR did — that shape is how the polyfill.io supply-chain attack worked, and SRI cannot fix it here because the CDN serves a dynamically minified build. Embedded notebooks are sandboxed without allow-same-origin.

al_email_protect — email obfuscation (closes #3540, from #3532)
Set protect_email: true and addresses rendered through {% al_email_protect_link %} or {{ … | al_email_obfuscate }} are split at build time — no user@host and no mailto: in the HTML at all — and clicking copies to the clipboard instead of opening a mail client. The build-time part is the point: harvesters parse markup and do not run your JavaScript, so a client-side rewrite protects nobody.

Scope, stated plainly: this applies where a layout calls the tag or filter. It does not yet cover the social links in the navbar and footer — those are rendered by the third-party jekyll-socials gem, which owns the whole block and offers no hook for the email entry. 1.0.1 ships al_email_protect_html, a filter that rewrites mailto: anchors in already-rendered HTML, which is the interception point that fixes this; wiring al_folio_core's layouts through it is landing in v1.2.1. If you enable the flag today, expect the CV and any addresses you render yourself to be protected, and the socials icons not to be.

🐛 Fixes

The theme switch flickered (al_folio_core 1.0.15) — headings changed colour visibly later than the text around them. color, fill and stroke are inherited properties, but were transitioned on html.transition *, so every inheriting element ran its own 240ms ease toward a parent that was itself still animating; convergence compounded once per level of nesting and then snapped when the class was removed. Measured on the about page, an h2 > a sat at rgb(50,50,50) while the paragraph beside it was already at rgb(130,130,130). Those properties are now transitioned once, at the root. Two smaller defects fell out of the same pass: transition-delay: 0 was invalid and silently dropped by the CSS parser (a <time> needs a unit even for zero, unlike a <length>), and the class was removed 20ms after a 240ms transition, so one slow frame truncated it into a snap.

Cookie consent's theme-sync script 404'd (al_cookie 1.0.1) — it was published to /lib/assets/al_cookie/js/ while the script tag pointed at /assets/al_cookie/js/. Only the feature being off by default kept this from being noticed: every site that enabled GDPR consent lost theme syncing.

The favicon <link> was emitted with an empty filename (al_folio_core 1.0.13) — site.icon != blank is always true under plain Liquid, because the blank literal compares by calling blank? on the other operand and neither nil nor String defines it without ActiveSupport. An unset icon therefore produced href="/assets/img/", a guaranteed 404 on every page.

iOS "Add to Home Screen" used a screenshot instead of the site icon (al_folio_core 1.0.13) — Safari only reads rel="apple-touch-icon", which was never emitted. Fixes #2774.

Video publication previews rendered as broken images (al_folio_core 1.0.13) — preview = {clip.mp4} in a .bib entry went straight to the image path. Fixes #3564.

🧹 Two dead services retired

Profile trophies are off by default. github-profile-trophy.vercel.app answers HTTP 402 / DEPLOYMENT_DISABLED — the Vercel account behind the free public instance is paused. The feature has not become paid: the project is still open source and runs on a free Hobby account, so repo_trophies.enabled plus external_services.github_profile_trophy_url will point at your own instance. Until then every visitor to /repositories/ was loading twelve images that all failed, hidden by an onerror handler.

The Plotly demo's basemap. Stamen retired the tile endpoint it used (503); their successor at Stadia needs an API key, so it cannot be a template default. Switched to carto-positron — deliberately not open-street-map, since pointing every copied site at OSM's standard tile servers is the distributed use their tile policy asks people to avoid.

🔧 Infrastructure

  • README screenshots are automated and current. They had drifted a full major version; update-screenshots.yml now regenerates all fourteen from a real production build and refuses to commit a shot that rendered with missing assets. That guard is what surfaced both dead services above.
  • A seventh integration test, integration_new_plugins.sh, asserts each new plugin renders when its gate is on and renders nothing when it is off — the off case being the one that matters, since these fail by emitting an empty string rather than an error.
  • Dependency bumps across all sixteen plugin repos.

⬆️ Upgrading

1. Update the pins in your Gemfile to the v1.2 column above, and add the three new gems if you want them:

gem "al_email_protect", "= 1.0.1"
gem "al_marimo", "= 1.0.0"
gem "al_rtl", "= 1.0.0"

2. Add them to _config.yml as well — a plugin present in only one of the two lists is inert, with no error:

plugins:
  - al_email_protect
  - al_marimo
  - al_rtl

protect_email: false # opt in when you want it

3. Install and verify:

bundle install
bundle exec al-folio upgrade audit
bundle list | grep -E 'al_folio_core|al_cookie'

You want al_folio_core 1.0.15 and al_cookie 1.0.1. No template, layout or content changes are required.


Full Changelog: v1.1...v1.2