@riebeckite/plugin-series 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -144
- package/README_ja.md +125 -125
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
# @riebeckite/plugin-series
|
|
2
|
-
|
|
3
|
-
Ordered multi-part posts ("series") for Riebeckite. At build time, notes that
|
|
4
|
-
share a series name get the same generated navigation listing every part in
|
|
5
|
-
order, with the current part marked and previous/next links.
|
|
6
|
-
|
|
7
|
-
[日本語](./README_ja.md)
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
`series()` reads series metadata from frontmatter, groups every matching
|
|
12
|
-
manifest entry, sorts the group, and appends a `<nav class="rb-series">` block
|
|
13
|
-
to each note in the series. Links use the permalinks resolved by Core, so
|
|
14
|
-
plugins such as `permalink` are respected. A single-note series renders no
|
|
15
|
-
navigation block.
|
|
16
|
-
|
|
17
|
-
The plugin is build-time only: it ships a stylesheet asset and no client
|
|
18
|
-
runtime.
|
|
19
|
-
|
|
20
|
-
## Usage
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
import { defineConfig } from "@riebeckite/core";
|
|
24
|
-
import { series } from "@riebeckite/plugin-series";
|
|
25
|
-
|
|
26
|
-
export default defineConfig({
|
|
27
|
-
// ...
|
|
28
|
-
plugins: [series()],
|
|
29
|
-
});
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Frontmatter contract
|
|
33
|
-
|
|
34
|
-
| Key | Type | Required | Description |
|
|
35
|
-
| --- | ---- | -------- | ----------- |
|
|
36
|
-
| `series` | `string` | yes | Series name used for grouping. |
|
|
37
|
-
| `series_order` | `number` | recommended | Position within the series (ascending). |
|
|
38
|
-
| `series_title` | `string` | no | Display title for the series heading. |
|
|
39
|
-
|
|
40
|
-
```yaml
|
|
41
|
-
---
|
|
42
|
-
title: Installing the thing
|
|
43
|
-
series: Build a thing
|
|
44
|
-
series_order: 2
|
|
45
|
-
---
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Notes missing a valid `series_order` are still included; they are ordered after
|
|
49
|
-
the numbered parts, using `date`/`created`/`published`, then `title`, then
|
|
50
|
-
`slug`. Ties always resolve deterministically.
|
|
51
|
-
|
|
52
|
-
## Options
|
|
53
|
-
|
|
54
|
-
| Option | Type | Default | Description |
|
|
55
|
-
| ------ | ---- | ------- | ----------- |
|
|
56
|
-
| `key` | `string` | `"series"` | Frontmatter key that names the series. |
|
|
57
|
-
| `orderKey` | `string` | `"series_order"` | Frontmatter key holding the numeric order. |
|
|
58
|
-
| `titleKey` | `string` | `"series_title"` | Frontmatter key overriding the series heading. |
|
|
59
|
-
| `heading` | `boolean` | `true` | Render the series heading above the list. |
|
|
60
|
-
| `className` | `string` | `"rb-series"` | Base CSS class for generated markup. |
|
|
61
|
-
| `positionLabel` | `boolean` | `false` | Add a `Part N of M` label for the current note. |
|
|
62
|
-
|
|
63
|
-
## Output
|
|
64
|
-
|
|
65
|
-
Each note in a series of two or more parts gets the following block appended to
|
|
66
|
-
its HTML:
|
|
67
|
-
|
|
68
|
-
```html
|
|
69
|
-
<nav class="rb-series" data-series="Build a thing"
|
|
70
|
-
aria-label="Series navigation">
|
|
71
|
-
<p class="rb-series__title">
|
|
72
|
-
<a class="rb-series__link" href="/build-a-thing">Build a thing</a>
|
|
73
|
-
</p>
|
|
74
|
-
<ol class="rb-series__list">
|
|
75
|
-
<li class="rb-series__item">
|
|
76
|
-
<a class="rb-series__link" href="/part-1" data-series-order="1">Part 1</a>
|
|
77
|
-
</li>
|
|
78
|
-
<li class="rb-series__item">
|
|
79
|
-
<a class="rb-series__link" href="/part-2" data-series-order="2"
|
|
80
|
-
aria-current="page">Part 2</a>
|
|
81
|
-
</li>
|
|
82
|
-
</ol>
|
|
83
|
-
<div class="rb-series__nav">
|
|
84
|
-
<a class="rb-series__prev" rel="prev" href="/part-1">← Part 1</a>
|
|
85
|
-
<a class="rb-series__next" rel="next" href="/part-3">Part 3 →</a>
|
|
86
|
-
</div>
|
|
87
|
-
</nav>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
All text and attributes are escaped. The injected HTML is written back to both
|
|
91
|
-
the manifest entry and the processed content object so the page route, feeds,
|
|
92
|
-
and search see the same markup.
|
|
93
|
-
|
|
94
|
-
## Exports
|
|
95
|
-
|
|
96
|
-
- `series(options?)` / `seriesPlugin(options?)` — plugin factory
|
|
97
|
-
- `buildSeriesIndex(manifest, name, options?)` — ordered members for one series
|
|
98
|
-
(`SeriesIndex | null`); useful for landing pages
|
|
99
|
-
- `renderSeriesIndex(manifest, name, options?)` — standalone `<section>` block
|
|
100
|
-
for a whole series
|
|
101
|
-
- `renderSeriesNavigation(index, currentSlug, options?)` — a single navigation
|
|
102
|
-
block
|
|
103
|
-
- `collectSeriesIndexes(manifest, options?)` — every series in first-seen order
|
|
104
|
-
- `resolveSeriesOptions(options?)` — options with defaults applied
|
|
105
|
-
- Types: `SeriesOptions`, `ResolvedSeriesOptions`, `SeriesMember`, `SeriesIndex`
|
|
106
|
-
|
|
107
|
-
### Series landing page
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import { buildSeriesIndex, renderSeriesIndex } from "@riebeckite/plugin-series";
|
|
111
|
-
|
|
112
|
-
// inside a route component, with the resolved manifest:
|
|
113
|
-
const index = buildSeriesIndex(manifest, "Build a thing");
|
|
114
|
-
const html = renderSeriesIndex(manifest, "Build a thing");
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Diagnostics
|
|
118
|
-
|
|
119
|
-
Emitted with `pluginName: "series"` and `severity: "warning"`:
|
|
120
|
-
|
|
121
|
-
| Code | Meaning |
|
|
122
|
-
| ---- | ------- |
|
|
123
|
-
| `series-invalid-name` | The series key is present but is not a non-empty string. |
|
|
124
|
-
| `series-missing-order` | The note has no valid numeric order key; fallback ordering is used. |
|
|
125
|
-
| `series-duplicate-order` | Two or more notes share the same `(series, order)` pair. |
|
|
126
|
-
|
|
127
|
-
## CSS hooks
|
|
128
|
-
|
|
129
|
-
`style.css` styles `.rb-series`, `.rb-series__title`, `.rb-series__position`,
|
|
130
|
-
`.rb-series__list`, `.rb-series__item`, `.rb-series__nav`, `.rb-series__prev`,
|
|
131
|
-
`.rb-series__next`, and the `.rb-series--index` variant. The current part is
|
|
132
|
-
matched with `.rb-series__item a[aria-current="page"]`.
|
|
133
|
-
|
|
134
|
-
## Limitations
|
|
135
|
-
|
|
136
|
-
- A note belongs to exactly one series.
|
|
137
|
-
- A series of one note produces no navigation block.
|
|
138
|
-
- `series_order` must be a finite number; numeric strings are not coerced.
|
|
139
|
-
- The plugin does not generate routes for series; combine
|
|
140
|
-
`renderSeriesIndex()` with your own page to build a series landing page.
|
|
141
|
-
|
|
142
|
-
## See also
|
|
143
|
-
|
|
144
|
-
- [Plugin guide](../../../docs/en/plugin-
|
|
1
|
+
# @riebeckite/plugin-series
|
|
2
|
+
|
|
3
|
+
Ordered multi-part posts ("series") for Riebeckite. At build time, notes that
|
|
4
|
+
share a series name get the same generated navigation listing every part in
|
|
5
|
+
order, with the current part marked and previous/next links.
|
|
6
|
+
|
|
7
|
+
[日本語](./README_ja.md)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`series()` reads series metadata from frontmatter, groups every matching
|
|
12
|
+
manifest entry, sorts the group, and appends a `<nav class="rb-series">` block
|
|
13
|
+
to each note in the series. Links use the permalinks resolved by Core, so
|
|
14
|
+
plugins such as `permalink` are respected. A single-note series renders no
|
|
15
|
+
navigation block.
|
|
16
|
+
|
|
17
|
+
The plugin is build-time only: it ships a stylesheet asset and no client
|
|
18
|
+
runtime.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { defineConfig } from "@riebeckite/core";
|
|
24
|
+
import { series } from "@riebeckite/plugin-series";
|
|
25
|
+
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
// ...
|
|
28
|
+
plugins: [series()],
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Frontmatter contract
|
|
33
|
+
|
|
34
|
+
| Key | Type | Required | Description |
|
|
35
|
+
| --- | ---- | -------- | ----------- |
|
|
36
|
+
| `series` | `string` | yes | Series name used for grouping. |
|
|
37
|
+
| `series_order` | `number` | recommended | Position within the series (ascending). |
|
|
38
|
+
| `series_title` | `string` | no | Display title for the series heading. |
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
---
|
|
42
|
+
title: Installing the thing
|
|
43
|
+
series: Build a thing
|
|
44
|
+
series_order: 2
|
|
45
|
+
---
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Notes missing a valid `series_order` are still included; they are ordered after
|
|
49
|
+
the numbered parts, using `date`/`created`/`published`, then `title`, then
|
|
50
|
+
`slug`. Ties always resolve deterministically.
|
|
51
|
+
|
|
52
|
+
## Options
|
|
53
|
+
|
|
54
|
+
| Option | Type | Default | Description |
|
|
55
|
+
| ------ | ---- | ------- | ----------- |
|
|
56
|
+
| `key` | `string` | `"series"` | Frontmatter key that names the series. |
|
|
57
|
+
| `orderKey` | `string` | `"series_order"` | Frontmatter key holding the numeric order. |
|
|
58
|
+
| `titleKey` | `string` | `"series_title"` | Frontmatter key overriding the series heading. |
|
|
59
|
+
| `heading` | `boolean` | `true` | Render the series heading above the list. |
|
|
60
|
+
| `className` | `string` | `"rb-series"` | Base CSS class for generated markup. |
|
|
61
|
+
| `positionLabel` | `boolean` | `false` | Add a `Part N of M` label for the current note. |
|
|
62
|
+
|
|
63
|
+
## Output
|
|
64
|
+
|
|
65
|
+
Each note in a series of two or more parts gets the following block appended to
|
|
66
|
+
its HTML:
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<nav class="rb-series" data-series="Build a thing"
|
|
70
|
+
aria-label="Series navigation">
|
|
71
|
+
<p class="rb-series__title">
|
|
72
|
+
<a class="rb-series__link" href="/build-a-thing">Build a thing</a>
|
|
73
|
+
</p>
|
|
74
|
+
<ol class="rb-series__list">
|
|
75
|
+
<li class="rb-series__item">
|
|
76
|
+
<a class="rb-series__link" href="/part-1" data-series-order="1">Part 1</a>
|
|
77
|
+
</li>
|
|
78
|
+
<li class="rb-series__item">
|
|
79
|
+
<a class="rb-series__link" href="/part-2" data-series-order="2"
|
|
80
|
+
aria-current="page">Part 2</a>
|
|
81
|
+
</li>
|
|
82
|
+
</ol>
|
|
83
|
+
<div class="rb-series__nav">
|
|
84
|
+
<a class="rb-series__prev" rel="prev" href="/part-1">← Part 1</a>
|
|
85
|
+
<a class="rb-series__next" rel="next" href="/part-3">Part 3 →</a>
|
|
86
|
+
</div>
|
|
87
|
+
</nav>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
All text and attributes are escaped. The injected HTML is written back to both
|
|
91
|
+
the manifest entry and the processed content object so the page route, feeds,
|
|
92
|
+
and search see the same markup.
|
|
93
|
+
|
|
94
|
+
## Exports
|
|
95
|
+
|
|
96
|
+
- `series(options?)` / `seriesPlugin(options?)` — plugin factory
|
|
97
|
+
- `buildSeriesIndex(manifest, name, options?)` — ordered members for one series
|
|
98
|
+
(`SeriesIndex | null`); useful for landing pages
|
|
99
|
+
- `renderSeriesIndex(manifest, name, options?)` — standalone `<section>` block
|
|
100
|
+
for a whole series
|
|
101
|
+
- `renderSeriesNavigation(index, currentSlug, options?)` — a single navigation
|
|
102
|
+
block
|
|
103
|
+
- `collectSeriesIndexes(manifest, options?)` — every series in first-seen order
|
|
104
|
+
- `resolveSeriesOptions(options?)` — options with defaults applied
|
|
105
|
+
- Types: `SeriesOptions`, `ResolvedSeriesOptions`, `SeriesMember`, `SeriesIndex`
|
|
106
|
+
|
|
107
|
+
### Series landing page
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { buildSeriesIndex, renderSeriesIndex } from "@riebeckite/plugin-series";
|
|
111
|
+
|
|
112
|
+
// inside a route component, with the resolved manifest:
|
|
113
|
+
const index = buildSeriesIndex(manifest, "Build a thing");
|
|
114
|
+
const html = renderSeriesIndex(manifest, "Build a thing");
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Diagnostics
|
|
118
|
+
|
|
119
|
+
Emitted with `pluginName: "series"` and `severity: "warning"`:
|
|
120
|
+
|
|
121
|
+
| Code | Meaning |
|
|
122
|
+
| ---- | ------- |
|
|
123
|
+
| `series-invalid-name` | The series key is present but is not a non-empty string. |
|
|
124
|
+
| `series-missing-order` | The note has no valid numeric order key; fallback ordering is used. |
|
|
125
|
+
| `series-duplicate-order` | Two or more notes share the same `(series, order)` pair. |
|
|
126
|
+
|
|
127
|
+
## CSS hooks
|
|
128
|
+
|
|
129
|
+
`style.css` styles `.rb-series`, `.rb-series__title`, `.rb-series__position`,
|
|
130
|
+
`.rb-series__list`, `.rb-series__item`, `.rb-series__nav`, `.rb-series__prev`,
|
|
131
|
+
`.rb-series__next`, and the `.rb-series--index` variant. The current part is
|
|
132
|
+
matched with `.rb-series__item a[aria-current="page"]`.
|
|
133
|
+
|
|
134
|
+
## Limitations
|
|
135
|
+
|
|
136
|
+
- A note belongs to exactly one series.
|
|
137
|
+
- A series of one note produces no navigation block.
|
|
138
|
+
- `series_order` must be a finite number; numeric strings are not coerced.
|
|
139
|
+
- The plugin does not generate routes for series; combine
|
|
140
|
+
`renderSeriesIndex()` with your own page to build a series landing page.
|
|
141
|
+
|
|
142
|
+
## See also
|
|
143
|
+
|
|
144
|
+
- [Plugin guide](../../../docs/en/reference/plugin-api.md)
|
package/README_ja.md
CHANGED
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
# @riebeckite/plugin-series
|
|
2
|
-
|
|
3
|
-
連載記事(シリーズ)を順番どおりに並べ、各記事へ共通のナビゲーションを差し込むプラグインです。ビルド時に、同じシリーズ名を持つノートをまとめて、目次・現在位置・前後の記事リンクを生成します。
|
|
4
|
-
|
|
5
|
-
[English](./README.md)
|
|
6
|
-
|
|
7
|
-
## 概要
|
|
8
|
-
|
|
9
|
-
`series()` は frontmatter からシリーズ情報を読み取り、該当するノートをグループ化して並べ替えたうえで、各ノートの HTML に `<nav class="rb-series">` ブロックを追加します。リンクには Core が解決したパーマリンクを使うため、`permalink` プラグインなどとも併用できます。1件だけのシリーズにはナビゲーションを出力しません。
|
|
10
|
-
|
|
11
|
-
このプラグインはビルド時のみ動作し、クライアント用のランタイムは持ちません(スタイルシートのみを登録します)。
|
|
12
|
-
|
|
13
|
-
## 設定する
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { defineConfig } from "@riebeckite/core";
|
|
17
|
-
import { series } from "@riebeckite/plugin-series";
|
|
18
|
-
|
|
19
|
-
export default defineConfig({
|
|
20
|
-
// ...
|
|
21
|
-
plugins: [series()],
|
|
22
|
-
});
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## frontmatter の書き方
|
|
26
|
-
|
|
27
|
-
| キー | 型 | 必須 | 説明 |
|
|
28
|
-
| ---- | -- | ---- | ---- |
|
|
29
|
-
| `series` | `string` | はい | グループ化に使うシリーズ名。 |
|
|
30
|
-
| `series_order` | `number` | 推奨 | シリーズ内の並び順(昇順)。 |
|
|
31
|
-
| `series_title` | `string` | いいえ | 見出しに表示するシリーズ名。 |
|
|
32
|
-
|
|
33
|
-
```yaml
|
|
34
|
-
---
|
|
35
|
-
title: 導入編
|
|
36
|
-
series: 何かを作る
|
|
37
|
-
series_order: 2
|
|
38
|
-
---
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`series_order` が無い・不正なノートも対象に含まれます。その場合は番号付きの記事の後ろに並び、`date`/`created`/`published`、`title`、`slug` の順で安定して並べ替えます。同点の場合は常に決まった順序になります。
|
|
42
|
-
|
|
43
|
-
## オプション
|
|
44
|
-
|
|
45
|
-
| オプション | 型 | 既定値 | 説明 |
|
|
46
|
-
| ---------- | -- | ------ | ---- |
|
|
47
|
-
| `key` | `string` | `"series"` | シリーズ名を持つ frontmatter キー。 |
|
|
48
|
-
| `orderKey` | `string` | `"series_order"` | 並び順の数値を持つ frontmatter キー。 |
|
|
49
|
-
| `titleKey` | `string` | `"series_title"` | 見出しのシリーズ名を上書きするキー。 |
|
|
50
|
-
| `heading` | `boolean` | `true` | リストの上に見出しを表示する。 |
|
|
51
|
-
| `className` | `string` | `"rb-series"` | 生成する HTML の基準クラス名。 |
|
|
52
|
-
| `positionLabel` | `boolean` | `false` | 現在の記事に「Part N of M」を付ける。 |
|
|
53
|
-
|
|
54
|
-
## 出力
|
|
55
|
-
|
|
56
|
-
2件以上あるシリーズの各ノートには、次のブロックが HTML の末尾に追加されます。
|
|
57
|
-
|
|
58
|
-
```html
|
|
59
|
-
<nav class="rb-series" data-series="何かを作る"
|
|
60
|
-
aria-label="Series navigation">
|
|
61
|
-
<p class="rb-series__title">
|
|
62
|
-
<a class="rb-series__link" href="/part-1">何かを作る</a>
|
|
63
|
-
</p>
|
|
64
|
-
<ol class="rb-series__list">
|
|
65
|
-
<li class="rb-series__item">
|
|
66
|
-
<a class="rb-series__link" href="/part-1" data-series-order="1">導入編</a>
|
|
67
|
-
</li>
|
|
68
|
-
<li class="rb-series__item">
|
|
69
|
-
<a class="rb-series__link" href="/part-2" data-series-order="2"
|
|
70
|
-
aria-current="page">実装編</a>
|
|
71
|
-
</li>
|
|
72
|
-
</ol>
|
|
73
|
-
<div class="rb-series__nav">
|
|
74
|
-
<a class="rb-series__prev" rel="prev" href="/part-1">← 導入編</a>
|
|
75
|
-
<a class="rb-series__next" rel="next" href="/part-3">仕上げ編 →</a>
|
|
76
|
-
</div>
|
|
77
|
-
</nav>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
テキストと属性はすべてエスケープします。生成した HTML は manifest の entry と処理済みコンテンツの両方へ書き戻すため、ページのルート表示・フィード・検索でも同じマークアップになります。
|
|
81
|
-
|
|
82
|
-
## 公開 API
|
|
83
|
-
|
|
84
|
-
- `series(options?)` / `seriesPlugin(options?)` — プラグインファクトリ
|
|
85
|
-
- `buildSeriesIndex(manifest, name, options?)` — 1つのシリーズの並び順付きメンバー(`SeriesIndex | null`)。ランディングページ向け
|
|
86
|
-
- `renderSeriesIndex(manifest, name, options?)` — シリーズ全体の `<section>` ブロック
|
|
87
|
-
- `renderSeriesNavigation(index, currentSlug, options?)` — ナビゲーション1つ分
|
|
88
|
-
- `collectSeriesIndexes(manifest, options?)` — 全シリーズを出現順で取得
|
|
89
|
-
- `resolveSeriesOptions(options?)` — 既定値を適用したオプション
|
|
90
|
-
- 型: `SeriesOptions`, `ResolvedSeriesOptions`, `SeriesMember`, `SeriesIndex`
|
|
91
|
-
|
|
92
|
-
### シリーズのランディングページ
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
import { buildSeriesIndex, renderSeriesIndex } from "@riebeckite/plugin-series";
|
|
96
|
-
|
|
97
|
-
// ルートコンポーネント内で、解決済みの manifest を使って:
|
|
98
|
-
const index = buildSeriesIndex(manifest, "何かを作る");
|
|
99
|
-
const html = renderSeriesIndex(manifest, "何かを作る");
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## 診断
|
|
103
|
-
|
|
104
|
-
`pluginName: "series"`、`severity: "warning"` で出力します。
|
|
105
|
-
|
|
106
|
-
| コード | 意味 |
|
|
107
|
-
| ------ | ---- |
|
|
108
|
-
| `series-invalid-name` | シリーズのキーはあるが、空でない文字列になっていない。 |
|
|
109
|
-
| `series-missing-order` | 有効な数値の並び順キーが無く、代替の順序を使った。 |
|
|
110
|
-
| `series-duplicate-order` | 同じ `(シリーズ, 並び順)` の組を持つノートが複数ある。 |
|
|
111
|
-
|
|
112
|
-
## CSS フック
|
|
113
|
-
|
|
114
|
-
`style.css` は `.rb-series`、`.rb-series__title`、`.rb-series__position`、`.rb-series__list`、`.rb-series__item`、`.rb-series__nav`、`.rb-series__prev`、`.rb-series__next`、および `.rb-series--index` をスタイルします。現在の記事は `.rb-series__item a[aria-current="page"]` で判定できます。
|
|
115
|
-
|
|
116
|
-
## 制限
|
|
117
|
-
|
|
118
|
-
- 1つのノートが所属できるシリーズは1つだけです。
|
|
119
|
-
- 1件だけのシリーズにはナビゲーションを出力しません。
|
|
120
|
-
- `series_order` は有限の数値である必要があります。数値文字列は変換しません。
|
|
121
|
-
- シリーズ用のルートは生成しません。ランディングページを作る場合は `renderSeriesIndex()` を自前のページと組み合わせてください。
|
|
122
|
-
|
|
123
|
-
## 関連
|
|
124
|
-
|
|
125
|
-
- [プラグインガイド](../../../docs/ja/plugin-
|
|
1
|
+
# @riebeckite/plugin-series
|
|
2
|
+
|
|
3
|
+
連載記事(シリーズ)を順番どおりに並べ、各記事へ共通のナビゲーションを差し込むプラグインです。ビルド時に、同じシリーズ名を持つノートをまとめて、目次・現在位置・前後の記事リンクを生成します。
|
|
4
|
+
|
|
5
|
+
[English](./README.md)
|
|
6
|
+
|
|
7
|
+
## 概要
|
|
8
|
+
|
|
9
|
+
`series()` は frontmatter からシリーズ情報を読み取り、該当するノートをグループ化して並べ替えたうえで、各ノートの HTML に `<nav class="rb-series">` ブロックを追加します。リンクには Core が解決したパーマリンクを使うため、`permalink` プラグインなどとも併用できます。1件だけのシリーズにはナビゲーションを出力しません。
|
|
10
|
+
|
|
11
|
+
このプラグインはビルド時のみ動作し、クライアント用のランタイムは持ちません(スタイルシートのみを登録します)。
|
|
12
|
+
|
|
13
|
+
## 設定する
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { defineConfig } from "@riebeckite/core";
|
|
17
|
+
import { series } from "@riebeckite/plugin-series";
|
|
18
|
+
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
// ...
|
|
21
|
+
plugins: [series()],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## frontmatter の書き方
|
|
26
|
+
|
|
27
|
+
| キー | 型 | 必須 | 説明 |
|
|
28
|
+
| ---- | -- | ---- | ---- |
|
|
29
|
+
| `series` | `string` | はい | グループ化に使うシリーズ名。 |
|
|
30
|
+
| `series_order` | `number` | 推奨 | シリーズ内の並び順(昇順)。 |
|
|
31
|
+
| `series_title` | `string` | いいえ | 見出しに表示するシリーズ名。 |
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
---
|
|
35
|
+
title: 導入編
|
|
36
|
+
series: 何かを作る
|
|
37
|
+
series_order: 2
|
|
38
|
+
---
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`series_order` が無い・不正なノートも対象に含まれます。その場合は番号付きの記事の後ろに並び、`date`/`created`/`published`、`title`、`slug` の順で安定して並べ替えます。同点の場合は常に決まった順序になります。
|
|
42
|
+
|
|
43
|
+
## オプション
|
|
44
|
+
|
|
45
|
+
| オプション | 型 | 既定値 | 説明 |
|
|
46
|
+
| ---------- | -- | ------ | ---- |
|
|
47
|
+
| `key` | `string` | `"series"` | シリーズ名を持つ frontmatter キー。 |
|
|
48
|
+
| `orderKey` | `string` | `"series_order"` | 並び順の数値を持つ frontmatter キー。 |
|
|
49
|
+
| `titleKey` | `string` | `"series_title"` | 見出しのシリーズ名を上書きするキー。 |
|
|
50
|
+
| `heading` | `boolean` | `true` | リストの上に見出しを表示する。 |
|
|
51
|
+
| `className` | `string` | `"rb-series"` | 生成する HTML の基準クラス名。 |
|
|
52
|
+
| `positionLabel` | `boolean` | `false` | 現在の記事に「Part N of M」を付ける。 |
|
|
53
|
+
|
|
54
|
+
## 出力
|
|
55
|
+
|
|
56
|
+
2件以上あるシリーズの各ノートには、次のブロックが HTML の末尾に追加されます。
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<nav class="rb-series" data-series="何かを作る"
|
|
60
|
+
aria-label="Series navigation">
|
|
61
|
+
<p class="rb-series__title">
|
|
62
|
+
<a class="rb-series__link" href="/part-1">何かを作る</a>
|
|
63
|
+
</p>
|
|
64
|
+
<ol class="rb-series__list">
|
|
65
|
+
<li class="rb-series__item">
|
|
66
|
+
<a class="rb-series__link" href="/part-1" data-series-order="1">導入編</a>
|
|
67
|
+
</li>
|
|
68
|
+
<li class="rb-series__item">
|
|
69
|
+
<a class="rb-series__link" href="/part-2" data-series-order="2"
|
|
70
|
+
aria-current="page">実装編</a>
|
|
71
|
+
</li>
|
|
72
|
+
</ol>
|
|
73
|
+
<div class="rb-series__nav">
|
|
74
|
+
<a class="rb-series__prev" rel="prev" href="/part-1">← 導入編</a>
|
|
75
|
+
<a class="rb-series__next" rel="next" href="/part-3">仕上げ編 →</a>
|
|
76
|
+
</div>
|
|
77
|
+
</nav>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
テキストと属性はすべてエスケープします。生成した HTML は manifest の entry と処理済みコンテンツの両方へ書き戻すため、ページのルート表示・フィード・検索でも同じマークアップになります。
|
|
81
|
+
|
|
82
|
+
## 公開 API
|
|
83
|
+
|
|
84
|
+
- `series(options?)` / `seriesPlugin(options?)` — プラグインファクトリ
|
|
85
|
+
- `buildSeriesIndex(manifest, name, options?)` — 1つのシリーズの並び順付きメンバー(`SeriesIndex | null`)。ランディングページ向け
|
|
86
|
+
- `renderSeriesIndex(manifest, name, options?)` — シリーズ全体の `<section>` ブロック
|
|
87
|
+
- `renderSeriesNavigation(index, currentSlug, options?)` — ナビゲーション1つ分
|
|
88
|
+
- `collectSeriesIndexes(manifest, options?)` — 全シリーズを出現順で取得
|
|
89
|
+
- `resolveSeriesOptions(options?)` — 既定値を適用したオプション
|
|
90
|
+
- 型: `SeriesOptions`, `ResolvedSeriesOptions`, `SeriesMember`, `SeriesIndex`
|
|
91
|
+
|
|
92
|
+
### シリーズのランディングページ
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { buildSeriesIndex, renderSeriesIndex } from "@riebeckite/plugin-series";
|
|
96
|
+
|
|
97
|
+
// ルートコンポーネント内で、解決済みの manifest を使って:
|
|
98
|
+
const index = buildSeriesIndex(manifest, "何かを作る");
|
|
99
|
+
const html = renderSeriesIndex(manifest, "何かを作る");
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 診断
|
|
103
|
+
|
|
104
|
+
`pluginName: "series"`、`severity: "warning"` で出力します。
|
|
105
|
+
|
|
106
|
+
| コード | 意味 |
|
|
107
|
+
| ------ | ---- |
|
|
108
|
+
| `series-invalid-name` | シリーズのキーはあるが、空でない文字列になっていない。 |
|
|
109
|
+
| `series-missing-order` | 有効な数値の並び順キーが無く、代替の順序を使った。 |
|
|
110
|
+
| `series-duplicate-order` | 同じ `(シリーズ, 並び順)` の組を持つノートが複数ある。 |
|
|
111
|
+
|
|
112
|
+
## CSS フック
|
|
113
|
+
|
|
114
|
+
`style.css` は `.rb-series`、`.rb-series__title`、`.rb-series__position`、`.rb-series__list`、`.rb-series__item`、`.rb-series__nav`、`.rb-series__prev`、`.rb-series__next`、および `.rb-series--index` をスタイルします。現在の記事は `.rb-series__item a[aria-current="page"]` で判定できます。
|
|
115
|
+
|
|
116
|
+
## 制限
|
|
117
|
+
|
|
118
|
+
- 1つのノートが所属できるシリーズは1つだけです。
|
|
119
|
+
- 1件だけのシリーズにはナビゲーションを出力しません。
|
|
120
|
+
- `series_order` は有限の数値である必要があります。数値文字列は変換しません。
|
|
121
|
+
- シリーズ用のルートは生成しません。ランディングページを作る場合は `renderSeriesIndex()` を自前のページと組み合わせてください。
|
|
122
|
+
|
|
123
|
+
## 関連
|
|
124
|
+
|
|
125
|
+
- [プラグインガイド](../../../docs/ja/reference/plugin-api.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/plugin-series",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
"./style.css": "./style.css"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@riebeckite/core": "0.0.
|
|
18
|
+
"@riebeckite/core": "0.0.13"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"tsx": "^4.22.4",
|
|
22
|
-
"@riebeckite/test": "0.0.
|
|
22
|
+
"@riebeckite/test": "0.0.13"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"access": "public"
|