برنامه نویسی

با پوشه برنامه Next.js 13 و Contentlayer یک برنامه وبلاگ بسازید

فهرست

بیا شروع کنیم

ابتدا باید یک برنامه Next.js جدید با ویژگی پوشه برنامه جدید ایجاد کنیم:

npx create-next-app@latest --ts
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همچنین می توانید استفاده کنید Javascript بجای Typescript. در این آموزش استفاده خواهیم کرد Typescript.

سپس باید Contentlayer را نصب کنید:

npm i contentlayer next-contentlayer @opentelemetry/api
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر، صادرات contentlayer پیکربندی در next.config.js:

const { withContentlayer } = require('next-contentlayer')

module.exports = withContentlayer({
  experimental: { appDir: true },
})
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر، ما نیاز به ایجاد یک contentlayer.config.ts فایل در ریشه پروژه:

import { defineDocumentType, makeSource } from "contentlayer/source-files";


const Post = defineDocumentType(() => ({
  name: "Post",
  filePathPattern: `**/*.mdx`,
  contentType: "mdx",
  fields: {
    title: {
      type: "string",
      description: "The title of the post",
      required: true,
    },
    description: {
      type: "string",
      description: "The description of the post",
      required: true,
    },
  },
  computedFields: {
    url: {
      type: "string",
      resolve: (doc) => `/posts/${doc._raw.flattenedPath}`,
    },
  },
}));

