@riebeckite/plugin-taxonomy 0.0.15 → 0.0.17

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
@@ -104,6 +104,8 @@ Folder terms get the same files under `/folders/<path>/…`. Feed channels carry
104
104
  their own term title and self link, so a tag subscription is distinguishable
105
105
  from the site-wide feeds owned by `@riebeckite/plugin-seo`. Only published,
106
106
  non-`noindex` entries reach the manifest's public view and therefore the feeds.
107
+ RSS and Atom term feeds expose entry summaries. JSON term feeds use the same
108
+ summary as `content_text` and do not duplicate rendered article HTML.
107
109
 
108
110
  ## Related tags
109
111
 
@@ -139,10 +141,12 @@ the folder's landing page.
139
141
 
140
142
  ## Page types
141
143
 
142
- `taxonomy()` registers `taxonomy-term`. Its SSG paths and resolver are derived
143
- from the public manifest, so unpublished entries never appear in tag or folder
144
- pages. The returned page body includes feed discovery `<link rel="alternate">`
145
- metadata, which the generic document frame renders in its head.
144
+ `taxonomy()` registers two page types. `taxonomy-term` renders one tag or
145
+ folder page and includes feed discovery `<link rel="alternate">` metadata.
146
+ `taxonomy-index` renders the all-tags list at `tagsBasePath` and the
147
+ all-folders list at `foldersBasePath`, linking to every term. Both derive
148
+ their SSG paths and resolver from the public manifest, so unpublished entries
149
+ never appear on a tag, folder, or index page.
146
150
 
147
151
  Use `pluginPageSsgParams(content)` and `resolveRiebeckiteRoute(content, path)`
148
152
  from `@riebeckite/honox/server` in the site's generic catch-all route. This is
@@ -167,6 +171,7 @@ import "@riebeckite/plugin-taxonomy/style.css";
167
171
  - `buildTaxonomyIndex(entries, options)` — build tag and folder terms
168
172
  - `serializeTaxonomyIndex(index)` / `serializeTaxonomyTerm(term)` — JSON-safe projections
169
173
  - `renderTaxonomyPage(term, options)` / `renderRelatedTerms(term, options)` — page fragments
174
+ - `renderTaxonomyIndexPage(kind, terms, options)` — all-tags/all-folders page fragment
170
175
  - `renderTermFeed(config, term, format, limit?)` / `buildFeedHeadTags(term)` — per-term feeds
171
176
  - `buildTaxonomySeo(config, term)` — listing-page SEO metadata
172
177
  - `slugifyTaxonomyValue(value)` — URL/file slug
@@ -185,4 +190,3 @@ import "@riebeckite/plugin-taxonomy/style.css";
185
190
 
186
191
  - [Plugin guide](../../../docs/en/docs/reference/plugin-api.md)
187
192
  - [Content system](../../../docs/en/docs/framework/content-system.md)
188
-
package/README_ja.md CHANGED
@@ -104,6 +104,8 @@ GET /taxonomy/index.json
104
104
  語ごとのタイトルと self link を持つため、タグの購読と
105
105
  `@riebeckite/plugin-seo` が持つサイト全体のフィードを区別できます。公開かつ
106
106
  `noindex` でないエントリだけがマニフェストの公開ビューに入り、フィードへ届きます。
107
+ 語ごとの RSS と Atom はエントリの要約を出します。語ごとの JSON Feed は同じ要約を
108
+ `content_text` として出し、描画済みの記事 HTML は複製しません。
107
109
 
108
110
  ## 関連タグ
109
111
 
@@ -138,10 +140,12 @@ taxonomy はマニフェストの公開ビューからタグ語とフォルダ
138
140
 
139
141
  ## Page Type
140
142
 
141
- `taxonomy()` は `taxonomy-term` を登録します。SSG のパスと resolver は公開
142
- マニフェストから作るため、非公開エントリがタグ・フォルダページへ入ることはありません。
143
- 返す page body にはフィード検出用の `<link rel="alternate">` メタデータを含め、
144
- 共通の document frame が head に描画します。
143
+ `taxonomy()` は 2 つの Page Type を登録します。`taxonomy-term` は 1 つのタグ・
144
+ フォルダページを描画し、フィード検出用の `<link rel="alternate">` メタデータを
145
+ 含みます。`taxonomy-index` は `tagsBasePath` に全タグ一覧、`foldersBasePath` に
146
+ 全フォルダ一覧を描画し、各語へリンクします。どちらも SSG のパスと resolver を
147
+ 公開マニフェストから作るため、非公開エントリがタグ・フォルダ・一覧ページへ
148
+ 入ることはありません。
145
149
 
146
150
  サイトの共通 catch-all route では、`@riebeckite/honox/server` の
147
151
  `pluginPageSsgParams(content)` と `resolveRiebeckiteRoute(content, path)` を使います。
@@ -166,6 +170,7 @@ import "@riebeckite/plugin-taxonomy/style.css";
166
170
  - `buildTaxonomyIndex(entries, options)` — タグ・フォルダ語を構築する
167
171
  - `serializeTaxonomyIndex(index)` / `serializeTaxonomyTerm(term)` — JSON 安全な射影
168
172
  - `renderTaxonomyPage(term, options)` / `renderRelatedTerms(term, options)` — ページ断片
173
+ - `renderTaxonomyIndexPage(kind, terms, options)` — 全タグ・全フォルダ一覧のページ断片
169
174
  - `renderTermFeed(config, term, format, limit?)` / `buildFeedHeadTags(term)` — 語ごとのフィード
170
175
  - `buildTaxonomySeo(config, term)` — 一覧ページの SEO メタデータ
171
176
  - `slugifyTaxonomyValue(value)` — URL・ファイル用の slug
@@ -185,4 +190,3 @@ import "@riebeckite/plugin-taxonomy/style.css";
185
190
 
186
191
  - [プラグインガイド](../../../docs/ja/docs/reference/plugin-api.md)
187
192
  - [コンテンツシステム](../../../docs/ja/docs/framework/content-system.md)
188
-
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { ResolvedTaxonomyOptions, TaxonomyOptions } from "./src/types.js";
3
3
  export { buildTaxonomyIndex, serializeTaxonomyIndex, serializeTaxonomyTerm, toEntryReference, } from "./src/collections.js";
4
4
  export { buildFeedHeadTags, renderTermFeed } from "./src/feeds.js";
5
5
  export { DEFAULT_TAXONOMY_CLASS_NAME, DEFAULT_TAXONOMY_DATA_ENDPOINT, DEFAULT_TAXONOMY_FEED_LIMIT, DEFAULT_TAXONOMY_FOLDERS_BASE_PATH, DEFAULT_TAXONOMY_MIN_ENTRIES, DEFAULT_TAXONOMY_RELATED_LIMIT, DEFAULT_TAXONOMY_TAGS_BASE_PATH, resolveTaxonomyOptions, } from "./src/options.js";
6
- export { renderRelatedTerms, renderTaxonomyPage } from "./src/pages.js";
6
+ export { renderRelatedTerms, renderTaxonomyIndexPage, renderTaxonomyPage, } from "./src/pages.js";
7
7
  export { buildTaxonomySeo } from "./src/seo.js";
8
8
  export { slugifyTaxonomyValue } from "./src/slug.js";
9
9
  export type { ResolvedTaxonomyOptions, TaxonomyEntryReference, TaxonomyFeedFormat, TaxonomyFeedLinks, TaxonomyFeedOptions, TaxonomyHeadTag, TaxonomyIndex, TaxonomyIndexData, TaxonomyKind, TaxonomyOptions, TaxonomyPage, TaxonomyRelatedTerm, TaxonomyTerm, TaxonomyTermContext, TaxonomyTermData, } from "./src/types.js";
package/dist/index.js CHANGED
@@ -285,7 +285,7 @@ function renderJson(config, term, entries, title) {
285
285
  id: url,
286
286
  url,
287
287
  title: entry.title,
288
- content_html: entry.html,
288
+ content_text: getDescription(entry),
289
289
  summary: getDescription(entry),
290
290
  date_published: getPublishedTime(entry) ?? void 0,
291
291
  date_modified: getUpdatedTime(entry) ?? void 0,
@@ -296,8 +296,8 @@ function renderJson(config, term, entries, title) {
296
296
  }
297
297
  function getResolvedFeedMetadata(config) {
298
298
  return {
299
- description: config.site.feed.description ?? config.site.description,
300
- language: config.site.feed.language ?? config.site.locale.replace("_", "-")
299
+ description: config.site.feed.description,
300
+ language: config.site.feed.language
301
301
  };
302
302
  }
303
303
  function getDescription(entry) {
@@ -421,6 +421,26 @@ function renderRelatedTerms(term, options) {
421
421
  ).join("");
422
422
  return `<nav class="${className}__related" aria-label="Related tags" data-rr-taxonomy-related><ul>${items}</ul></nav>`;
423
423
  }
424
+ function renderTaxonomyIndexPage(kind, terms, options) {
425
+ const className = escapeHtmlAttribute(options.className);
426
+ const label = kind === "tag" ? "Tags" : "Folders";
427
+ const items = terms.map(
428
+ (term) => `<li class="${className}__item"><a class="${className}__link" href="${escapeHtmlAttribute(
429
+ term.path
430
+ )}" data-rr-taxonomy-count="${term.entries.length}">${escapeHtml(
431
+ term.title
432
+ )}</a></li>`
433
+ ).join("");
434
+ const html = `<section class="${className} ${className}--index" data-rr-taxonomy-index="${kind}"><h1 class="${className}__title">${escapeHtml(
435
+ label
436
+ )}</h1><ul class="${className}__list">${items}</ul></section>`;
437
+ return {
438
+ title: label,
439
+ frontmatter: { title: label },
440
+ html,
441
+ headTags: []
442
+ };
443
+ }
424
444
  function renderFeedLinks(term, className) {
425
445
  const links = [];
426
446
  if (term.feeds.rss) {
@@ -506,6 +526,30 @@ function taxonomy(options = {}) {
506
526
  headTags: page.headTags
507
527
  };
508
528
  }
529
+ },
530
+ {
531
+ id: "taxonomy-index",
532
+ paths: () => taxonomyIndexPagePaths(resolved),
533
+ outputDependencies: [{ type: "global" }],
534
+ resolve: ({ manifest, pathname }) => {
535
+ const kind = resolveTaxonomyIndexPath(pathname, resolved);
536
+ if (!kind) return null;
537
+ const index = buildTaxonomyIndex(
538
+ manifest.discoverableEntries,
539
+ resolved
540
+ );
541
+ const page = renderTaxonomyIndexPage(
542
+ kind,
543
+ kind === "tag" ? index.tags : index.folders,
544
+ resolved
545
+ );
546
+ return {
547
+ type: "taxonomy-index",
548
+ pathname,
549
+ title: page.title,
550
+ body: page.html
551
+ };
552
+ }
509
553
  }
510
554
  ],
