페이지 레이아웃

이 페이지

편집자가 에디터의 드롭다운에서 페이지별로 레이아웃(예: 기본, 전체 너비, 랜딩 페이지)을 선택할 수 있도록 하며, 페이지 라우트의 레이아웃 컴포넌트에 매핑된 select 필드를 사용합니다.

작동 방식

  1. 페이지 컬렉션에 template 선택 필드 추가
  2. 각 옵션에 대한 레이아웃 컴포넌트 생성
  3. 페이지 라우트에서 필드 값을 레이아웃에 매핑

이는 EmDash의 선택 필드와 Astro의 컴포넌트 모델을 사용합니다.

필드 추가

관리 UI에서 슬러그 template과 레이아웃 옵션(예: “Default”, “Full Width”)이 있는 선택 필드를 페이지 컬렉션에 추가합니다. 또는 시드 데이터에 포함시킵니다:

{
  "slug": "template",
  "label": "Template",
  "type": "select",
  "validation": {
    "options": ["Default", "Full Width"]
  },
  "defaultValue": "Default"
}

레이아웃 컴포넌트 생성

각 레이아웃은 다른 스타일로 기본 레이아웃의 콘텐츠를 래핑합니다:

---
import type { ContentEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "./Base.astro";

interface Props {
  page: ContentEntry<any>;
}

const { page } = Astro.props;
---

<Base title={page.data.title}>
  <article class="page-default">
    <h1>{page.data.title}</h1>
    <PortableText value={page.data.content} />
  </article>
</Base>

<style>
  .page-default {
    max-width: var(--content-width);
    margin: 0 auto;
    padding: 2rem 1rem;
  }
</style>
---
import type { ContentEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "./Base.astro";

interface Props {
  page: ContentEntry<any>;
}

const { page } = Astro.props;
---

<Base title={page.data.title}>
  <article class="page-wide">
    <h1>{page.data.title}</h1>
    <PortableText value={page.data.content} />
  </article>
</Base>

<style>
  .page-wide {
    max-width: var(--wide-width);
    margin: 0 auto;
    padding: 2rem 1rem;
  }
</style>

라우트 연결

페이지 라우트에서 각 레이아웃을 가져오고 템플릿 값을 매핑합니다:

---
import { getEmDashEntry } from "emdash";
import PageDefault from "../../layouts/PageDefault.astro";
import PageFullWidth from "../../layouts/PageFullWidth.astro";

const { slug } = Astro.params;

if (!slug) {
  return Astro.redirect("/404");
}

const { entry: page } = await getEmDashEntry("pages", slug);

if (!page) {
  return Astro.redirect("/404");
}

const layouts = {
  "Default": PageDefault,
  "Full Width": PageFullWidth,
};

const Layout = layouts[page.data.template as keyof typeof layouts] ?? PageDefault;
---

<Layout page={page} />

라우트는 작게 유지됩니다. 각 레이아웃 컴포넌트는 자체 마크업과 스타일을 소유합니다. 레이아웃을 추가하는 것은: 컴포넌트를 생성하고, 선택 필드에 옵션을 추가하고, 맵에 줄을 추가하는 것입니다.

더 많은 레이아웃 추가

일반적인 레이아웃 선택:

  • Default — 좁은 콘텐츠 컬럼, 읽기에 좋음
  • Full Width — 더 넓은 콘텐츠 영역, 사이드바 없음
  • Landing Page — 헤더/푸터 없음, 히어로 섹션
  • Sidebar — 사이드바 위젯 영역이 있는 콘텐츠

각각은 src/layouts/ 디렉토리의 또 다른 Astro 컴포넌트이며 라우트의 레이아웃 맵의 또 다른 항목입니다.