فصل هشتم: ادغام با سیستم مدیریت محتوا (CMS) با استفاده از Nuxt Content

در این فصل، به ادغام اپلیکیشن مرکز اجاره کشتی‌های کروز با Nuxt Content، یک ماژول قدرتمند برای مدیریت محتوا در Nuxt 3، می‌پردازیم. Nuxt Content به توسعه‌دهندگان امکان می‌دهد محتوای خود را به‌صورت فایل‌های Markdown، JSON، YAML یا CSV مدیریت کنند و آن‌ها را به‌صورت پویا در اپلیکیشن نمایش دهند. این ماژول مانند یک سیستم مدیریت محتوا (CMS) سبک عمل می‌کند و برای مدیریت توضیحات کشتی‌ها در این پروژه ایده‌آل است. در ادامه، مراحل نصب، پیکربندی، ایجاد فایل‌های محتوا و استفاده از آن‌ها در صفحه جزئیات کشتی به‌طور کامل توضیح داده شده است.


اضافه کردن Nuxt Content

برای استفاده از Nuxt Content، ابتدا باید ماژول @nuxt/content را به پروژه اضافه کنیم.

دستور نصب:

npm install @nuxt/content

توضیحات:

  • دستور npm install @nuxt/content: این دستور ماژول @nuxt/content را به پروژه اضافه می‌کند. این ماژول به Nuxt امکان می‌دهد فایل‌های Markdown (و سایر فرمت‌ها) را به‌عنوان منبع داده خوانده و در اپلیکیشن استفاده کند.
  • کاربرد: با نصب این ماژول، می‌توانیم توضیحات کشتی‌ها را به‌صورت فایل‌های Markdown در پوشه content/ ذخیره کرده و به‌صورت پویا در صفحات نمایش دهیم.

به‌روزرسانی فایل تنظیمات (nuxt.config.ts)

برای فعال کردن ماژول Nuxt Content، باید آن را به لیست ماژول‌های Nuxt در فایل تنظیمات اضافه کنیم.

کد:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@pinia/nuxt', '@nuxtjs/tailwindcss', '@nuxt/image', '@nuxt/content'],
  // ...سایر تنظیمات
});

توضیحات:

  • اضافه کردن @nuxt/content به modules: این خط ماژول Nuxt Content را به پروژه اضافه می‌کند و آن را با سایر ماژول‌ها (مانند Pinia، Tailwind CSS و Nuxt Image) ادغام می‌کند.
  • کارکرد: این تنظیم به Nuxt اجازه می‌دهد فایل‌های موجود در پوشه content/ را شناسایی کرده و از آن‌ها به‌عنوان منبع داده استفاده کند.
  • مزایا:

  • امکان مدیریت محتوای متنی (مانند توضیحات کشتی‌ها) به‌صورت فایل‌های Markdown.

  • پشتیبانی از پرس‌وجوهای پویا برای دسترسی به محتوا.
  • ادغام آسان با رندر سمت سرور (SSR) و تولید سایت استاتیک (SSG).

ایجاد فایل محتوا برای کشتی‌ها (content/ships/1.md)

برای مدیریت توضیحات کشتی‌ها، فایل‌های Markdown را در پوشه content/ships/ ایجاد می‌کنیم. هر فایل Markdown شامل متادیتا (Frontmatter) و محتوای اصلی است.

نمونه فایل:

---
id: 1
name: Ocean Explorer
description: A luxurious cruise ship with a pool and gym.
---

توضیحات:

  • محل فایل: فایل در مسیر content/ships/1.md ذخیره می‌شود. پوشه content/ به‌صورت خودکار توسط Nuxt Content شناسایی می‌شود.
  • ساختار فایل:

  • Frontmatter (بخش بین ---): شامل متادیتای فایل به‌صورت کلید-مقدار است:

    • id: 1: شناسه یکتای کشتی، که با داده‌های موجود در API کشتی‌ها (server/api/ships.ts) مطابقت دارد.
    • name: Ocean Explorer: نام کشتی برای شناسایی.
    • description: A luxurious cruise ship with a pool and gym.: توضیحات متنی کشتی که در صفحه جزئیات نمایش داده می‌شود.
  • بدنه فایل: در این مثال خالی است، اما می‌توان محتوای اضافی (مانند متن طولانی‌تر یا HTML) را در زیر Frontmatter اضافه کرد.
  • کاربرد: این فایل توضیحات کشتی با شناسه ۱ را ذخیره می‌کند و می‌تواند به‌صورت پویا در صفحه جزئیات کشتی نمایش داده شود.
  • مزایا:

  • مدیریت محتوا به‌صورت فایل‌های Markdown ساده‌تر از استفاده از پایگاه داده است.

  • امکان ویرایش محتوا توسط غیربرنامه‌نویسان (مانند تیم‌های محتوا) با استفاده از ویرایشگرهای Markdown.
  • پشتیبانی از SSG، که باعث تولید محتوای استاتیک در زمان ساخت می‌شود.

