مستنداتبخش برنامه نویساندستورالعمل‌های گام‌به‌گام کاستوم‌سازی و توسعه

دستورالعمل‌های کاستوم‌سازی و توسعه فیچرهای جدید (Customization Recipes)

این راهنما برای برنامه‌نویسانی تدوین شده است که سورس‌کد پروژه را تهیه کرده‌اند و می‌خواهند فیچرهای اختصاصی جدید اضافه کنند، اپشن‌های محصولات را چندزبانه نمایند یا کامپوننت‌های بصری سفارشی بسازند.

دستورالعمل ۱: مدیریت و ترجمه اپشن‌های محصولات و سواچ رنگ (`color`)

قاعده غیرقابل‌تغییر برای کلید رنگ (Color Swatches)
در پنل ادمین Medusa، عنوان اپشن اختصاص یافته به رنگ حتماً و بدون استثنا باید کلمه color (یا Color) باشد. فرانت‌اند Next.js با این کلید، کدهای Hex رنگ را شناسایی کرده و دایره‌های رنگی تعاملی و فیلترهای بصری ایجاد می‌کند.

روند چندزبانه کردن عناوین اپشن‌ها با Strapi:

  • برای سایر اپشن‌ها (مانند سایز، جنس، برند)، نام‌گذاری به هر زبانی آزاد است.
  • ترجمه متناظر عناوین (مانند تبدیل color به "رنگ" یا Size به "سایز") در پنل Strapi CMS تعریف می‌شود.
  • فرانت‌اند Next.js بر اساس Locale جاری کاربر، ترجمه عنوان را از Strapi فچ می‌کند در حالی که کلید فیلتر رنگی color باقی می‌ماند.
نمونه فچ ترجمه اپشن از Strapi در فرانت‌اند
typescript
// store/src/lib/strapi-client/get-option-translations.ts
export async function getOptionTranslation(optionKey: string, locale: string = "fa") {
const res = await fetch(
`${process.env.NEXT_PUBLIC_STRAPI_URL}/api/option-translations?filters[key][$eq]=${optionKey}&locale=${locale}`,
{ headers: { Authorization: `Bearer ${process.env.STRAPI_API_TOKEN_FOR_FRONT}` } }
)
const json = await res.json()
return json.data?.[0]?.translated_name || optionKey
}

دستورالعمل ۲: افزودن Workflow و REST API Endpoint جدید در Medusa v2

در نسخه Medusa v2 منطق‌های تجاری به صورت Step و Workflow تفکیک می‌شوند:

store-admin/src/workflows/daily-deals.ts
typescript
import { createWorkflow, createStep, StepResponse, WorkflowResponse } from "@medusajs/framework/workflows-sdk";
const fetchDealsStep = createStep("fetch-deals-step", async () => {
const deals = [{ id: "deal_1", title: "پیشنهاد ویژه روز", discount: "25%" }];
return new StepResponse(deals);
});
export const getDailyDealsWorkflow = createWorkflow("get-daily-deals", function () {
const deals = fetchDealsStep();
return new WorkflowResponse(deals);
});
store-admin/src/api/store/daily-deals/route.ts
typescript
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
import { getDailyDealsWorkflow } from "../../../workflows/daily-deals";
export async function GET(req: MedusaRequest, res: MedusaResponse) {
const { result } = await getDailyDealsWorkflow(req.scope).run();
res.json({ deals: result });
}

دستورالعمل ۳: ساخت یک بلاک جدید برای صفحه اصلی

بلاک‌های صفحه اصلی در مسیر store/src/modules/home/components/ قرار دارند. هر بلاک از سه بخش تشکیل می‌شود: تعریف تایپ در homepage.ts، یک Component اسکیما در Strapi، و یک پوشه کامپوننت React.

ساختار واقعی پروژه
بلاک‌های موجود مثل FeaturesBlock، BlogPostsBlock، ProductShowcase و ProductSplitView هرکدام یک پوشه مستقل دارند و از طریق __component که Strapi برمی‌گرداند در BlockRenderer شناسایی می‌شوند.

مثال: افزودن بلاک «شمارش معکوس» (Countdown)

  1. تعریف تایپ TypeScript — در فایل store/src/lib/data/homepage.ts اینترفیس بلاک جدید را اضافه کنید و به union type اصلی اضافه کنید:
store/src/lib/data/homepage.ts
typescript
export interface CountdownBlock {
__component: "ui.countdown-block"
id: number
title?: string
target_date: string
}
// اضافه کردن به union type
export type HomepageBlock =
| ProductSplitViewBlock
| ProductShowcaseBlock
| FeaturesBlock
| BlogPostsBlock
| CategoryCollectionBlock
| CountdownBlock // <-- اینجا اضافه می‌شود
  1. ساخت پوشه و کامپوننت React — پوشه‌ای به نام CountdownBlock در مسیر store/src/modules/home/components/ بسازید:
store/src/modules/home/components/CountdownBlock/index.tsx
tsx
import React from "react"
import type { CountdownBlock as CountdownBlockType } from "@lib/data/homepage"
interface CountdownBlockProps {
block: CountdownBlockType
}
export default function CountdownBlock({ block }: CountdownBlockProps) {
return (
<section className="py-16 text-center">
<h2 className="text-xl font-bold mb-4">{block.title}</h2>
<p className="text-gray-500">{block.target_date}</p>
</section>
)
}
  1. ثبت در BlockRenderer — فایل store/src/modules/home/components/BlockRenderer/index.tsx را باز کنید و یک case جدید به switch اضافه کنید:
store/src/modules/home/components/BlockRenderer/index.tsx
tsx
import CountdownBlock from "../CountdownBlock"
// داخل تابع BlockRenderer، در switch(block.__component):
case "ui.countdown-block":
BlockContent = <CountdownBlock block={block} />
break
  1. ساخت Component اسکیما در Strapi — در پوشه website-admin/src/components/ui/ یک فایل JSON جدید بسازید:
website-admin/src/components/ui/countdown-block.json
json
{
"collectionName": "components_ui_countdown_blocks",
"info": {
"displayName": "Countdown Block",
"icon": "clock",
"description": "A countdown timer block for the homepage"
},
"options": {},
"attributes": {
"title": { "type": "string" },
"target_date": { "type": "datetime", "required": true }
}
}
گام آخر
پس از ری‌استارت Strapi، در پنل مدیریت به صفحه اصلی > Dynamic Zone بروید. بلاک جدید «Countdown Block» در لیست بلاک‌های قابل اضافه شدن ظاهر می‌شود.

دستورالعمل ۴: اتصال درگاه پرداخت جدید (Payment Provider)

جهت افزودن درگاه جدید، یک سرویس پیاده‌سازی‌کننده AbstractPaymentProvider در پوشه store-admin/src/modules/payment/ تعریف کرده و ان را در medusa-config.ts در بخش providers ماژول پرداخت ثبت نمایید.