WordPress 개발자를 위한 Astro

이 페이지

Astro는 EmDash 사이트의 페이지, 레이아웃, 컴포넌트 및 서버 렌더링을 제공합니다. 이 가이드는 현재 EmDash 템플릿에서 사용되는 Astro 개념을 다룹니다. WordPress 테마와 PHP 템플릿을 이미 이해하고 있다고 가정합니다.

EmDash에 특화되지 않은 프레임워크 기능은 Astro 문서를 참조하세요.

프로젝트 구조

Astro 사이트는 각 파일 유형에 명시적인 디렉터리를 할당합니다. 현재 EmDash 템플릿은 다음 구조를 사용합니다:

WordPressAstro용도
index.php, single.php, page.phpsrc/pages/URL 라우트
template-parts/src/components/재사용 가능한 마크업
header.phpfooter.phpsrc/layouts/공유 페이지 셸
style.csssrc/styles/사이트 스타일
플러그인 및 데이터베이스 설정astro.config.mjs통합 및 서버 어댑터
테마 설정 데이터seed/seed.json컬렉션, 메뉴, 샘플 콘텐츠

블로그 템플릿은 공개 URL과 일치하는 라우트 디렉터리를 사용합니다:

src/
├── components/
│   └── PostCard.astro
├── layouts/
│   └── Base.astro
├── pages/
│   ├── index.astro
│   ├── pages/
│   │   └── [slug].astro
│   └── posts/
│       ├── index.astro
│       └── [slug].astro
└── live.config.ts

Astro 컴포넌트

.astro 컴포넌트는 서버 사이드 TypeScript와 HTML 템플릿을 결합합니다. --- 펜스 사이의 코드는 서버에서 실행됩니다. 두 번째 펜스 아래의 마크업이 응답 HTML이 됩니다.

다음 컴포넌트는 프론트매터에서 props를 선언하고 템플릿에서 렌더링합니다:

---
interface Props {
  title: string;
  excerpt?: string;
  href: string;
}

const { title, excerpt, href } = Astro.props;
---

<article>
  <h2><a href={href}>{title}</a></h2>
  {excerpt && <p>{excerpt}</p>}
</article>

Astro는 {value}로 렌더링되는 값을 이스케이프합니다. import, 데이터베이스 쿼리 및 기타 서버 작업은 프론트매터에 속합니다.

템플릿 표현식

Astro 템플릿은 PHP 템플릿이 <?php ?>로 전환하는 곳에서 중괄호를 사용합니다. EmDash 템플릿에서 가장 일반적인 패턴은 값, 조건, 배열 매핑입니다:

목적Astro 구문
값 출력{post.data.title}
값이 존재할 때 렌더링{post.data.excerpt && <p>{post.data.excerpt}</p>}
두 결과 중 선택{posts.length === 0 ? <p>아직 게시물이 없습니다.</p> : <PostList />}
목록 렌더링{posts.map((post) => <PostCard title={post.data.title} excerpt={post.data.excerpt} href={"/posts/" + post.id} />)}

표현식은 프론트매터에서 준비된 변수, Astro.props의 값, 또는 EmDash 쿼리에서 반환된 데이터를 사용할 수 있습니다. Astro는 기본적으로 문자열 값을 이스케이프합니다. HTML을 주입하는 대신 구조화된 리치 텍스트에는 <PortableText />와 같은 렌더러를 사용하세요.

Props와 슬롯

Props는 get_template_part()에 전달되는 $args와 비슷합니다. 각 입력을 명시적으로 만들며 TypeScript로 확인할 수 있습니다.

슬롯은 부모가 컴포넌트에 마크업을 전달할 수 있게 합니다. 기본 슬롯은 페이지 콘텐츠에 유용하며, 이름이 지정된 슬롯은 추가 삽입 지점을 제공합니다:

---
interface Props {
  title: string;
}

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

<article>
  <h2>{title}</h2>
  <slot />
  <footer><slot name="footer" /></footer>
</article>

다음 페이지는 두 슬롯을 모두 채웁니다:

---
import Card from "../components/Card.astro";
---

<Card title="최신 게시물">
  <p>카드의 메인 콘텐츠.</p>
  <a slot="footer" href="/posts/latest">게시물 읽기</a>
</Card>