export default makeSource({
  contentDirPath: "posts",
  documentTypes: [Post],
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کد بالا پیکربندی Contentlayer است. الف ایجاد خواهد کرد Post نوع سند و ایجاد خواهد شد url زمینه بر اساس flattenedPath رشته.

در حال حاضر، ما نیاز به ایجاد یک posts پوشه را در ریشه پروژه قرار دهید و a ایجاد کنید hello-world.mdx فایل در آن:

---
title: "How to create Next.js app"
description: "Learn how to create Next.js app"
---

# Install Next.js

### Fist you need to install Next.js with the following command:

npm i create-next-app@latest
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سپس با دستور زیر برنامه را ریستارت کنید:

npm run dev
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر، شما می توانید جدید را ببینید .contentlayer پوشه در ریشه پروژه این پوشه حاوی فایل های JSON تولید شده، انواع و موارد دیگر است.

پوشه لایه محتوا تولید کنید

در حال حاضر، ما نیاز به ایجاد یک posts پوشه در app پوشه و ایجاد یک [slug] پوشه در آن و ایجاد یک page.tsx فایل در [slug] پوشه:

app/posts/[slug]/page.tsx

import { allPosts } from "contentlayer/generated";
import { getMDXComponent } from "next-contentlayer/hooks";

export const generateStaticParams = async () =>


  allPosts.map((post) => ({ slug: post._raw.flattenedPath }));
  export const generateMetadata = ({ params }:any) => {
    const post = allPosts.find((post:any) => post._raw.flattenedPath === params.slug)
    return { title: post?.title,description: post?.description }
  }

const PostLayout = ({ params }: { params: { slug: string } }) => {
  const post = allPosts.find(
    (post) => post._raw.flattenedPath === params.slug
  );

  let MDXContent;

  if (!post) {
    return <div>404</div>;
  } else {
    MDXContent = getMDXComponent(post!.body.code);
  }

  return (
    <div>
      <h1>
        {post.title}
      </h1>
      <p>{post.description}</p>
      <article>
        <MDXContent />
      </article>
    </div>
  );
};

export default PostLayout;

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کد بالا صفحه پست وبلاگ است. این پست وبلاگ را بر اساس slug پارامتر.

اکنون، می توانید وبلاگ رندر شده را در قسمت مشاهده کنید http://localhost:3000/posts/hello-world:

وبلاگ ارائه شده است

سبک دادن به وبلاگ

اکنون، ما باید با استفاده از وبلاگ استایل کنیم CSS یا دیگران در این آموزش استفاده خواهیم کرد CSS:

globals.css

pre {
  padding: 15px 20px;
  border-radius: 10px;
  background-color: #f9f8f981;
  overflow: auto;
  font-size: 0.9rem;
  margin: 40px 0;
}
article p {
  font-size: 1rem;
  line-height: 1.8rem;
  margin-top: 20px;
}
article h1 {
  font-size: 2.5rem;
  line-height: 3.5rem;
  margin-top: 60px;
  font-weight: 425;
}

...

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون، می توانید سبک وبلاگ را ببینید:

وبلاگ سبک

همچنین می توانید استفاده کنید TailwindCSS یا دیگران

اجزای سفارشی

کامپوننت های سفارشی یک ویژگی عالی است MDX. شما می توانید اجزای خود را ایجاد کنید و از آنها در پست های وبلاگ خود استفاده کنید.

به عنوان مثال، می توانیم a ایجاد کنیم CodeSnippet جزء:

app/posts/[slug]/page.tsx

import { allWritings } from "contentlayer/generated";
import { getMDXComponent } from "next-contentlayer/hooks";
import { Snippet } from "@geist-ui/core";

...

const CodeSnippet = (props: any) => (
 <Snippet {...props} text={props.text} />
);

 return (
    <div>
      <h1>
        {writing.title}
      </h1>
      <p>{writing.description}</p>
      <article>
        <MDXContent components={{ CodeSnippet }} />
      </article>
    </div>
  );

export default PostLayout;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر، شما می توانید استفاده کنید CodeSnippet جزء در پست های وبلاگ شما:

---
title: How to create a Next.js app
description: Learn how to create a Next.js app
---

# Install Next.js

### First, install Next.js using the following command:

<CodeSnippet text="npx create-next-app@latest" />
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر، شما می توانید ببینید CodeSnippet جزء در پست وبلاگ:

قطعه کد

لیست همه پست ها

اکنون باید صفحه ای ایجاد کنیم که همه پست ها را فهرست کند. برای این کار باید a ایجاد کنیم posts پوشه در app پوشه و ایجاد یک page.tsx فایل در آن:

app/posts/page.tsx

import Link from 'next/link'
import { allPosts, Post } from 'contentlayer/generated'

function PostCard(post: Post) {
  return (
    <div>
      <h2>
        <Link href={post.url} legacyBehavior>
          {post.title}
        </Link>
      </h2>
      <p>{post.description}</p>
    </div>
  )
}

function page() {
  const posts = allPosts

  return (
    <div>
      <div>
      {posts.map((post, idx) => (
        <PostCard key={idx} {...post} />
      ))}
      </div>
    </div>
  )
}

export default page;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون، می توانید لیست تمام پست ها را در قسمت مشاهده کنید http://localhost:3000/posts:

لیست تمام پست ها

کدها را برجسته کنید

اکنون باید کدهای موجود در پست های وبلاگ را برجسته کنیم. برای این کار استفاده خواهیم کرد rehype-pretty-code:

npm i rehype-pretty-code shiki
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در حال حاضر، ما باید اضافه کنیم rehype-pretty-code افزونه به contentlayer.config.ts فایل:

contentlayer.config.ts

import { defineDocumentType, makeSource } from "contentlayer/source-files";
import rehypePrettyCode from "rehype-pretty-code";

const Writing = defineDocumentType(() => ({
  ...
}));

const rehypeoptions = {
    // Use one of Shiki's packaged themes
    theme: "light-plus",
    keepBackground: isDark ,
    onVisitLine(node: any) {
      if (node.children.length === 0) {
        node.children = [{ type: "text", value: " " }];
      }
    },
    onVisitHighlightedLine(node: any) {
      node.properties.className.push("highlighted");
    },
    onVisitHighlightedWord(node: any, id: any) {
      node.properties.className = ["word"];
    },
  };

export default makeSource({
  contentDirPath: "writings",
  documentTypes: [Writing],
  mdx: {
    rehypePlugins: [[rehypePrettyCode, rehypeoptions]],
  },
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون، می توانید کدهای برجسته شده را در پست های وبلاگ مشاهده کنید:

کدهای هایلایت شده

می توانید اطلاعات بیشتری در مورد rehype-pretty-code بیابید
و مضامین شیکی.

نتیجه

در این آموزش یاد گرفتیم که چگونه با استفاده از وبلاگ بسازیم Next.js، Contentlayer، و MDX. ما یاد گرفتیم که چگونه یک پست وبلاگ ایجاد کنیم، چگونه همه پست ها را فهرست کنیم، و چگونه کدها را در پست های وبلاگ برجسته کنیم.

می توانید کد منبع آن را پیدا کنید Contentlayer وبلاگ در مخزن GitHub زیر:

کد منبع مثال

منابع

درباره نویسنده

ارشد یاسین. من یک مهندس نرم‌افزار هستم و دوست دارم که جلوه‌های زیبایی‌شناسانه ایجاد کنم. اگر سوالی دارید، در صورت تمایل از من بپرسید توییتر.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا