Color mode

Gallery

Markdown-driven card galleries. A fenced gallery code block with a small YAML body renders as a responsive card grid, which makes theme galleries, project showcases, and link collections easy to author without HTML.

日本語

Overview

markdown
```gallery
columns: 3
items:
  - title: Default
    description: A calm, readable baseline theme.
    image: /themes/default.png
    href: /themes/default
    meta: v0.1.0
  - title: Gruvbox
    href: /themes/gruvbox
```

Each item becomes one card. When href is present the card is an <a>; otherwise it is a plain <div>. When image is absent the card is text-only. The grid is rendered at build time, so no client-side JavaScript is required.

Usage

ts
import { defineConfig } from "@riebeckite/core";
import { gallery } from "@riebeckite/plugin-gallery";
 
export default defineConfig({
  // ...
  plugins: [gallery()],
});

Options

Option Type Default Description
language string "gallery" Fenced code block language
columns number 3 Default column count
aspect string "4/3" Default image aspect ratio
ts
gallery({ columns: 4, aspect: "1/1" });

Block fields

Field Type Description
items GalleryItem[] Required. The cards, in order
columns number Column count. Overrides the plugin option
aspect string Image aspect ratio. Overrides the plugin option

Each GalleryItem field is optional, but an item should set at least title or image:

Field Description
image Image source URL
alt Alternative text. Falls back to title, then ""
title Card heading
description Supporting copy
href Link target. Omitted renders a non-interactive card
meta Small trailing label, for example a version or a date

Output

html
<div class="rr-gallery" data-rr-gallery style="--rr-gallery-columns:3;--rr-gallery-aspect:4/3">
  <ul class="rr-gallery__items">
    <li class="rr-gallery__item">
      <a class="rr-gallery__card" href="/themes/default">
        <img class="rr-gallery__image" src="/themes/default.png" alt="Default" loading="lazy" decoding="async">
        <span class="rr-gallery__body">
          <span class="rr-gallery__title">Default</span>
          <span class="rr-gallery__description">A calm, readable baseline theme.</span>
          <span class="rr-gallery__meta">v0.1.0</span>
        </span>
      </a>
    </li>
  </ul>
</div>

Diagnostics

Code Severity Meaning
gallery-invalid error The body is not valid YAML, is not a mapping, or items / columns / aspect is malformed. The block is replaced by an error box
gallery-item-incomplete warning An item has neither a title nor an image

alt is always emitted on generated images so the output passes quality:img-alt-missing. The plugin also composes with responsive-image (for srcset) and lightbox (for zoom).

Style

The package ships style.css. Register it like any other plugin stylesheet:

ts
import "@riebeckite/plugin-gallery/style.css";

The grid uses container-type: inline-size and collapses to two columns below 36rem and one column below 22rem.

Exports

  • gallery(options?) — plugin factory
  • galleryPlugin — alias of gallery
  • parseGallery(source, options) — parse a block body into a spec
  • renderGallery(spec) / renderGalleryError(message) — render the grid or an error box
  • remarkGallery(options?) — the remark transform
  • resolveGalleryOptions(options?) — apply option defaults
  • Constants: GALLERY_PLUGIN_NAME, GALLERY_CLASS, GALLERY_ATTRIBUTE, DEFAULT_GALLERY_COLUMNS, DEFAULT_GALLERY_ASPECT
  • Types: GalleryOptions, GalleryItem, GallerySpec, GalleryParseResult, GalleryWarning, ResolvedGalleryOptions

Limitations

  • Items are static data. Filtering or querying the content manifest is out of scope; use the query plugin's table/cards output for that.
  • The container-query collapse targets the default multi-column layout. A block that explicitly sets columns: 1 is unaffected visually.

See also

History