슬롯은 컴포넌트 호출에 로컬입니다. 다른 곳에서 등록된 콜백을 받을 수 있는 WordPress 액션과는 다르게 동작합니다.

레이아웃

레이아웃은 WordPress 테마가 header.phpfooter.php 사이에 나누는 공유 문서 구조를 소유합니다. 페이지는 레이아웃을 가져오고 슬롯을 통해 콘텐츠를 전달합니다.

다음 레이아웃은 문서 셸을 제공합니다:

---
interface Props {
  title: string;
}

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

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{title}</title>
  </head>
  <body>
    <header><a href="/">내 사이트</a></header>
    <main><slot /></main>
  </body>
</html>

다음 페이지는 레이아웃의 제목과 메인 콘텐츠를 제공합니다:

---
import Base from "../layouts/Base.astro";
---

<Base title="홈">
  <h1>최신 게시물</h1>
</Base>

파일 기반 라우팅

src/pages/의 파일이 라우트를 정의합니다. 대괄호로 된 파일 이름은 동적 세그먼트를 생성합니다.

파일URL
src/pages/index.astro/
src/pages/posts/index.astro/posts
src/pages/posts/[slug].astro/posts/hello-world
src/pages/pages/[slug].astro/pages/about

src/pages/posts/[slug].astro 내에서 Astro.params.slug는 URL의 값을 포함합니다. rest 파라미터, 리다이렉트 및 기타 라우팅 기능에 대해서는 Astro 라우팅을 참조하세요.

서버 렌더링

현재 EmDash 템플릿은 astro.config.mjs에서 output: "server"를 사용합니다. 따라서 페이지는 각 요청마다 데이터베이스를 쿼리할 수 있으므로, 게시된 콘텐츠가 새로운 정적 빌드에 의존하지 않습니다.

사이트가 의도적으로 EmDash를 빌드 시 데이터 소스로 취급하지 않는 한, EmDash 테마 라우트에 getStaticPaths()를 추가하지 마세요. 제공되는 테마는 서버 렌더링됩니다.

프레임워크 수준의 동작에 대해서는 Astro 온디맨드 렌더링을 참조하세요.

EmDash 콘텐츠 쿼리

EmDash는 getEmDashCollection()getEmDashEntry()로 Astro 라이브 콘텐츠 컬렉션을 래핑합니다. 컬렉션 결과는 entries 배열을 포함합니다. 단일 항목 결과는 entry를 포함하며, 게시된 항목이 일치하지 않으면 null입니다.

다음 아카이브는 현재 블로그 템플릿과 동일한 정렬 및 식별자를 사용합니다:

---
import { getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";

const { entries: posts, error } = await getEmDashCollection("posts", {
  orderBy: { published_at: "desc" },
});

if (error) {
  return new Response("게시물을 불러올 수 없습니다", { status: 500 });
}
---

<Base title="게시물">
  {posts.map((post) => (
    <article>
      <h2><a href={`/posts/${post.id}`}>{post.data.title}</a></h2>
      {post.data.excerpt && <p>{post.data.excerpt}</p>}
    </article>
  ))}
</Base>

post.id는 Astro가 노출하는 라우트 식별자이며, 일반적으로 항목의 슬러그입니다. post.data.id는 데이터베이스 식별자입니다. 택소노미나 댓글 헬퍼와 같이 API가 저장된 콘텐츠 ID를 기대하는 경우 data.id를 사용하세요.

다음 동적 라우트는 URL의 슬러그로 게시물을 조회하고 Portable Text 필드를 렌더링합니다:

---
import { decodeSlug, getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "../../layouts/Base.astro";

const slug = decodeSlug(Astro.params.slug);
if (!slug) return Astro.redirect("/404");

const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) return new Response("게시물을 불러올 수 없습니다", { status: 500 });
if (!post) return Astro.redirect("/404");
---

<Base title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <PortableText value={post.data.content} />
  </article>
</Base>

Astro 계속 배우기

EmDash 템플릿은 컴포넌트 스타일과 소규모 브라우저 스크립트도 사용하지만, 이는 EmDash 개념이 아닌 일반적인 Astro 기능입니다. 범위 지정 및 전역 스타일에 대해서는 스타일과 CSS를, 컴포넌트에 브라우저 측 동작이 필요한 경우 스크립트와 이벤트 처리를 참조하세요.