From 39ad1c56d2f9aecc2ff0c5bebfb7cef21cee577a Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Fri, 20 Sep 2024 19:42:09 +0800 Subject: [PATCH] feat(theme): add support post cover for blog post list (#196) --- .../src/client/components/Blog/VPPostItem.vue | 242 +++++++++++++----- .../src/client/components/Blog/VPPostList.vue | 1 + theme/src/client/components/VPLink.vue | 5 +- .../src/client/composables/blog-post-list.ts | 2 +- theme/src/node/prepare/prepareBlogData.ts | 1 + theme/src/shared/blog.ts | 41 +++ theme/src/shared/frontmatter/page.ts | 8 + theme/src/shared/frontmatter/post.ts | 8 +- 8 files changed, 240 insertions(+), 68 deletions(-) diff --git a/theme/src/client/components/Blog/VPPostItem.vue b/theme/src/client/components/Blog/VPPostItem.vue index 067f95ea2..4bda62efe 100644 --- a/theme/src/client/components/Blog/VPPostItem.vue +++ b/theme/src/client/components/Blog/VPPostItem.vue @@ -1,16 +1,22 @@ diff --git a/theme/src/client/components/Blog/VPPostList.vue b/theme/src/client/components/Blog/VPPostList.vue index 70a3104b4..790ebcae1 100644 --- a/theme/src/client/components/Blog/VPPostList.vue +++ b/theme/src/client/components/Blog/VPPostList.vue @@ -29,6 +29,7 @@ const { diff --git a/theme/src/client/components/VPLink.vue b/theme/src/client/components/VPLink.vue index b37e59467..72999a411 100644 --- a/theme/src/client/components/VPLink.vue +++ b/theme/src/client/components/VPLink.vue @@ -6,6 +6,7 @@ import { useLink } from '../composables/index.js' const props = defineProps<{ tag?: string href?: string + text?: string noIcon?: boolean target?: string rel?: string @@ -34,7 +35,9 @@ function linkTo(e: Event) { :rel="rel ?? (isExternal ? 'noreferrer' : undefined)" @click="linkTo($event)" > - + + {{ text || href }} + diff --git a/theme/src/client/composables/blog-post-list.ts b/theme/src/client/composables/blog-post-list.ts index b41085c40..d929d16f1 100644 --- a/theme/src/client/composables/blog-post-list.ts +++ b/theme/src/client/composables/blog-post-list.ts @@ -5,7 +5,7 @@ import { useData } from './data.js' import { useRouteQuery } from './route-query.js' import type { PlumeThemeBlogPostItem } from '../../shared/index.js' -const DEFAULT_PER_PAGE = 10 +const DEFAULT_PER_PAGE = 15 export function usePostListControl(homePage: Ref) { const { theme } = useData() diff --git a/theme/src/node/prepare/prepareBlogData.ts b/theme/src/node/prepare/prepareBlogData.ts index 8d6c162b8..6c0bf43fa 100644 --- a/theme/src/node/prepare/prepareBlogData.ts +++ b/theme/src/node/prepare/prepareBlogData.ts @@ -73,6 +73,7 @@ export async function preparedBlogData( createTime: page.data.frontmatter.createTime! || page.date?.replaceAll('-', '/') || '', lang: page.lang, excerpt: '', + cover: page.data.frontmatter.cover, } if (isEncryptPage(page, encrypt)) { diff --git a/theme/src/shared/blog.ts b/theme/src/shared/blog.ts index 3f9b1aedd..25bd5f29b 100644 --- a/theme/src/shared/blog.ts +++ b/theme/src/shared/blog.ts @@ -10,6 +10,7 @@ export interface PlumeThemeBlogPostItem { createTime: string lang: string encrypt?: boolean + cover?: string | BlogPostCover } export type PlumeThemeBlogPostData = PlumeThemeBlogPostItem[] @@ -98,4 +99,44 @@ export interface PlumeThemeBlog { * @default '/blog/categories/' */ categoriesLink?: string + + /** + * 博客文章封面图 + * + * 配置封面图的位置,支持 `'left'`、`'right'`、`'top'`、`'top-inside'` + * + * @default 'right' + */ + postCover?: BlogPostCoverLayout | Omit +} + +export type BlogPostCoverLayout = 'left' | 'right' | 'odd-left' | 'odd-right' | 'top' + +export interface BlogPostCover { + /** + * 封面图链接地址,只能使用 绝对路径 以及 远程图片地址 + */ + url: string + /** + * 博客文章封面图的位置 + */ + layout?: BlogPostCoverLayout + /** + * 博客文章封面图的比例 + * + * @default '4:3' + */ + ratio?: number | `${number}:${number}` | `${number}/${number}` + + /** + * 封面图的宽度, 仅在 layout 为 'left' 或 'right' 时生效 + * + * @default 240 + */ + width?: number + /** + * 是否使用紧凑模式,紧凑模式下,封面图紧贴容器边缘 + * @default false + */ + compact?: boolean } diff --git a/theme/src/shared/frontmatter/page.ts b/theme/src/shared/frontmatter/page.ts index 763422d6a..5a6cd5338 100644 --- a/theme/src/shared/frontmatter/page.ts +++ b/theme/src/shared/frontmatter/page.ts @@ -62,4 +62,12 @@ export interface PlumeThemePageFrontmatter extends PlumeNormalFrontmatter { * 或直接传入 svg 字符串 */ icon?: string | { svg: string } + + /** + * 标题徽章 + */ + badge?: string | { + text: string + type?: 'info' | 'tip' | 'warning' | 'danger' + } } diff --git a/theme/src/shared/frontmatter/post.ts b/theme/src/shared/frontmatter/post.ts index 43c18052a..65a83b19b 100644 --- a/theme/src/shared/frontmatter/post.ts +++ b/theme/src/shared/frontmatter/post.ts @@ -1,3 +1,4 @@ +import type { BlogPostCover } from 'vuepress-theme-plume' import type { PlumeThemePageFrontmatter } from './page.js' export interface PlumeThemePostFrontmatter extends PlumeThemePageFrontmatter { @@ -19,10 +20,7 @@ export interface PlumeThemePostFrontmatter extends PlumeThemePageFrontmatter { draft?: boolean /** - * 标题徽章 + * 文章封面图 */ - badge?: string | { - text: string - type?: 'info' | 'tip' | 'warning' | 'danger' - } + cover?: string | BlogPostCover }