Skip to content

feat(content): lightgallery support for figures and Twikoo comments - #57

Merged
hakula139 merged 19 commits into
mainfrom
feat/lightgallery
Jul 19, 2026
Merged

feat(content): lightgallery support for figures and Twikoo comments#57
hakula139 merged 19 commits into
mainfrom
feat/lightgallery

Conversation

@hakula139

@hakula139 hakula139 commented May 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add opt-in lightGallery 2.9 support for article figures and Twikoo content images, with thumbnails, zoom, and figcaption overlays.
  • Preserve kiln's LQIP loading contract and figure layout when gallery anchors are inserted. Existing image links, post banners, inline images, Twikoo avatars, and OwO emoji remain outside the gallery.
  • Consolidate CDN script and stylesheet emission in shared macros, and give Prettier, dprint, and Taplo explicit non-overlapping formatter ownership.

Design decisions

  • When an unlinked figure image is inside kiln's .lqip wrapper, the gallery anchor wraps the span. The prose CSS treats both direct .lqip and .lightgallery children as centered, bounded figure media.
  • Images already inside anchors retain their original links, which avoids nested anchors.
  • Figure caption text is passed through data-sub-html as the gallery caption.
  • Twikoo's onCommentLoaded callback reapplies wrapping after comment renders, including replies and pagination.
  • The optional license key is emitted in page metadata and read by the deferred initializer.
  • Prettier owns CSS, JavaScript, and JSON; dprint owns Markdown and fenced code; Taplo owns standalone TOML and aligns trailing comments.

Validation

  • Run pnpm install --frozen-lockfile, pnpm build, pnpm format, pnpm lint, pnpm spellcheck, and nix flake check.
  • Pass the IgnIt pull request CI check.
  • Load all 24 figures on a consuming-site preview with no broken or hidden images, layout drift, request failures, or console errors.
  • Open and close the article gallery; verify thumbnails, zoom controls, and caption overlays.
  • Confirm a page without figures creates no gallery instance.
  • Confirm the post banner remains outside the gallery and its configured credit URL remains intact.
  • Confirm the configured license key produces no visible license warning.
  • Exercise an existing linked figure on a consuming site; the current preview has no linked-figure fixture.
  • Exercise Twikoo image rendering and pagination with a comment-image fixture.
  • Run Lighthouse and confirm deferred gallery assets do not block first paint.

hakula139 added 11 commits July 18, 2026 17:09
Four SRI keys cover the core bundle, the thumbnail and zoom plugins,
and the CSS bundle.
…captions

Article-side gallery, gated by [params.lightgallery] enabled = true.
head-deps emits the bundle CSS, body-deps emits lib + thumbnail and zoom
plugins + the local init, and content/lightgallery.js wraps every figure
img in .prose with `<a class="lightgallery">`. Each figure's figcaption
text feeds the anchor's data-sub-html so it shows as a caption overlay
in the gallery.

Optional license_key lands as window.__lgLicenseKey in an inline script
before the deferred init runs.

When LQIP wraps an img in `<span class="lqip">`, the new anchor wraps the
span so the fade-in stays on the inner element.
Twikoo's onCommentLoaded fires after every comment render (initial load,
pagination, replies). The callback hands the #twikoo root to
window.__rewrapLightGallery so newly inserted images get wrapped. OwO
emoji exclusion lives in lightgallery.js's selector. Optional-chained so
the callback no-ops when lightgallery is disabled.
Sweeps existing JS and CSS comments to match the prose style guide:
em-dashes are reserved for true parenthetical asides, and "X, not Y"
antithesis only for ruling out a real misconception. Most call sites
read more naturally as "since" / "because" / a comma instead.
The previous implementation used `tojson` to inline the license key into
a `<script>`, but kiln's minijinja build doesn't enable the `json`
feature, so any site with `[params.lightgallery] license_key = "..."`
broke the template render. Switching to a `<meta>` tag is also a
cleaner contract: the license key is a flat string, not structured
data, and the deferred init script can read it at any time without
ordering constraints.
Centralize the SRI + crossorigin contract for jsDelivr-style assets in
a single `cdn.script` / `cdn.stylesheet` macro pair, then collapse the
seven repeated `<script>` blocks in body-deps and the three repeated
`<link rel="stylesheet">` blocks in head-deps to one-line calls. The
three FontAwesome `<link rel="preload">` blocks fold into a `for` loop
since they only differ in font filename.
Twikoo renders user avatars as `<img class="tk-avatar-img">`, which the
previous comment selector wrapped into the gallery alongside real
content images. Tighten the `:not()` chain to skip them.

Also surface a console warning when `window.lightGallery` is missing
inside `initOn()`. The script is only emitted when `enabled = true`, so
the absent global is always a CDN load failure, never a feature toggle.
Five comments were too WHAT-y or temporally misleading:

- lightgallery.js: spell out that lqip.css uses `.lqip > img` direct-child
  selectors, so an interposed anchor would break them — that is the actual
  reason the wrap target is the parent, not the inner img.
- lightgallery.js: explain that we re-scan on every Twikoo render because
  pagination and reply submit replace comment DOM, instead of just
  describing when the hook fires.
- twikoo.js: annotate the new `onCommentLoaded` callback with the same
  rationale so the cross-script coupling is visible at the call site.
- toc.js: rephrase "track, then pick" (which read as a temporal sequence)
  as "set of visible headings; pickActive() picks the topmost".
- float-buttons.js: pin down why the manual rect.top check is needed
  (IO only fires on state change, and a thread taller than the viewport
  never exits the root).
- comments.css: name the OwO emote selector in the comment so the line
  height fix is recognizable without a roundtrip to the rule.
The 'image-only links' rule used `:has(> img:only-child)`, which misses
anchors whose direct child is the `.lqip` span (the lightgallery
wrapper sits there to keep `.lqip > img` direct-child selectors intact).
The result was a visible border-bottom underline on every gallery
figure, in the theme link colour.

Extend the selector list to also match `:has(> .lqip:only-child)` so
both shapes get `border-b-0 pb-0`.
Regenerate static/css/style.css so the prose anchor selector matches
the source change in 7acfa7b. CI's `git diff --exit-code static/` gate
failed because the build artifact wasn't refreshed alongside the
_src/ edit.
@hakula139
hakula139 force-pushed the feat/lightgallery branch from 5d17af4 to cd69fb6 Compare July 18, 2026 09:10
Preserve existing image links, avoid empty gallery initialization, and leave the library's temporary license default intact when no key is configured. Remove comments that restate the code, retain only hidden invariants, and document the public configuration.
Keep comments only where they preserve a hidden browser, cascade, accessibility, timing, or DOM constraint.
Long component files use these banners as structural navigation. Keep them while continuing to omit comments that only restate the code.
Use the Taplo-backed Prettier TOML plugin for TOML files and fenced examples. Extend the pre-commit formatter scope so the alignment is enforced locally as well as in CI.
Taplo aligns comments across whole TOML tables and mismeasures CJK display width. The surrounding prose already explains these examples, so inline annotations add noise and format poorly.
Use dprint for Markdown and fenced code, Taplo for standalone TOML, and keep Prettier scoped to CSS, JS, and JSON where Tailwind class sorting is required. This mirrors the formatter boundaries in nixos-config and keeps local hooks aligned with CI.
lightGallery inserts an anchor between each figure and its LQIP wrapper, so the original direct-child selector no longer applies. Give wrapped and unwrapped figures the same centered, bounded layout.
@hakula139
hakula139 merged commit 351c042 into main Jul 19, 2026
1 check passed
@hakula139
hakula139 deleted the feat/lightgallery branch July 19, 2026 15:19
hakula139 added a commit that referenced this pull request Jul 19, 2026
)

## Summary

- Add opt-in lightGallery 2.9 support for article figures and Twikoo content images, with thumbnails, zoom, and figcaption overlays.
- Preserve kiln's LQIP loading contract and figure layout when gallery anchors are inserted. Existing image links, post banners, inline images, Twikoo avatars, and OwO emoji remain outside the gallery.
- Consolidate CDN script and stylesheet emission in shared macros, and give Prettier, dprint, and Taplo explicit non-overlapping formatter ownership.

## Design decisions

- When an unlinked figure image is inside kiln's `.lqip` wrapper, the gallery anchor wraps the span. The prose CSS treats both direct `.lqip` and `.lightgallery` children as centered, bounded figure media.
- Images already inside anchors retain their original links, which avoids nested anchors.
- Figure caption text is passed through `data-sub-html` as the gallery caption.
- Twikoo's `onCommentLoaded` callback reapplies wrapping after comment renders, including replies and pagination.
- The optional license key is emitted in page metadata and read by the deferred initializer.
- Prettier owns CSS, JavaScript, and JSON; dprint owns Markdown and fenced code; Taplo owns standalone TOML and aligns trailing comments.

## Validation

- [x] Run `pnpm install --frozen-lockfile`, `pnpm build`, `pnpm format`, `pnpm lint`, `pnpm spellcheck`, and `nix flake check`.
- [x] Pass the IgnIt pull request CI check.
- [x] Load all 24 figures on a consuming-site preview with no broken or hidden images, layout drift, request failures, or console errors.
- [x] Open and close the article gallery; verify thumbnails, zoom controls, and caption overlays.
- [x] Confirm a page without figures creates no gallery instance.
- [x] Confirm the post banner remains outside the gallery and its configured credit URL remains intact.
- [x] Confirm the configured license key produces no visible license warning.
- [ ] Exercise an existing linked figure on a consuming site; the current preview has no linked-figure fixture.
- [ ] Exercise Twikoo image rendering and pagination with a comment-image fixture.
- [ ] Run Lighthouse and confirm deferred gallery assets do not block first paint.
hakula139 added a commit to hakula139/hakula.xyz-kiln that referenced this pull request Jul 19, 2026
## Summary

- Enable lightGallery for prose figures and Twikoo content images, including the existing client-side activation key.
- Pin the IgnIt submodule to the merged `main` implementation and rebuild the committed site CSS so gallery-wrapped LQIP figures retain their centered, bounded layout. See [IgnIt PR 57](hakula139/IgnIt#57).
- Keep the site parameter blocks in alphabetical order.

## Validation

- [x] Pin the submodule to IgnIt `main` commit `88dcab3`.
- [x] Pass Nix Flake Check, Site Check, both site builds, and the Cloudflare preview deployment.
- [x] Load all 24 figures on the live preview with no broken or hidden images, layout drift, request failures, or console errors.
- [x] Open and close the article gallery; verify thumbnails, zoom controls, and figcaption overlays.
- [x] Confirm a page without figures creates no gallery instance.
- [x] Confirm the post banner remains outside the gallery and its configured credit URL remains intact.
- [x] Confirm the configured license key produces no visible license warning.
- [ ] Exercise an existing linked figure; the current site has no linked-figure fixture.
- [ ] Exercise Twikoo image rendering and pagination with a comment-image fixture.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant