diff --git a/src/content/docs/ko/plugins/extended.mdx b/src/content/docs/ko/plugins/extended.mdx new file mode 100644 index 00000000..d08c6308 --- /dev/null +++ b/src/content/docs/ko/plugins/extended.mdx @@ -0,0 +1,316 @@ +--- +i18nReady: true +title: 플러그인을 유용하게 만들기 +description: StudioCMS 플러그인과 그 작동 방식에 대해 알아보세요. +sidebar: + order: 2 +--- + +import ReadMore from '~/components/ReadMore.astro' +import { FileTree } from '@astrojs/starlight/components' + +# 소개 + +StudioCMS 플러그인을 만드는 것은 StudioCMS의 기능을 확장하는 강력한 방법입니다. 플러그인은 StudioCMS 프로젝트에 새로운 기능을 간단하고 유연하게 추가할 수 있는 방법을 제공합니다. 다음은 StudioCMS 플러그인을 만들고 작동하는 방식에 대한 기본적인 예시입니다. + +## 시작하기 + +시작하려면 새로운 StudioCMS 플러그인을 생성해야 합니다. 다음은 StudioCMS 플러그인의 기본적인 파일 구조 예시입니다. + + + +- package.json +- src + - index.ts + - routes + - [...slug].astro + - dashboard-grid-items + - MyPluginGridItem.astro + + + +## 플러그인 만들기 + +`src/index.ts` 파일에서 StudioCMS 플러그인을 정의합니다. 다음은 간단한 블로그 예시를 만들기 위해 Astro 통합을 포함하는 StudioCMS 플러그인을 정의하는 방법의 예시입니다. + +```ts twoslash title="index.ts" +import { definePlugin } from 'studiocms/plugins'; +import { AstroIntegration } from 'astro'; +import { addVirtualImports, createResolver } from 'astro-integration-kit'; + +// 플러그인 및 통합에 대한 옵션을 정의합니다. +interface Options { + route: string; +} + +export function studioCMSPageInjector(options: Options) { + + // 현재 파일의 경로를 확인합니다. + const { resolve } = createResolver(import.meta.url); + + // Astro 통합을 정의합니다. + function myIntegration(options: Options): AstroIntegration { + const route = `/${options?.route || 'my-plugin'}`; + + return { + name: 'my-astro-integration', + hooks: { + "astro:config:setup": (params) => { + const { injectRoute } = params; + + // 플러그인 라우트를 삽입합니다. + injectRoute({ + entrypoint: resolve('./routes/[...slug].astro'), + pattern: `/${route}/[...slug]`, + prerender: false, + }) + + addVirtualImports(params, { + name: 'my-astro-integration', + imports: { + 'myplugin:config': ` + export const options = ${JSON.stringify({ route })}; + export default options; + `, + } + }) + } + } + } + } + + // StudioCMS 플러그인을 정의합니다. + return definePlugin({ + identifier: 'my-plugin', + name: 'My Plugin', + studiocmsMinimumVersion: '0.1.0-beta.8', + integration: myIntegration(options), // 선택 사항이지만, 권장 사항입니다. + // 플러그인의 프런트엔드 탐색 링크를 정의합니다. (선택 사항) + // 예를 들어, `@studiocms/blog` 플러그인을 사용할 때처럼 + // 레이아웃에서 StudioCMS 내장 탐색 도우미를 사용하는 경우에 유용합니다. + frontendNavigationLinks: [{ label: 'Title here', href: options?.route || 'my-plugin' }], + // pageTypes를 생성할 때 플러그인에 사용자 정의 콘텐츠 편집기가 필요한 경우 `pageContentComponent`를 정의할 수도 있습니다. + // pageTypes: [{ identifier: 'my-plugin', label: 'Blog Post (My Plugin)', pageContentComponent: resolve('./components/MyContentEditor.astro') }], + // 이 예시에서는 기본 콘텐츠 편집기 (Markdown)를 사용해도 괜찮습니다. + pageTypes: [{ identifier: 'my-plugin', label: 'Blog Post (My Plugin)' }], + // 대시보드에 표시할 그리드 항목을 정의합니다. + // StudioCMS 대시보드에 표시될 항목들입니다. + // 원하는 만큼 여러 항목을 정의할 수 있습니다. + // 이 예시에서는 span이 2이고 'editor' 권한이 필요하며 일반 HTML 사용자 정의 요소를 대체하는 Astro 컴포넌트를 삽입하는 단일 항목을 정의합니다. + dashboardGridItems: [ + { + name: 'example', + span: 2, + variant: 'default', + requiresPermission: 'editor', + header: { title: 'Example', icon: 'bolt' }, + body: { + // 태그에는 `-` 또는 특수 문자 없이 항상 일반 HTML을 사용하세요. 이는 Astro 컴포넌트로 대체될 것이며, 이 HTML은 렌더링되지 않습니다. + html: '', + components: { + // 일반 HTML 사용자 정의 요소를 대체할 Astro 컴포넌트를 삽입합니다. + examplegriditem: resolve('./dashboard-grid-items/MyPluginGridItem.astro') + } + } + } + ], + }); +} +``` + +위 예시는 간단한 블로그 예시를 만들기 위해 Astro 통합을 포함하는 StudioCMS 플러그인을 정의합니다. 이 플러그인은 StudioCMS 프로젝트에 삽입되는 라우트와 StudioCMS 대시보드에 표시되는 그리드 항목을 포함합니다. + +Astro 통합을 만드는 방법에 대한 더 자세한 정보는 [Astro 통합 키트](https://astro-integration-kit.netlify.app/)와 [Astro 통합 문서](https://docs.astro.build/ko/reference/integrations-reference/)를 참조하세요. + +## 라우트 예시 + +`src/routes/[...slug].astro` 파일에서 플러그인의 라우트를 정의합니다. 다음은 플러그인의 라우트를 정의하는 방법의 예시이며, 이를 두 부분으로 나누어 설명하겠습니다. 첫 번째 부분은 프런트매터 (`---` 표시 사이)이고, 두 번째 부분은 두 번째 `---` 아래에 배치되는 HTML 템플릿입니다. + +```ts twoslash title="Frontmatter" +// @noErrors +// @filename: plugin.d.ts +declare module 'myplugin:config' { + export const options: { route: string }; + export default options; +} +// ---cut--- +// @filename: Frontmatter.ts +/// +/// +import type { AstroGlobal } from 'astro'; +const Astro: AstroGlobal = {}; +// ---cut--- +import { StudioCMSRenderer } from 'studiocms:renderer'; +import sdk from 'studiocms:sdk'; +import config from 'myplugin:config'; + +const makeRoute = (slug: string) => { + return `/${config.route}/${slug}`; +} + +// 여기서 'my-plugin'은 +// 플러그인 정의에서 가져온 `pageType`의 식별자로 사용됩니다. +const pages = await sdk.GET.packagePages('my-plugin'); + +const { slug } = Astro.params; + +const page = pages.find((page) => page.slug === slug || ''); +``` + +```astro title="Template" +{ + slug && page ? ( +
+