511
555
  buildEnd(context) {
@@ -539,6 +583,25 @@ function findTaxonomyTerm(entries, options, pathname) {
539
583
  (term) => term.path === pathname
540
584
  );
541
585
  }
586
+ function taxonomyIndexPagePaths(options) {
587
+ const paths = [];
588
+ if (options.tags && options.tagsBasePath !== "") {
589
+ paths.push(options.tagsBasePath);
590
+ }
591
+ if (options.folders && options.foldersBasePath !== "") {
592
+ paths.push(options.foldersBasePath);
593
+ }
594
+ return [...new Set(paths)];
595
+ }
596
+ function resolveTaxonomyIndexPath(pathname, options) {
597
+ if (options.tags && options.tagsBasePath !== "" && pathname === options.tagsBasePath) {
598
+ return "tag";
599
+ }
600
+ if (options.folders && options.foldersBasePath !== "" && pathname === options.foldersBasePath) {
601
+ return "folder";
602
+ }
603
+ return null;
604
+ }
542
605
  function resolveTaxonomyOptionsFromConfig(config) {
543
606
  const plugin = resolvePlugins2(config.plugins).find(
544
607
  (candidate) => candidate.name === TAXONOMY_PLUGIN_NAME
@@ -651,6 +714,7 @@ export {
651
714
  buildTaxonomyIndex,
652
715
  buildTaxonomySeo,
653
716
  renderRelatedTerms,
717
+ renderTaxonomyIndexPage,
654
718
  renderTaxonomyPage,
655
719
  renderTermFeed,
656
720
  resolveTaxonomyOptions,
@@ -1,4 +1,4 @@
1
- import type { ResolvedTaxonomyOptions, TaxonomyPage, TaxonomyTerm } from "./types.js";
1
+ import type { ResolvedTaxonomyOptions, TaxonomyKind, TaxonomyPage, TaxonomyTerm } from "./types.js";
2
2
  /**
3
3
  * Renders a taxonomy listing page fragment. The fragment owns the listing and
4
4
  * related-term navigation only; the Site's route and layout wrap it (see the
@@ -7,3 +7,4 @@ import type { ResolvedTaxonomyOptions, TaxonomyPage, TaxonomyTerm } from "./type
7
7
  export declare function renderTaxonomyPage(term: TaxonomyTerm, options: ResolvedTaxonomyOptions): TaxonomyPage;
8
8
  /** Renders only the related-term navigation for a tag term. */
9
9
  export declare function renderRelatedTerms(term: TaxonomyTerm, options: ResolvedTaxonomyOptions): string;
10
+ export declare function renderTaxonomyIndexPage(kind: TaxonomyKind, terms: readonly TaxonomyTerm[], options: ResolvedTaxonomyOptions): TaxonomyPage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-taxonomy",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
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.15"
18
+ "@riebeckite/core": "0.0.17"
19
19
  },
20
20
  "devDependencies": {
21
21
  "tsx": "^4.22.4"
package/style.css CHANGED
@@ -99,9 +99,3 @@
99
99
  border-color: var(--rr-taxonomy-accent);
100
100
  color: var(--rr-taxonomy-accent);
101
101
  }
102
-
103
- html[data-theme="dark"] .rr-taxonomy,
104
- html.dark .rr-taxonomy {
105
- --rr-taxonomy-ink: var(--rb-color-paper, #ffffff);
106
- --rr-taxonomy-muted: var(--rb-color-muted, #a8a29a);
107
- }