diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-09-15 22:01:29 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-09-15 22:01:29 +0900 |
| commit | dea594c6dda0f84ee3ebf6982ea1c98ff760bf71 (patch) | |
| tree | f335463efbd05962e80a07ee6ea3497ea7c2a849 | |
| parent | 2d287d60868a5059ad3ba3938ef0972ead0ff066 (diff) | |
SocialShare: X投稿のキャプションをページごとに生成
| -rw-r--r-- | src/components/SocialShare.astro | 11 | ||||
| -rw-r--r-- | src/components/starlight/Footer.astro | 9 | ||||
| -rw-r--r-- | src/utils/share-caption.ts | 37 |
3 files changed, 50 insertions, 7 deletions
diff --git a/src/components/SocialShare.astro b/src/components/SocialShare.astro index f3be8e8..a375884 100644 --- a/src/components/SocialShare.astro +++ b/src/components/SocialShare.astro @@ -2,7 +2,7 @@ export interface Props { /** Page URL (defaults to current page) */ url?: string; - /** Page title */ + /** 共有時のキャプション(ページを表す文言) */ title?: string; } @@ -11,12 +11,11 @@ const pageUrl = url ?? Astro.url.href; const pageTitle = title ?? ""; const encodedUrl = encodeURIComponent(pageUrl); -const encodedTitle = encodeURIComponent(pageTitle); -const siteCredits = encodeURIComponent("小平市議 安竹洋平"); +const siteCredits = "小平市議 安竹洋平"; -const xText = encodedTitle - ? `${encodedTitle}%20%7C%20${siteCredits}` - : siteCredits; +const xText = encodeURIComponent( + pageTitle ? `${siteCredits} ${pageTitle}` : siteCredits, +); const SHARE_LINKS = [ { diff --git a/src/components/starlight/Footer.astro b/src/components/starlight/Footer.astro index 7c3871c..5b59d09 100644 --- a/src/components/starlight/Footer.astro +++ b/src/components/starlight/Footer.astro @@ -5,10 +5,17 @@ import Pagination from 'virtual:starlight/components/Pagination'; import config from 'virtual:starlight/user-config'; import { Icon } from '@astrojs/starlight/components'; import SocialShare from '../SocialShare.astro'; +import { shareCaption } from '../../utils/share-caption'; + +const route = Astro.locals.starlightRoute; +const caption = shareCaption( + route.entry?.slug || route.id || '', + route.entry?.data?.title, +); --- <footer class="sl-flex"> - <SocialShare /> + <SocialShare title={caption} /> <div class="meta sl-flex"> <EditLink /> diff --git a/src/utils/share-caption.ts b/src/utils/share-caption.ts new file mode 100644 index 0000000..73315cc --- /dev/null +++ b/src/utils/share-caption.ts @@ -0,0 +1,37 @@ +/** + * ページのスラッグとタイトルから、X などで共有するときのキャプションを組み立てる。 + * + * 一般質問ページは、どの年度・月定例会のものかがキャプションだけで分かるよう、 + * スラッグ(例: ippan-situmon/r8d/9gatu)から文言を自動生成する。 + * それ以外のページはフロントマターの title をそのまま使う。 + */ +const REIWA_RE = /^r(\d+)d$/; +const MONTH_RE = /^(\d+)gatu$/; + +function reiwaYear(n: string): string { + return `令和${n === "1" ? "元" : n}年`; +} + +export function shareCaption(slug: string, title?: string): string { + const parts = slug.split("/").filter(Boolean); + + // トップページは「小平市議 安竹洋平」のみにする + if (parts.length === 0) return ""; + + if (parts[0] === "ippan-situmon") { + if (parts.length === 1) return "安竹洋平の一般質問一覧"; + + const year = parts[1]?.match(REIWA_RE); + if (!year) return title ?? ""; + if (parts.length === 2) return `${reiwaYear(year[1])}度の一般質問一覧`; + + const month = parts[2]?.match(MONTH_RE); + if (!month) return title ?? ""; + const session = `${reiwaYear(year[1])}${month[1]}月定例会`; + + if (parts.length === 3) return `${session}一般質問一覧`; + return title ? `${session}一般質問${title}` : `${session}一般質問`; + } + + return title ?? ""; +} |