دریافت محتوا در صفحه جزئیات کشتی (pages/ships/[id].vue)

برای نمایش توضیحات کشتی از فایل Markdown، از API پرس‌وجوی Nuxt Content در صفحه جزئیات کشتی استفاده می‌کنیم.

کد:

<script setup>
const { data: content } = await useAsyncData('ship-content', () =>
  queryContent('/ships').where({ id: Number(route.params.id) }).findOne()
);
</script>
<template>
  <div v-if="content">{{ content.description }}</div>
</template>

توضیحات:

  1. بخش Script:

  2. useAsyncData: یک تابع داخلی Nuxt برای دریافت داده‌ها به‌صورت غیرهمزمان. این تابع برای بارگذاری محتوای پویا در زمان رندر سمت سرور یا کلاینت استفاده می‌شود.

    • اولین پارامتر (ship-content): یک کلید یکتا برای شناسایی داده در کش Nuxt.
    • دومین پارامتر: یک تابع که پرس‌وجوی محتوا را تعریف می‌کند.
  3. queryContent('/ships'): یک پرس‌وجو برای دسترسی به فایل‌های موجود در پوشه content/ships/ ایجاد می‌کند.
  4. where({ id: Number(route.params.id) }): فایل Markdown را بر اساس فیلد id در Frontmatter فیلتر می‌کند. route.params.id از URL صفحه (مانند /ships/1) استخراج شده و به عدد تبدیل می‌شود.
  5. findOne(): اولین فایل Markdown که با شرط مطابقت دارد را برمی‌گرداند.
  6. data: content: داده دریافت‌شده در متغیر content ذخیره می‌شود.

  7. بخش Template:

  8. <div v-if="content">{{ content.description }}</div>: اگر محتوای دریافت‌شده وجود داشته باشد، فیلد description از Frontmatter نمایش داده می‌شود (مثلاً "A luxurious cruise ship with a pool and gym.").

  9. اگر محتوایی یافت نشود، چیزی نمایش داده نمی‌شود.

  10. کاربرد:

  11. این کد به صفحه جزئیات کشتی (pages/ships/[id].vue) امکان می‌دهد توضیحات کشتی را از فایل Markdown مربوطه نمایش دهد.

  12. برای مثال، برای کشتی با id: 1، توضیحات از فایل content/ships/1.md لود می‌شود.

  13. مزایا:

  14. مدیریت آسان محتوا: توضیحات کشتی‌ها را می‌توان بدون تغییر کد اصلی در فایل‌های Markdown ویرایش کرد.

  15. بهینه‌سازی برای SSG: محتوای Markdown در زمان ساخت به HTML استاتیک تبدیل می‌شود، که سرعت بارگذاری را افزایش می‌دهد.
  16. انعطاف‌پذیری: می‌توان فیلدهای بیشتری (مانند تصاویر اضافی یا جزئیات دیگر) به Frontmatter اضافه کرد.

  17. ادغام با صفحه جزئیات:

  18. این کد باید به صفحه موجود pages/ships/[id].vue اضافه شود. برای مثال، می‌توان <div v-if="content">{{ content.description }}</div> را زیر بخش نمایش امکانات (amenities) قرار داد تا توضیحات کشتی نمایش داده شود.


نکات تکمیلی

  • گسترش محتوا: می‌توان فایل‌های Markdown بیشتری برای کشتی‌های دیگر (مانند content/ships/2.md) اضافه کرد و یا محتوای اضافی مانند گالری تصاویر یا نظرات کاربران را در بدنه فایل Markdown قرار داد.
  • پرس‌وجوهای پیشرفته: Nuxt Content از پرس‌وجوهای پیچیده‌تر پشتیبانی می‌کند، مانند فیلتر کردن چندین فایل یا مرتب‌سازی محتوا بر اساس فیلدها.
  • اتصال به CMS خارجی: برای پروژه‌های بزرگ‌تر، می‌توان Nuxt Content را با سیستم‌های CMS مانند Contentful یا Sanity ادغام کرد، اما استفاده از فایل‌های Markdown برای پروژه‌های کوچک‌تر ساده‌تر است.
  • محلی‌سازی: می‌توان با افزودن فایل‌های Markdown در پوشه‌های جداگانه (مانند content/ships/fa/1.md برای فارسی) از محلی‌سازی پشتیبانی کرد.

جمع‌بندی فصل هشتم

در این فصل، ماژول @nuxt/content را به اپلیکیشن مرکز اجاره کشتی‌های کروز اضافه کردیم تا توضیحات کشتی‌ها به‌صورت فایل‌های Markdown مدیریت شوند. این ماژول با نصب ساده، پیکربندی در nuxt.config.ts، ایجاد فایل‌های محتوا و استفاده از API پرس‌وجوی Nuxt Content، امکان مدیریت محتوای پویا را فراهم کرد. این رویکرد برای پروژه‌های کوچک و متوسط که نیاز به CMS سبک دارند بسیار مناسب است. در فصل‌های بعدی، به تست و بهینه‌سازی اپلیکیشن خواهیم پرداخت.