Skip to content

Add ImageGallery shortcode with Lightbox2 support#11

Draft
Copilot wants to merge 9 commits intomainfrom
copilot/create-inline-image-gallery
Draft

Add ImageGallery shortcode with Lightbox2 support#11
Copilot wants to merge 9 commits intomainfrom
copilot/create-inline-image-gallery

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 16, 2026

Implements a Statiq IShortcode that renders an inline image gallery using Lightbox2, allowing images to be cycled through in a fullscreen overlay.

New components

  • ImageGalleryShortcode (SyncShortcode) — parses newline-separated image entries from shortcode content (src, src|title, or src|title|alt), HTML-encodes all attribute values, strips Markdown-injected HTML tags from content lines, and emits Lightbox2-compatible markup with full configuration option support
  • ImageGalleryConfigurator (IConfigurator<Bootstrapper>) — registers the shortcode as ImageGallery, following the existing ReadingTimeConfigurator pattern

Usage

<?# ImageGallery Name=my-gallery WrapAround=true AlbumLabel="Photo %1 of %2" ?>
/images/photo1.jpg|Caption for photo 1
/images/photo2.jpg|Caption for photo 2|Accessible alt text for photo 2
/images/photo3.jpg
<?#/ ImageGallery ?>

Parameters:

Parameter Default Description
Name gallery Lightbox2 gallery group name — images sharing the same name can be cycled through.
Class (none) Additional CSS class(es) on the wrapping <div>.
AlbumLabel "Image %1 of %2" Text shown below the image count (%1 = current, %2 = total).
WrapAround false Wrap around when navigating past the first/last image.
DisableScrolling false Prevent page scrolling while the lightbox is open.
FadeDuration 300 Duration (ms) of the fade-in/fade-out animation.
ImageFadeDuration 300 Duration (ms) of the image fade animation.
ResizeDuration 700 Duration (ms) of the resize animation.
FitImagesInViewport true Resize images larger than the viewport.
ShowImageNumberLabel true Show the AlbumLabel text in the lightbox.
MaxWidth (none) Maximum width (px) of the lightbox image.
MaxHeight (none) Maximum height (px) of the lightbox image.

Output:

<div class="image-gallery">
  <a href="/images/photo1.jpg" data-lightbox="my-gallery" data-title="Caption for photo 1" data-alt="Caption for photo 1">
    <img src="/images/photo1.jpg" alt="Caption for photo 1" />
  </a>
  ...
</div>
<script>
lightbox.option({
  'wrapAround': true,
  'albumLabel': "Photo %1 of %2"
});
</script>

When any Lightbox2 JS options are provided, a <script>lightbox.option({...});</script> block is emitted after the gallery markup. String values are JS-escaped to prevent injection.

Requires Lightbox2 CSS/JS in the layout — CDN links and SRI hash generation guidance included in the README.

Sample project

The sample/ site project is wired up to demonstrate the plugin end-to-end:

  • sample/Program.cs: registers ImageGalleryConfigurator via AddConfigurator<Bootstrapper>(new ImageGalleryConfigurator())
  • sample/input/posts/_partials/_head.cshtml: Lightbox2 CSS <link> tag, included via @Html.Partial("_partials/_head") in the layout <head>
  • sample/input/posts/_partials/_scripts.cshtml: Lightbox2 JS <script> tag using the jQuery-bundled build (lightbox-plus-jquery.min.js), included via @Html.Partial("_partials/_scripts") before </body>
  • sample/input/posts/_layout.cshtml: references the _head and _scripts partials instead of inline CDN tags
  • sample/input/posts/1.md: uses the ImageGallery shortcode with WrapAround=true to demonstrate the plugin in action

Running dotnet run in the sample directory generates correct Lightbox2 markup in output/posts/1.html.

Copilot AI linked an issue Apr 16, 2026 that may be closed by this pull request
Copilot AI and others added 3 commits April 16, 2026 21:28
… to README CDN links

Agent-Logs-Url: https://github.com/AlexHedley/statiq.plugins/sessions/0a97ea5e-9c2b-4e78-bd4b-7898c0595a54

Co-authored-by: AlexHedley <1573469+AlexHedley@users.noreply.github.com>
Copilot AI changed the title [WIP] Add shortcode for inline image gallery Add ImageGallery shortcode with Lightbox2 support Apr 16, 2026
Copilot AI requested a review from AlexHedley April 16, 2026 21:34
@AlexHedley
Copy link
Copy Markdown
Owner

@copilot add lightbox2 options

Copy link
Copy Markdown
Author

Copilot AI commented Apr 16, 2026

@copilot add lightbox2 options

Done in commit a37c7e8 (fixed double-encoding bug in 5b39c12).

The shortcode now supports all Lightbox2 options:

New gallery-level parameters (emits a <script>lightbox.option({...})</script> block when any are set):

Parameter Type Lightbox2 option
AlbumLabel string albumLabel
WrapAround bool wrapAround
DisableScrolling bool disableScrolling
FadeDuration int fadeDuration
ImageFadeDuration int imageFadeDuration
ResizeDuration int resizeDuration
FitImagesInViewport bool fitImagesInViewport
ShowImageNumberLabel bool showImageNumberLabel
MaxWidth int maxWidth
MaxHeight int maxHeight

Per-image data-alt is now supported via a third pipe-separated column (src|title|alt). If omitted, alt falls back to title.

Example:

<?# ImageGallery Name=my-gallery WrapAround=true AlbumLabel="Photo %1 of %2" ?>
/images/photo1.jpg|Caption 1
/images/photo2.jpg|Caption 2|Accessible alt text for photo 2
<?#/ ImageGallery ?>

@AlexHedley
Copy link
Copy Markdown
Owner

@copilot update the site project in the sample folder to use the gallery plugin and confirm the plugin is working

Copy link
Copy Markdown
Author

Copilot AI commented Apr 17, 2026

@copilot update the site project in the sample folder to use the gallery plugin and confirm the plugin is working

Done in commit 6214604.

Changes made to the sample project:

  • sample/Program.cs: registered ImageGalleryConfigurator via AddConfigurator<Bootstrapper>(new ImageGalleryConfigurator())
  • sample/input/posts/_layout.cshtml: added Lightbox2 CSS (in <head>) and JS (before </body>) CDN links
  • src/Statiq.Plugins/ImageGallery/ImageGalleryShortcode.cs: added HTML tag stripping in ParseImages — Markdown pre-processes shortcode content and wraps lines in <p> tags, which was corrupting the src/title values

Running dotnet run in the sample directory now generates correct gallery markup in output/posts/1.html:

<div class="image-gallery">
  <a href="/posts/images/background.jpg" data-lightbox="my-gallery" data-title="Background" data-alt="Background">
    <img src="/posts/images/background.jpg" alt="Background" />
  </a>
</div>
<script>
lightbox.option({
  'wrapAround': true
});
</script>

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.cdnjs.com
    • Triggering command: /usr/bin/curl curl -s REDACTED ref/netstandard1-v ref/�� ref/netstandard1.0/ja/System.Reflection.Extensions.xml ref/netstandard1.0/de/System.Reflection.Extensions.xml de/node/bin/git (dns block)
  • cdnjs.cloudflare.com
    • Triggering command: /usr/bin/curl curl -s --max-time 10 REDACTED -o /tmp/lightbox.min.css tnet/tools/git hub.com/.extrahegit (dns block)
  • cdnjs.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@AlexHedley
Copy link
Copy Markdown
Owner

@copilot does it need to be dist/js/lightbox-plus-jquery.min.js.map instead?

Also could you use _head and _scripts files to put these items in instead?

Copy link
Copy Markdown
Author

Copilot AI commented Apr 17, 2026

@copilot does it need to be dist/js/lightbox-plus-jquery.min.js.map instead?

Also could you use _head and _scripts files to put these items in instead?

Done in commit a9a09b5.

  • Switched to lightbox-plus-jquery.min.js (bundles jQuery, so no separate jQuery dependency needed)
  • Created sample/input/posts/_partials/_head.cshtml for the Lightbox2 CSS link
  • Created sample/input/posts/_partials/_scripts.cshtml for the Lightbox2 JS script
  • Updated _layout.cshtml to use @Html.Partial("_partials/_head") and @Html.Partial("_partials/_scripts") instead of inline tags

@AlexHedley
Copy link
Copy Markdown
Owner

@copilot share some screenshots of the gallery in action from the sample site

Copy link
Copy Markdown
Author

Copilot AI commented Apr 17, 2026

@copilot share some screenshots of the gallery in action from the sample site

Here are the screenshots from the sample site running the ImageGallery shortcode:

Gallery thumbnails (three images rendered side-by-side):

Gallery thumbnails

Lightbox2 overlay (clicking an image opens the full-screen lightbox, with the title "Mountain Landscape" and "Photo 1 of 3" counter from the AlbumLabel="Photo %1 of %2" option, plus prev/next navigation and close button):

Lightbox2 overlay

The wrapAround: true option means navigating past the last image cycles back to the first.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdnjs.cloudflare.com
    • Triggering command: /usr/bin/curl curl -sL REDACTED -o /home/REDACTED/work/statiq.plugins/statiq.plugins/sample/output/lib/lightbox2/lightbox.min.css (dns block)
    • Triggering command: /usr/bin/curl curl -sL REDACTED -o /home/REDACTED/work/statiq.plugins/statiq.plugins/sample/output/lib/lightbox2/lightbox-plus-jquery.min.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image Gallery

2 participants