705 字
4 分钟
在博客中添加系列栏
2024-10-23
2024-10-25

如果是同一个系列(series)的文章,在名片栏下方增加一个系列栏,显示系列内所有文章的链接

改动点#

  1. 修改📁i18n里的文件,增加seriesKey
src\i18n\i18nKey.ts
ts
enum I18nKey {
    // ...
    series = 'series', 
}

export default I18nKey
src\i18n\languages\en.ts
ts
export const en: Translation = {
    // ...
    [Key.series]: 'Series', 
}
src\i18n\languages\es.ts
ts
export const es: Translation = {
    // ...
    [Key.series]: 'Serie', 
}
src\i18n\languages\ja.ts
ts
export const ja: Translation = {
    // ...
    [Key.series]: 'シリーズ', 
}
src\i18n\languages\ko.ts
ts
export const ko: Translation = {
    // ...
    [Key.series]: '시리즈', 
}
src\i18n\languages\zh_CN.ts
ts
export const zh_CN: Translation = {
    // ...
    [Key.series]: '系列', 
}
src\i18n\languages\zh_TW.ts
ts
export const zh_TW: Translation = {
    // ...
    [Key.series]: '系列', 
}
  1. 在两个config文件里增加series字段
src\types\config.ts
ts
export type BlogPostData = {
  // ...
  series?: string
  prevTitle?: string
  prevSlug?: string
  nextTitle?: string
  nextSlug?: string
}
src\content\config.ts
ts
const postsCollection = defineCollection({
  schema: z.object({
    // ...
    lang: z.string().optional().default(''),
    series: z.string().optional(), 

    /* For internal use */
    prevTitle: z.string().default(''),
    // ...
  }),
})
  1. 修改[...slug]页面,将series传入MainGridLayout组件
src\pages\posts[...slug].astro
astro
<MainGridLayout banner={entry.data.image} title={entry.data.title} 
    description={entry.data.description} lang={entry.data.lang} 
    setOGTypeArticle={true} series={entry.data.series}>
    
</MainGridLayout>
  1. 修改MainGridLayout组件里的三处代码,接收series并将其传入SideBar组件
src\layouts\MainGridLayout.astro
astro
---
interface Props {
  title?: string
  banner?: string
  description?: string
  lang?: string
  setOGTypeArticle?: boolean;
  series?: string
}

const { title, banner, description, lang, setOGTypeArticle, series } = Astro.props
---

<SideBar class="mb-4 row-start-2 row-end-3 col-span-2 lg:row-start-1 lg:row-end-2 lg:col-span-1 lg:max-w-[17.5rem] onload-animation" 
    series={ series }>
</SideBar>
  1. content-utils.ts里添加getPostSeries方法
src\utils\content-utils.ts
ts
export async function getPostSeries(
  seriesName: string,
): Promise<{ body: string; data: BlogPostData; slug: string }[]> {
  const posts = (await getCollection('posts', ({ data }) => {
    return (
      (import.meta.env.PROD ? data.draft !== true : true) &&
      data.series === seriesName
    )
  })) as unknown as { body: string; data: BlogPostData; slug: string }[]

  return posts
}
  1. 📁widget里新增Series组件
src\components\widget\Series.astro
astro
---
import I18nKey from '../../i18n/i18nKey'
import { i18n } from '../../i18n/translation'
import { getPostSeries } from '../../utils/content-utils'
import { getPostUrlBySlug } from '../../utils/url-utils'
import WidgetLayout from './WidgetLayout.astro'

const COLLAPSED_HEIGHT = '7.5rem'

interface Props {
  class?: string
  style?: string
  series: string
}
const className = Astro.props.class
const style = Astro.props.style
const seriesName = Astro.props.series

const series = await getPostSeries(seriesName)

const isCollapsed = series.length >= 10
---
<WidgetLayout name={i18n(I18nKey.series) + " - " + series[0].data.series} id="series" isCollapsed={isCollapsed} collapsedHeight={COLLAPSED_HEIGHT} class={className} style={style}>
    <div class="flex flex-col gap-1">
        {series.map(t => (
            <a href={getPostUrlBySlug(t.slug)}
                aria-label={t.data.title}
                class="group btn-plain h-10 w-full rounded-lg hover:text-[initial]"
            >
                <!-- dot and line -->
                <div class="w-[15%] md:w-[10%] relative dash-line h-full flex items-center">
                    <div class="transition-all mx-auto w-1 h-1 rounded group-hover:h-5
                    bg-[oklch(0.5_0.05_var(--hue))] group-hover:bg-[var(--primary)]
                    outline outline-4 z-50
                    outline-[var(--card-bg)]
                    group-hover:outline-[var(--btn-plain-bg-hover)]
                    group-active:outline-[var(--btn-plain-bg-active)]
                    "
                    ></div>
                </div>
                <!-- post title -->
                <div class="w-[85%] text-left font-bold
                    group-hover:translate-x-1 transition-all group-hover:text-[var(--primary)]
                    text-75 pr-8 whitespace-nowrap overflow-ellipsis overflow-hidden"
                >
                        {t.data.title}
                </div>
            </a>
        ))}
    </div>
</WidgetLayout>
  1. SideBar组件中导入Series组件,接收series并将其出入Series组件
src\components\widget\SideBar.astro
astro
---
import Categories from './Categories.astro'
import Profile from './Profile.astro'
import Series from './Series.astro'
import Tag from './Tags.astro'

interface Props { 
  class?: string
  series?: string
} 

const { className } = Astro.props 
const className = Astro.props.class 
const series = Astro.props.series 
---
<div id="sidebar" class:list={[className, "w-full"]}>
    <div class="flex flex-col w-full gap-4 mb-4">
        <Profile></Profile>
    </div>
    <div id="sidebar-sticky" class="transition-all duration-700 flex flex-col w-full gap-4 top-4 sticky top-4">
        <div id="series" class="flex flex-col w-full gap-4">
            { series && <Series series={ series }></Series> }
        </div>
        <Categories class="onload-animation" style="animation-delay: 150ms"></Categories>
        <Tag class="onload-animation" style="animation-delay: 200ms"></Tag>
    </div>
</div>
  1. 在 swup 的 containers 配置项里加上#series
astro.config.mjs
js
export default defineConfig({
  integrations: [
    swup({
      theme: false,
      animationClass: "transition-swup-", // see https://swup.js.org/options/#animationselector
      // the default value `transition-` cause transition delay
      // when the Tailwind class `transition-all` is used
      containers: ["main", "#series"],
      smoothScrolling: true,
      cache: true,
      preload: true,
      accessibility: true,
      updateHead: true,
      updateBodyClass: false,
      globalInstance: true,
    }),
  ],
});
在博客中添加系列栏
https://ikamusume7.org/posts/前端/在博客中添加系列栏/
作者
伊卡
发布于
2024-10-23
更新于
2024-10-25
许可协议
CC BY-NC-SA 4.0