@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 +9 -5
- package/README_ja.md +9 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +67 -3
- package/dist/src/pages.d.ts +2 -1
- package/package.json +2 -2
- package/style.css +0 -6
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
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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()` は
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
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
|
|
300
|
-
language: config.site.feed.language
|
|
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,
|
package/dist/src/pages.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
-
}
|