{page.title}

+ +
+ ) : ( +
+

My Plugin

+
    + {pages.length > 0 && pages.map((page) => ( +
  • + {page.title} +
  • + ))} +
+
+ ) +} +``` + +위의 예시는 슬러그가 제공되지 않으면 블로그 게시물 목록을 표시하고, 슬러그가 제공되면 특정 블로그 게시물의 내용을 표시하는 플러그인을 위한 [동적 라우트](https://docs.astro.build/ko/guides/routing/#동적-라우트)를 정의합니다. + +## 그리드 항목 예시 + +`src/dashboard-grid-items/MyPluginGridItem.astro` 파일에서 플러그인의 그리드 항목을 정의합니다. 다음은 플러그인의 그리드 항목을 정의하는 방법의 예시입니다. + +```astro title="MyPluginGridItem.astro" +--- +import { StudioCMSRoutes } from 'studiocms:lib'; +import sdk from 'studiocms:sdk'; + +// 여기서 'my-plugin'은 +// 플러그인 정의에서 가져온 `pageType`의 식별자로 사용됩니다. +const pages = await sdk.GET.packagePages('my-plugin'); + +// 지난 30일 동안 가장 최근에 업데이트된 5개의 페이지를 가져옵니다. +const recentlyUpdatedPages = pages + .filter((page) => { + const now = new Date(); + const thirtyDaysAgo = new Date(now.setDate(now.getDate() - 30)); + return new Date(page.updatedAt) > thirtyDaysAgo; + }) + .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()) + .slice(0, 5); +--- + +
+

Recently Updated Pages

+
    + {recentlyUpdatedPages.length > 0 && recentlyUpdatedPages.map((page) => ( +
  • + {page.title} +
  • + ))} +
+
+``` + +위의 예시는 지난 30일 동안 가장 최근에 업데이트된 5개의 페이지를 표시하는 플러그인용 그리드 항목을 정의합니다. 이 그리드 항목은 각 페이지의 콘텐츠 관리 편집 페이지로 연결되는 링크 목록을 포함합니다. + +## FrontendNavigationLinks 도우미와 통합 + +프로젝트에서 `@studiocms/blog` 플러그인이 사용하는 방식과 유사하게, StudioCMS 내장 탐색 도우미를 사용하려면 다음과 같이 사용자 정의 `Navigation.astro` 컴포넌트를 생성할 수 있습니다. + +```astro title="Navigation.astro" +--- +import { StudioCMSRoutes } from 'studiocms:lib'; +import studioCMS_SDK from 'studiocms:sdk/cache'; +import { frontendNavigation } from 'studiocms:plugin-helpers'; + +// Navigation 컴포넌트의 props를 정의합니다. +interface Props { + topLevelLinkCount?: number; +}; + +// props에서 최상위 링크 개수를 가져옵니다. +const { topLevelLinkCount = 3 } = Astro.props; + +// 사이트 구성과 페이지 목록을 가져옵니다. +const config = (await studioCMS_SDK.GET.siteConfig()).data; + +// 구성에서 사이트 제목을 가져옵니다. +const { title } = config || { title: 'StudioCMS' }; + +// 메인 사이트 URL을 가져옵니다. +const { + mainLinks: { baseSiteURL }, +} = StudioCMSRoutes; + +// 탐색 메뉴의 링크 props를 정의합니다. +type LinkProps = { + text: string; + href: string; +}; + +// 탐색 메뉴의 링크들을 정의합니다. +const links: LinkProps[] = await frontendNavigation(); +--- +{/* 드롭다운 아이템이 없는 경우 */} +{ ( links.length < topLevelLinkCount || links.length === topLevelLinkCount ) && ( + +) } + +{/* 드롭다운 아이템이 있는 경우 */} +{ links.length > topLevelLinkCount && ( + +) } +``` + +위의 예시는 StudioCMS 내장 탐색 도우미를 사용하여 프로젝트의 탐색 메뉴를 생성하는 사용자 정의 `Navigation.astro` 컴포넌트를 정의합니다. 이 컴포넌트는 메인 사이트 URL, 인덱스 페이지 및 탐색 메뉴에 표시되도록 설정된 다른 모든 페이지로 연결되는 링크를 포함합니다. + +몇 가지 스타일만 추가하면 StudioCMS 내장 탐색 도우미와 연동되어 완벽하게 작동하는 탐색 메뉴를 갖게 됩니다.