1 changesCollapseExpand
1 + <!-- Generated from packages/plugins/gallery/README.md. Do not edit this page directly; edit the package README and run `pnpm docs:sync`. -->
2 +
3 + # Gallery
4 +
5 + Markdown-driven card galleries. A fenced `gallery` code block with a small YAML
6 + body renders as a responsive card grid, which makes theme galleries, project
7 + showcases, and link collections easy to author without HTML.
8 +
9 + [日本語](./gallery.md)
10 +
11 + ## Overview
12 +
13 + ````markdown
14 + ```gallery
15 + columns: 3
16 + items:
17 + - title: Default
18 + description: A calm, readable baseline theme.
19 + image: /themes/default.png
20 + href: /themes/default
21 + meta: v0.1.0
22 + - title: Gruvbox
23 + href: /themes/gruvbox
24 + ```
25 + ````
26 +
27 + Each item becomes one card. When `href` is present the card is an `<a>`;
28 + otherwise it is a plain `<div>`. When `image` is absent the card is text-only.
29 + The grid is rendered at build time, so no client-side JavaScript is required.
30 +
31 + ## Usage
32 +
33 + ```ts
34 + import { defineConfig } from "@riebeckite/core";
35 + import { gallery } from "@riebeckite/plugin-gallery";
36 +
37 + export default defineConfig({
38 + // ...
39 + plugins: [gallery()],
40 + });
41 + ```
42 +
43 + ## Options
44 +
45 + | Option | Type | Default | Description |
46 + | ------ | ---- | ------- | ----------- |
47 + | `language` | `string` | `"gallery"` | Fenced code block language |
48 + | `columns` | `number` | `3` | Default column count |
49 + | `aspect` | `string` | `"4/3"` | Default image aspect ratio |
50 +
51 + ```ts
52 + gallery({ columns: 4, aspect: "1/1" });
53 + ```
54 +
55 + ## Block fields
56 +
57 + | Field | Type | Description |
58 + | ----- | ---- | ----------- |
59 + | `items` | `GalleryItem[]` | Required. The cards, in order |
60 + | `columns` | `number` | Column count. Overrides the plugin option |
61 + | `aspect` | `string` | Image aspect ratio. Overrides the plugin option |
62 +
63 + Each `GalleryItem` field is optional, but an item should set at least `title`
64 + or `image`:
65 +
66 + | Field | Description |
67 + | ----- | ----------- |
68 + | `image` | Image source URL |
69 + | `alt` | Alternative text. Falls back to `title`, then `""` |
70 + | `title` | Card heading |
71 + | `description` | Supporting copy |
72 + | `href` | Link target. Omitted renders a non-interactive card |
73 + | `meta` | Small trailing label, for example a version or a date |
74 +
75 + ## Output
76 +
77 + ```html
78 + <div class="rr-gallery" data-rr-gallery style="--rr-gallery-columns:3;--rr-gallery-aspect:4/3">
79 + <ul class="rr-gallery__items">
80 + <li class="rr-gallery__item">
81 + <a class="rr-gallery__card" href="/themes/default">
82 + <img class="rr-gallery__image" src="/themes/default.png" alt="Default" loading="lazy" decoding="async">
83 + <span class="rr-gallery__body">
84 + <span class="rr-gallery__title">Default</span>
85 + <span class="rr-gallery__description">A calm, readable baseline theme.</span>
86 + <span class="rr-gallery__meta">v0.1.0</span>
87 + </span>
88 + </a>
89 + </li>
90 + </ul>
91 + </div>
92 + ```
93 +
94 + ## Diagnostics
95 +
96 + | Code | Severity | Meaning |
97 + | ---- | -------- | ------- |
98 + | `gallery-invalid` | `error` | The body is not valid YAML, is not a mapping, or `items` / `columns` / `aspect` is malformed. The block is replaced by an error box |
99 + | `gallery-item-incomplete` | `warning` | An item has neither a `title` nor an `image` |
100 +
101 + `alt` is always emitted on generated images so the output passes
102 + `quality:img-alt-missing`. The plugin also composes with `responsive-image`
103 + (for `srcset`) and `lightbox` (for zoom).
104 +
105 + ## Style
106 +
107 + The package ships `style.css`. Register it like any other plugin stylesheet:
108 +
109 + ```ts
110 + import "@riebeckite/plugin-gallery/style.css";
111 + ```
112 +
113 + The grid uses `container-type: inline-size` and collapses to two columns below
114 + `36rem` and one column below `22rem`.
115 +
116 + ## Exports
117 +
118 + - `gallery(options?)` — plugin factory
119 + - `galleryPlugin` — alias of `gallery`
120 + - `parseGallery(source, options)` — parse a block body into a spec
121 + - `renderGallery(spec)` / `renderGalleryError(message)` — render the grid or an error box
122 + - `remarkGallery(options?)` — the remark transform
123 + - `resolveGalleryOptions(options?)` — apply option defaults
124 + - Constants: `GALLERY_PLUGIN_NAME`, `GALLERY_CLASS`, `GALLERY_ATTRIBUTE`, `DEFAULT_GALLERY_COLUMNS`, `DEFAULT_GALLERY_ASPECT`
125 + - Types: `GalleryOptions`, `GalleryItem`, `GallerySpec`, `GalleryParseResult`, `GalleryWarning`, `ResolvedGalleryOptions`
126 +
127 + ## Limitations
128 +
129 + - Items are static data. Filtering or querying the content manifest is out of
130 + scope; use the `query` plugin's table/cards output for that.
131 + - The container-query collapse targets the default multi-column layout. A block
132 + that explicitly sets `columns: 1` is unaffected visually.
133 +
134 + ## See also
135 +
136 + - [Plugin guide](../reference/plugin-api.en.md)
137 +