From 9cb559a48da160ee6bb6a5812820d24e4c7025fa Mon Sep 17 00:00:00 2001 From: javayhu Date: Mon, 9 Jun 2025 00:17:09 +0800 Subject: [PATCH] cf: test remove docs and blog pages and content --- content/author/fox.mdx | 5 - content/author/fox.zh.mdx | 5 - content/author/mkdirs.mdx | 5 - content/author/mkdirs.zh.mdx | 5 - content/author/mksaas.mdx | 5 - content/author/mksaas.zh.mdx | 5 - content/category/company.mdx | 5 - content/category/company.zh.mdx | 5 - content/category/news.mdx | 5 - content/category/news.zh.mdx | 5 - content/category/product.mdx | 5 - content/category/product.zh.mdx | 5 - .../blog/(blog)/category/[slug]/page.tsx | 73 ----- .../category/[slug]/page/[page]/page.tsx | 84 ------ .../(marketing)/blog/(blog)/layout.tsx | 42 --- .../(marketing)/blog/(blog)/loading.tsx | 5 - .../[locale]/(marketing)/blog/(blog)/page.tsx | 45 --- .../blog/(blog)/page/[page]/page.tsx | 65 ----- .../(marketing)/blog/[...slug]/layout.tsx | 10 - .../(marketing)/blog/[...slug]/page.tsx | 256 ------------------ 20 files changed, 640 deletions(-) delete mode 100644 content/author/fox.mdx delete mode 100644 content/author/fox.zh.mdx delete mode 100644 content/author/mkdirs.mdx delete mode 100644 content/author/mkdirs.zh.mdx delete mode 100644 content/author/mksaas.mdx delete mode 100644 content/author/mksaas.zh.mdx delete mode 100644 content/category/company.mdx delete mode 100644 content/category/company.zh.mdx delete mode 100644 content/category/news.mdx delete mode 100644 content/category/news.zh.mdx delete mode 100644 content/category/product.mdx delete mode 100644 content/category/product.zh.mdx delete mode 100644 src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page/[page]/page.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/(blog)/layout.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/(blog)/loading.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/(blog)/page.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/(blog)/page/[page]/page.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/[...slug]/layout.tsx delete mode 100644 src/app/[locale]/(marketing)/blog/[...slug]/page.tsx diff --git a/content/author/fox.mdx b/content/author/fox.mdx deleted file mode 100644 index 6151ce7..0000000 --- a/content/author/fox.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: fox -name: Fox -avatar: /images/avatars/fox.png ---- diff --git a/content/author/fox.zh.mdx b/content/author/fox.zh.mdx deleted file mode 100644 index 6151ce7..0000000 --- a/content/author/fox.zh.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: fox -name: Fox -avatar: /images/avatars/fox.png ---- diff --git a/content/author/mkdirs.mdx b/content/author/mkdirs.mdx deleted file mode 100644 index e5cf61f..0000000 --- a/content/author/mkdirs.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: mkdirs -name: Mkdirs -avatar: /images/avatars/mkdirs.png ---- diff --git a/content/author/mkdirs.zh.mdx b/content/author/mkdirs.zh.mdx deleted file mode 100644 index 61ba558..0000000 --- a/content/author/mkdirs.zh.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: mkdirs -name: Mkdirs模板 -avatar: /images/avatars/mkdirs.png ---- diff --git a/content/author/mksaas.mdx b/content/author/mksaas.mdx deleted file mode 100644 index 77581c6..0000000 --- a/content/author/mksaas.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: mksaas -name: MkSaaS -avatar: /images/avatars/mksaas.png ---- diff --git a/content/author/mksaas.zh.mdx b/content/author/mksaas.zh.mdx deleted file mode 100644 index 294ec63..0000000 --- a/content/author/mksaas.zh.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: mksaas -name: MkSaaS模板 -avatar: /images/avatars/mksaas.png ---- diff --git a/content/category/company.mdx b/content/category/company.mdx deleted file mode 100644 index c3ac928..0000000 --- a/content/category/company.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: company -name: Company -description: Company news and updates ---- diff --git a/content/category/company.zh.mdx b/content/category/company.zh.mdx deleted file mode 100644 index 5217933..0000000 --- a/content/category/company.zh.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: company -name: 公司 -description: 公司新闻和更新 ---- diff --git a/content/category/news.mdx b/content/category/news.mdx deleted file mode 100644 index 550a4cb..0000000 --- a/content/category/news.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: news -name: News -description: News and updates about MkSaaS ---- diff --git a/content/category/news.zh.mdx b/content/category/news.zh.mdx deleted file mode 100644 index ffc2670..0000000 --- a/content/category/news.zh.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: news -name: 新闻 -description: 最新新闻和更新 ---- diff --git a/content/category/product.mdx b/content/category/product.mdx deleted file mode 100644 index aa07989..0000000 --- a/content/category/product.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: product -name: Product -description: Products and services powered by MkSaaS ---- diff --git a/content/category/product.zh.mdx b/content/category/product.zh.mdx deleted file mode 100644 index 3027a7d..0000000 --- a/content/category/product.zh.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -slug: product -name: 产品 -description: 产品和服务 ---- diff --git a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx deleted file mode 100644 index b8d0a41..0000000 --- a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import BlogGridWithPagination from '@/components/blog/blog-grid-with-pagination'; -import { LOCALES } from '@/i18n/routing'; -import { getPaginatedBlogPosts } from '@/lib/blog/data'; -import { constructMetadata } from '@/lib/metadata'; -import { getUrlWithLocale } from '@/lib/urls/urls'; -import { allCategories } from 'content-collections'; -import type { Locale } from 'next-intl'; -import { getTranslations } from 'next-intl/server'; -import { notFound } from 'next/navigation'; - -// Generate all static params for SSG (locale + category) -export function generateStaticParams() { - const params: { locale: string; slug: string }[] = []; - for (const locale of LOCALES) { - const localeCategories = allCategories.filter( - (category) => category.locale === locale - ); - for (const category of localeCategories) { - params.push({ locale, slug: category.slug }); - } - } - return params; -} - -// Generate metadata for each static category page (locale + category) -export async function generateMetadata({ params }: BlogCategoryPageProps) { - const { locale, slug } = await params; - const category = allCategories.find( - (category) => category.locale === locale && category.slug === slug - ); - if (!category) { - notFound(); - } - const t = await getTranslations({ locale, namespace: 'Metadata' }); - const canonicalPath = `/blog/category/${slug}`; - return constructMetadata({ - title: `${category.name} | ${t('title')}`, - description: category.description, - canonicalUrl: getUrlWithLocale(canonicalPath, locale), - }); -} - -interface BlogCategoryPageProps { - params: Promise<{ - locale: Locale; - slug: string; - }>; -} - -export default async function BlogCategoryPage({ - params, -}: BlogCategoryPageProps) { - const { locale, slug } = await params; - const category = allCategories.find( - (category) => category.locale === locale && category.slug === slug - ); - if (!category) { - notFound(); - } - const currentPage = 1; - const { paginatedPosts, totalPages } = getPaginatedBlogPosts({ - locale, - page: currentPage, - category: slug, - }); - return ( - - ); -} diff --git a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page/[page]/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page/[page]/page.tsx deleted file mode 100644 index 7c09807..0000000 --- a/src/app/[locale]/(marketing)/blog/(blog)/category/[slug]/page/[page]/page.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import BlogGridWithPagination from '@/components/blog/blog-grid-with-pagination'; -import { websiteConfig } from '@/config/website'; -import { LOCALES } from '@/i18n/routing'; -import { getPaginatedBlogPosts } from '@/lib/blog/data'; -import { constructMetadata } from '@/lib/metadata'; -import { getUrlWithLocale } from '@/lib/urls/urls'; -import { allCategories, allPosts } from 'content-collections'; -import type { Locale } from 'next-intl'; -import { getTranslations } from 'next-intl/server'; -import { notFound } from 'next/navigation'; - -// Generate all static params for SSG (locale + category + pagination) -export function generateStaticParams() { - const params: { locale: string; slug: string; page: string }[] = []; - for (const locale of LOCALES) { - const localeCategories = allCategories.filter( - (category) => category.locale === locale - ); - for (const category of localeCategories) { - const totalPages = Math.ceil( - allPosts.filter( - (post) => - post.locale === locale && - post.categories.some((cat) => cat && cat.slug === category.slug) - ).length / websiteConfig.blog.paginationSize - ); - for (let page = 2; page <= totalPages; page++) { - params.push({ locale, slug: category.slug, page: String(page) }); - } - } - } - return params; -} - -// Generate metadata for each static category page (locale + category + pagination) -export async function generateMetadata({ params }: BlogCategoryPageProps) { - const { locale, slug, page } = await params; - const category = allCategories.find( - (category) => category.slug === slug && category.locale === locale - ); - if (!category) { - notFound(); - } - const t = await getTranslations({ locale, namespace: 'Metadata' }); - const canonicalPath = `/blog/category/${slug}/page/${page}`; - return constructMetadata({ - title: `${category.name} | ${t('title')}`, - description: category.description, - canonicalUrl: getUrlWithLocale(canonicalPath, locale), - }); -} - -interface BlogCategoryPageProps { - params: Promise<{ - locale: Locale; - slug: string; - page: string; - }>; -} - -export default async function BlogCategoryPage({ - params, -}: BlogCategoryPageProps) { - const { locale, slug, page } = await params; - const currentPage = Number(page); - const category = allCategories.find( - (category) => category.slug === slug && category.locale === locale - ); - if (!category) { - notFound(); - } - const { paginatedPosts, totalPages } = getPaginatedBlogPosts({ - locale, - page: currentPage, - category: slug, - }); - return ( - - ); -} diff --git a/src/app/[locale]/(marketing)/blog/(blog)/layout.tsx b/src/app/[locale]/(marketing)/blog/(blog)/layout.tsx deleted file mode 100644 index 1302a1a..0000000 --- a/src/app/[locale]/(marketing)/blog/(blog)/layout.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { BlogCategoryFilter } from '@/components/blog/blog-category-filter'; -import Container from '@/components/layout/container'; -import type { NextPageProps } from '@/types/next-page-props'; -import { allCategories } from 'content-collections'; -import { getTranslations } from 'next-intl/server'; -import type { PropsWithChildren } from 'react'; - -interface BlogListLayoutProps extends PropsWithChildren, NextPageProps {} - -export default async function BlogListLayout({ - children, - params, -}: BlogListLayoutProps) { - const resolvedParams = await params; - const { locale } = resolvedParams; - const t = await getTranslations('BlogPage'); - - // Filter categories by locale - const categoryList = allCategories.filter( - (category) => category.locale === locale - ); - - return ( -
-
- {/* Header */} -
-

- {t('title')} -

-

- {t('subtitle')} -

-
- - -
- - {children} -
- ); -} diff --git a/src/app/[locale]/(marketing)/blog/(blog)/loading.tsx b/src/app/[locale]/(marketing)/blog/(blog)/loading.tsx deleted file mode 100644 index bc312b4..0000000 --- a/src/app/[locale]/(marketing)/blog/(blog)/loading.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { BlogGridSkeleton } from '@/components/blog/blog-grid'; - -export default function Loading() { - return ; -} diff --git a/src/app/[locale]/(marketing)/blog/(blog)/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/page.tsx deleted file mode 100644 index aaf6394..0000000 --- a/src/app/[locale]/(marketing)/blog/(blog)/page.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import BlogGridWithPagination from '@/components/blog/blog-grid-with-pagination'; -import { LOCALES } from '@/i18n/routing'; -import { getPaginatedBlogPosts } from '@/lib/blog/data'; -import { constructMetadata } from '@/lib/metadata'; -import { getUrlWithLocale } from '@/lib/urls/urls'; -import type { Locale } from 'next-intl'; -import { getTranslations } from 'next-intl/server'; - -export function generateStaticParams() { - return LOCALES.map((locale) => ({ locale })); -} - -export async function generateMetadata({ params }: BlogPageProps) { - const { locale } = await params; - const t = await getTranslations({ locale, namespace: 'Metadata' }); - const pt = await getTranslations({ locale, namespace: 'BlogPage' }); - const canonicalPath = '/blog'; - return constructMetadata({ - title: `${pt('title')} | ${t('title')}`, - description: pt('description'), - canonicalUrl: getUrlWithLocale(canonicalPath, locale), - }); -} - -interface BlogPageProps { - params: Promise<{ - locale: Locale; - }>; -} - -export default async function BlogPage({ params }: BlogPageProps) { - const { locale } = await params; - const currentPage = 1; - const { paginatedPosts, totalPages } = getPaginatedBlogPosts({ - locale, - page: currentPage, - }); - return ( - - ); -} diff --git a/src/app/[locale]/(marketing)/blog/(blog)/page/[page]/page.tsx b/src/app/[locale]/(marketing)/blog/(blog)/page/[page]/page.tsx deleted file mode 100644 index b0c42b1..0000000 --- a/src/app/[locale]/(marketing)/blog/(blog)/page/[page]/page.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import BlogGridWithPagination from '@/components/blog/blog-grid-with-pagination'; -import { websiteConfig } from '@/config/website'; -import { LOCALES } from '@/i18n/routing'; -import { getPaginatedBlogPosts } from '@/lib/blog/data'; -import { constructMetadata } from '@/lib/metadata'; -import { getUrlWithLocale } from '@/lib/urls/urls'; -import { allPosts } from 'content-collections'; -import type { Locale } from 'next-intl'; -import { getTranslations } from 'next-intl/server'; - -export function generateStaticParams() { - const paginationSize = websiteConfig.blog.paginationSize; - const params: { locale: string; page: string }[] = []; - for (const locale of LOCALES) { - const publishedPosts = allPosts.filter( - (post) => post.published && post.locale === locale - ); - const totalPages = Math.max( - 1, - Math.ceil(publishedPosts.length / paginationSize) - ); - for (let pageNumber = 2; pageNumber <= totalPages; pageNumber++) { - params.push({ - locale, - page: String(pageNumber), - }); - } - } - return params; -} - -export async function generateMetadata({ params }: BlogListPageProps) { - const { locale, page } = await params; - const t = await getTranslations({ locale, namespace: 'Metadata' }); - const pt = await getTranslations({ locale, namespace: 'BlogPage' }); - const canonicalPath = `/blog/page/${page}`; - return constructMetadata({ - title: `${pt('title')} | ${t('title')}`, - description: pt('description'), - canonicalUrl: getUrlWithLocale(canonicalPath, locale), - }); -} - -interface BlogListPageProps { - params: Promise<{ - locale: Locale; - page: string; - }>; -} - -export default async function BlogListPage({ params }: BlogListPageProps) { - const { page, locale } = await params; - const currentPage = Number(page); - const { paginatedPosts, totalPages } = getPaginatedBlogPosts({ - locale, - page: currentPage, - }); - return ( - - ); -} diff --git a/src/app/[locale]/(marketing)/blog/[...slug]/layout.tsx b/src/app/[locale]/(marketing)/blog/[...slug]/layout.tsx deleted file mode 100644 index ee15fe6..0000000 --- a/src/app/[locale]/(marketing)/blog/[...slug]/layout.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import Container from '@/components/layout/container'; -import type { PropsWithChildren } from 'react'; - -export default function BlogPostLayout({ children }: PropsWithChildren) { - return ( - -
{children}
-
- ); -} diff --git a/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx b/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx deleted file mode 100644 index 83233c0..0000000 --- a/src/app/[locale]/(marketing)/blog/[...slug]/page.tsx +++ /dev/null @@ -1,256 +0,0 @@ -import AllPostsButton from '@/components/blog/all-posts-button'; -import BlogGrid from '@/components/blog/blog-grid'; -import { BlogToc } from '@/components/blog/blog-toc'; -import { NewsletterCard } from '@/components/newsletter/newsletter-card'; -import { CustomMDXContent } from '@/components/shared/custom-mdx-content'; -import { websiteConfig } from '@/config/website'; -import { LocaleLink } from '@/i18n/navigation'; -import { LOCALES } from '@/i18n/routing'; -import { getTableOfContents } from '@/lib/blog/toc'; -import { formatDate } from '@/lib/formatter'; -import { constructMetadata } from '@/lib/metadata'; -import { getUrlWithLocale } from '@/lib/urls/urls'; -import { type Post, allPosts } from 'content-collections'; -import { CalendarIcon, ClockIcon, FileTextIcon } from 'lucide-react'; -import type { Metadata } from 'next'; -import type { Locale } from 'next-intl'; -import { getTranslations } from 'next-intl/server'; -import Image from 'next/image'; -import { notFound } from 'next/navigation'; - -import '@/styles/mdx.css'; - -/** - * Gets the blog post from the params - * @param slug - The slug of the blog post - * @param locale - The locale of the blog post - * @returns The blog post - * - * How it works: - * /[locale]/blog/first-post: - * params.slug = ["first-post"] - * slug becomes "first-post" after join('/') - * Matches post where slugAsParams === "first-post" AND locale === params.locale - */ -async function getBlogPostFromParams(locale: Locale, slug: string) { - // console.log('getBlogPostFromParams', locale, slug); - // Find post with matching slug and locale - const post = allPosts.find( - (post) => - (post.slugAsParams === slug || - (!slug && post.slugAsParams === 'index')) && - post.locale === locale - ); - - if (!post) { - // If no post found with the current locale, try to find one with the default locale - const defaultPost = allPosts.find( - (post) => - post.slugAsParams === slug || (!slug && post.slugAsParams === 'index') - ); - - return defaultPost; - } - - return post; -} - -/** - * get related posts, random pick from all posts with same locale, different slug, - * max size is websiteConfig.blog.relatedPostsSize - */ -async function getRelatedPosts(post: Post) { - const relatedPosts = allPosts - .filter((p) => p.locale === post.locale) - .filter((p) => p.slugAsParams !== post.slugAsParams) - .sort(() => Math.random() - 0.5) - .slice(0, websiteConfig.blog.relatedPostsSize); - - return relatedPosts; -} - -export function generateStaticParams() { - return LOCALES.flatMap((locale) => { - const posts = allPosts.filter((post) => post.locale === locale); - return posts.map((post) => ({ - locale, - slug: [post.slugAsParams], - })); - }); -} - -export async function generateMetadata({ - params, -}: BlogPostPageProps): Promise { - const { locale, slug } = await params; - const post = await getBlogPostFromParams(locale, slug.join('/')); - if (!post) { - notFound(); - } - - const t = await getTranslations({ locale, namespace: 'Metadata' }); - - return constructMetadata({ - title: `${post.title} | ${t('title')}`, - description: post.description, - canonicalUrl: getUrlWithLocale(post.slug, locale), - image: post.image, - }); -} - -interface BlogPostPageProps { - params: Promise<{ - locale: Locale; - slug: string[]; - }>; -} - -export default async function BlogPostPage(props: BlogPostPageProps) { - const { locale, slug } = await props.params; - const post = await getBlogPostFromParams(locale, slug.join('/')); - if (!post) { - notFound(); - } - - const publishDate = post.date; - const date = formatDate(new Date(publishDate)); - const toc = await getTableOfContents(post.content); - - // getTranslations may cause error DYNAMIC_SERVER_USAGE, so we set dynamic to force-static - const t = await getTranslations('BlogPage'); - - // get related posts - const relatedPosts = await getRelatedPosts(post); - - return ( -
- {/* content section */} -
- {/* left column (blog post content) */} -
- {/* Basic information */} -
- {/* blog post image */} -
- {post.image && ( - {post.title - )} -
- - {/* blog post date and reading time */} -
-
- - - {date} - -
-
- - - {t('readTime', { minutes: post.estimatedTime })} - -
-
- - {/* blog post title */} -

{post.title}

- - {/* blog post description */} -

{post.description}

-
- - {/* blog post content */} - {/* in order to make the mdx.css work, we need to add the className prose to the div */} - {/* https://github.com/tailwindlabs/tailwindcss-typography */} -
- -
- -
- -
-
- - {/* right column (sidebar) */} -
-
- {/* author info */} -
-

{t('author')}

-
-
- {post.author?.avatar && ( - {`avatar - )} -
- {post.author?.name} -
-
- - {/* categories */} -
-

{t('categories')}

-
    - {post.categories?.filter(Boolean).map( - (category) => - category && ( -
  • - - {category.name} - -
  • - ) - )} -
-
- - {/* table of contents */} -
-

- {t('tableOfContents')} -

-
- -
-
-
-
-
- - {/* Footer section shows related posts */} - {relatedPosts && relatedPosts.length > 0 && ( -
-
- -

- {t('morePosts')} -

-
- - -
- )} - - {/* newsletter */} -
- -
-
- ); -}