@riebeckite/plugin-taxonomy 0.0.12 → 0.0.14

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 CHANGED
@@ -17,11 +17,10 @@ listing terms with the Core collection contract (`buildContentCollections`):
17
17
  Entries always link through their resolved `permalink`; the plugin never
18
18
  reconstructs a URL from a slug.
19
19
 
20
- The plugin owns data, feeds, and SEO only. It deliberately does **not** register
21
- application routes. Per-term feeds are written as static files through the
22
- build's generated-output sink, and an app renders `/tags/<tag>` and
23
- `/folders/<path>` from the exported helpers (see
24
- [App-route wiring](#app-route-wiring)).
20
+ The plugin owns data, feeds, SEO, and the `/tags/<tag>` and `/folders/<path>`
21
+ page types. Per-term feeds are written as static files through the build's
22
+ generated-output sink. A site renders the page types through its generic
23
+ Riebeckite catch-all route; no taxonomy-specific application route is needed.
25
24
 
26
25
  ## Usage
27
26
 
@@ -140,52 +139,16 @@ chosen permalink is recorded as `metadata["taxonomy.folder"]`. A location is
140
139
  never claimed when another note already owns it; the conflict is reported as a
141
140
  diagnostic instead.
142
141
 
143
- ## App-route wiring
144
-
145
- The application owns routing. Register the listing paths in the app and render
146
- them from the plugin's data:
147
-
148
- ```tsx
149
- // app/routes/tags/[slug{.+}].tsx
150
- import { ssgParams } from "hono/ssg";
151
- import { createRoute } from "honox/factory";
152
- import {
153
- buildTaxonomyIndex,
154
- buildTaxonomySeo,
155
- renderTaxonomyPage,
156
- resolveTaxonomyOptionsFromConfig,
157
- } from "@riebeckite/plugin-taxonomy";
158
- import Article from "../../components/article/article";
159
- import { config } from "../../config";
160
- import { content } from "../../content";
161
-
162
- export default createRoute(
163
- ssgParams(async () => {
164
- const options = resolveTaxonomyOptionsFromConfig(config);
165
- const manifest = await content.getManifest();
166
- return buildTaxonomyIndex(manifest.publicEntries, options).tags.map(
167
- (term) => ({ slug: term.path.replace(/^\/tags\//, "") }),
168
- );
169
- }),
170
- async (c) => {
171
- const options = resolveTaxonomyOptionsFromConfig(config);
172
- const manifest = await content.getManifest();
173
- const term = buildTaxonomyIndex(manifest.publicEntries, options).tags.find(
174
- (candidate) => candidate.path === c.req.path,
175
- );
176
- c.set("seo", term ? buildTaxonomySeo(config, term) : undefined);
177
- if (!term) return c.notFound();
178
- const page = renderTaxonomyPage(term, options);
179
- c.set("headTags", page.headTags);
180
- return c.render(<Article content={page} />);
181
- },
182
- );
183
- ```
142
+ ## Page types
143
+
144
+ `taxonomy()` registers `taxonomy-term`. Its SSG paths and resolver are derived
145
+ from the public manifest, so unpublished entries never appear in tag or folder
146
+ pages. The returned page body includes feed discovery `<link rel="alternate">`
147
+ metadata, which the generic document frame renders in its head.
184
148
 
185
- A folder route follows the same shape with `.folders` and `/folders/`. The
186
- `renderTaxonomyPage` result is `PostContent`-compatible (`frontmatter` + `html`),
187
- so it drops into the reference `Article` primitive; `headTags` adds the feed
188
- discovery `<link rel="alternate">` elements to the document head.
149
+ Use `pluginPageSsgParams(content)` and `resolveRiebeckiteRoute(content, path)`
150
+ from `@riebeckite/honox/server` in the site's generic catch-all route. This is
151
+ the same wiring used for every plugin page type.
189
152
 
190
153
  ## Style
191
154
 
@@ -223,5 +186,5 @@ import "@riebeckite/plugin-taxonomy/style.css";
223
186
 
224
187
  ## See also
225
188
 
226
- - [Plugin guide](../../../docs/en/plugin-system.md)
227
- - [Content system](../../../docs/en/content-system.md)
189
+ - [Plugin guide](../../../docs/en/reference/plugin-api.md)
190
+ - [Content system](../../../docs/en/framework/content-system.md)
package/README_ja.md CHANGED
@@ -17,11 +17,11 @@ Riebeckite のビルド時タクソノミー(タグ・フォルダ)プラグ
17
17
  エントリのリンクには常に解決済みの `permalink` を使い、slug から URL を組み立てる
18
18
  ことはありません。
19
19
 
20
- このプラグインが持つのはデータ・フィード・SEO だけです。アプリケーションの
21
- ルートは登録しません。語ごとのフィードはビルドの generated-output sink 経由で
22
- 静的ファイルとして出力し、`/tags/<tag>` と `/folders/<path>` のページは
23
- エクスポートしたヘルパーを使ってアプリ側で描画します
24
- ([アプリルートの配線](#アプリルートの配線) を参照)。
20
+ このプラグインはデータ・フィード・SEO に加え、`/tags/<tag>` と
21
+ `/folders/<path>` の Page Type を提供します。語ごとのフィードは build の
22
+ generated-output sink 経由で静的ファイルとして出力します。サイトは共通の
23
+ Riebeckite catch-all route で Page Type を描画するため、taxonomy 専用の
24
+ アプリケーションルートは不要です。
25
25
 
26
26
  ## 使い方
27
27
 
@@ -137,52 +137,16 @@ Core `seo` 拡張ポイント(たとえば `@riebeckite/plugin-seo`)へ委
137
137
  選ばれた permalink は `metadata["taxonomy.folder"]` に記録されます。すでに他の
138
138
  ノートが所有している location は決して奪わず、衝突は診断として報告します。
139
139
 
140
- ## アプリルートの配線
141
-
142
- ルーティングはアプリケーションが所有します。一覧パスをアプリに登録し、プラグインの
143
- データから描画してください。
144
-
145
- ```tsx
146
- // app/routes/tags/[slug{.+}].tsx
147
- import { ssgParams } from "hono/ssg";
148
- import { createRoute } from "honox/factory";
149
- import {
150
- buildTaxonomyIndex,
151
- buildTaxonomySeo,
152
- renderTaxonomyPage,
153
- resolveTaxonomyOptionsFromConfig,
154
- } from "@riebeckite/plugin-taxonomy";
155
- import Article from "../../components/article/article";
156
- import { config } from "../../config";
157
- import { content } from "../../content";
158
-
159
- export default createRoute(
160
- ssgParams(async () => {
161
- const options = resolveTaxonomyOptionsFromConfig(config);
162
- const manifest = await content.getManifest();
163
- return buildTaxonomyIndex(manifest.publicEntries, options).tags.map(
164
- (term) => ({ slug: term.path.replace(/^\/tags\//, "") }),
165
- );
166
- }),
167
- async (c) => {
168
- const options = resolveTaxonomyOptionsFromConfig(config);
169
- const manifest = await content.getManifest();
170
- const term = buildTaxonomyIndex(manifest.publicEntries, options).tags.find(
171
- (candidate) => candidate.path === c.req.path,
172
- );
173
- c.set("seo", term ? buildTaxonomySeo(config, term) : undefined);
174
- if (!term) return c.notFound();
175
- const page = renderTaxonomyPage(term, options);
176
- c.set("headTags", page.headTags);
177
- return c.render(<Article content={page} />);
178
- },
179
- );
180
- ```
140
+ ## Page Type
141
+
142
+ `taxonomy()` は `taxonomy-term` を登録します。SSG のパスと resolver は公開
143
+ マニフェストから作るため、非公開エントリがタグ・フォルダページへ入ることはありません。
144
+ 返す page body にはフィード検出用の `<link rel="alternate">` メタデータを含め、
145
+ 共通の document frame が head に描画します。
181
146
 
182
- フォルダのルートも `.folders` と `/folders/` に置き換えると同じ形です。
183
- `renderTaxonomyPage` の戻り値は `PostContent` 互換(`frontmatter` + `html`)なので、
184
- 参照アプリの `Article` primitive にそのまま渡せます。`headTags` はフィード検出用の
185
- `<link rel="alternate">` を document head に追加します。
147
+ サイトの共通 catch-all route では、`@riebeckite/honox/server` の
148
+ `pluginPageSsgParams(content)` と `resolveRiebeckiteRoute(content, path)` を使います。
149
+ これはすべての Plugin Page Type に共通の配線です。
186
150
 
187
151
  ## スタイル
188
152
 
@@ -221,5 +185,5 @@ import "@riebeckite/plugin-taxonomy/style.css";
221
185
 
222
186
  ## 関連
223
187
 
224
- - [プラグインガイド](../../../docs/ja/plugin-system.md)
225
- - [コンテンツシステム](../../../docs/ja/content-system.md)
188
+ - [プラグインガイド](../../../docs/ja/reference/plugin-api.md)
189
+ - [コンテンツシステム](../../../docs/ja/framework/content-system.md)
package/dist/index.d.ts CHANGED
@@ -14,11 +14,10 @@ export declare const TAXONOMY_PLUGIN_NAME = "taxonomy";
14
14
  * Build-time taxonomy data, per-term feeds, SEO metadata, and folder-index
15
15
  * locations for Riebeckite.
16
16
  *
17
- * The plugin owns data, feeds, and SEO only. It does not register application
18
- * routes: an app renders `/tags/<tag>` and `/folders/<path>` from the exported
19
- * helpers (see the README for the documented wiring). Per-term feeds are
20
- * emitted as static files through the build's generated-output sink, so no
21
- * client JavaScript is required.
17
+ * The plugin owns data, feeds, SEO, and tag/folder page types. A generic site
18
+ * catch-all resolves those page types, so this plugin never needs application
19
+ * routes. Per-term feeds are emitted as static files through the build's
20
+ * generated-output sink, so no client JavaScript is required.
22
21
  */
23
22
  export declare function taxonomy(options?: TaxonomyOptions): import("@riebeckite/core").RiebeckitePlugin<TaxonomyOptions>;
24
23
  /** Alias matching the `*Plugin` suffix used by other plugin factories. */
package/dist/index.js CHANGED
@@ -529,6 +529,28 @@ function taxonomy(options = {}) {
529
529
  validateOptions: validateTaxonomyOptions,
530
530
  resolveContentLocations: ({ entries, diagnostics }) => resolveFolderIndexLocations(entries, resolved, diagnostics),
531
531
  endpoints: createTaxonomyEndpoints(resolved),
532
+ pageTypes: [
533
+ {
534
+ id: "taxonomy-term",
535
+ paths: ({ manifest }) => taxonomyPagePaths(manifest.publicEntries, resolved),
536
+ resolve: ({ manifest, pathname }) => {
537
+ const term = findTaxonomyTerm(
538
+ manifest.publicEntries,
539
+ resolved,
540
+ pathname
541
+ );
542
+ if (!term) return null;
543
+ const page = renderTaxonomyPage(term, resolved);
544
+ return {
545
+ type: "taxonomy-term",
546
+ pathname: term.path,
547
+ title: page.title,
548
+ body: page.html,
549
+ headTags: page.headTags
550
+ };
551
+ }
552
+ }
553
+ ],
532
554
  buildEnd(context) {
533
555
  const { config, manifest } = context;
534
556
  if (!config) return;
@@ -549,6 +571,16 @@ function taxonomy(options = {}) {
549
571
  });
550
572
  }
551
573
  var taxonomyPlugin = taxonomy;
574
+ function taxonomyPagePaths(entries, options) {
575
+ const index = buildTaxonomyIndex(entries, options);
576
+ return [...index.tags, ...index.folders].map((term) => term.path);
577
+ }
578
+ function findTaxonomyTerm(entries, options, pathname) {
579
+ const index = buildTaxonomyIndex(entries, options);
580
+ return [...index.tags, ...index.folders].find(
581
+ (term) => term.path === pathname
582
+ );
583
+ }
552
584
  function resolveTaxonomyOptionsFromConfig(config) {
553
585
  const plugin = resolvePlugins2(config.plugins).find(
554
586
  (candidate) => candidate.name === TAXONOMY_PLUGIN_NAME
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-taxonomy",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,7 +15,7 @@
15
15
  "./style.css": "./style.css"
16
16
  },
17
17
  "dependencies": {
18
- "@riebeckite/core": "0.0.12"
18
+ "@riebeckite/core": "0.0.14"
19
19
  },
20
20
  "devDependencies": {
21
21
  "tsx": "^4.22.4"