Перейти к содержимому

Макеты

Макеты - это компоненты Astro, которые определяют структуру пользовательского интерфейса(UI), например, шаблоны страниц.

Мы условно используем термин “макет” для компонентов Astro, которые создают общие элементы UI, такие как заголовки, панели навигации и нижние колонтитулы, используемые на разных страницах. Типичный компонент макета Astro используется для предоставления страницам Astro, Markdown или MDX следующего:

  • оболочки страницы (теги <html>, <head> и <body>)
  • <slot />, чтобы указать, куда должно быть вставлено содержимое отдельной страницы.

Но в макетном компоненте нет ничего особенного! Они могут принимать свойства и импортировать и использовать другие компоненты, как и любой другой компонент Astro. Они могут включать в себя компоненты UI-фреймворков и скрипты на стороне клиента. Они даже не обязательно должны предоставлять полную оболочку страницы, вместо этого их можно использовать как частичные шаблоны пользовательского интерфейса.

Компоненты макета обычно помещаются в раздел src/layouts в вашем проекте для организации, но это не является обязательным; вы можете выбрать местоположение по своему усмотрению. Вы даже можете поместить компоненты макета рядом со своими страницами, добавив префикс _ к именам макетов.

src/layouts/MySiteLayout.astro
---
import BaseHead from '../components/BaseHead.astro';
import Footer from '../components/Footer.astro';
const { title } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<BaseHead title={title}/>
</head>
<body>
<nav>
<a href="#">Home</a>
<a href="#">Posts</a>
<a href="#">Contact</a>
</nav>
<h1>{title}</h1>
<article>
<slot /> <!-- Ваше содержимое вставляется сюда -->
</article>
<Footer />
</body>
</html>
src/pages/index.astro
---
import MySiteLayout from '../layouts/MySiteLayout.astro';
---
<MySiteLayout title="Home Page">
<p>Мой контент, обернутый в макет!</p>
</MySiteLayout>
Узнать больше о слотах.

Макеты страниц особенно полезны для Markdown и MDX файлов, которые иначе не имели бы какого-либо форматирования.

Astro предоставляет специальное свойство layout frontmatter, чтобы указать, какой компонент .astro использовать в качестве макета страницы.

src/pages/page.md
---
layout: ../layouts/BaseLayout.astro
title: "Hello, World!"
author: "Matthew Phillips"
date: "09 Aug 2022"
---
Все свойства frontmatter доступны в качестве входных параметров компонента для макета Astro.
Свойство `layout` - единственное специальное свойство, предоставляемое Astro.
Вы можете использовать его как в Markdown, так и в MDX-файлах, расположенных внутри `src/pages/`.

Типичный макет для страниц Markdown или MDX включает в себя:

  1. Свойство frontmatter для доступа к frontmatter и другим данным страницы Markdown или MDX.
  2. Cтандартный <slot /> для указания места, где должно быть отображено содержимое страницы в формате Markdown/MDX.
src/layouts/BaseLayout.astro
---
// 1. Свойство frontmatter предоставляет доступ к frontmatter и другим данным
const { frontmatter } = Astro.props;
---
<html>
<head>
<!-- Добавьте сюда другие элементы <head>, такие как стили и мета-теги. -->
<title>{frontmatter.title}</title>
</head>
<body>
<!-- Добавьте сюда другие компоненты UI, такие как верхний и нижний колонтитулы страницы. -->
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<!-- 2. Готовый HTML будет передан в стандартный слот. -->
<slot />
<p>Written on: {frontmatter.date}</p>
</body>
</html>

Вы можете установить тип входных параметров компонента макета с помощью вспомогательных функций MarkdownLayoutProps или MDXLayoutProps:

src/layouts/BaseLayout.astro
---
import type { MarkdownLayoutProps } from 'astro';
type Props = MarkdownLayoutProps<{
// Здесь определите свойства frontmatter
title: string;
author: string;
date: string;
}>;
// Теперь свойства макета Markdown, такие как `frontmatter`, `url`,
// и другие, доступны с типобезопасностью
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<link rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.title}</title>
</head>
<body>
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<slot />
<p>Written on: {frontmatter.date}</p>
</body>
</html>

Макет Markdown/MDX будет иметь доступ к следующей информации через Astro.props:

  • file - Абсолютный путь этого файла (например, /home/user/projects/.../file.md).
  • url - Если это страница, то URL страницы (например, /en/guides/markdown-content).
  • frontmatter - Вся мета-информация из документа Markdown или MDX.
    • frontmatter.file - То же, что и свойство верхнего уровня file.
    • frontmatter.url - То же, что и свойство верхнего уровня url.
  • headings - Список заголовков (h1 -> h6) в документе Markdown или MDX с соответствующими метаданными. Этот список следует типу: { depth: number; slug: string; text: string }[].
  • (Только для Markdown) rawContent() - Функция, возвращающая необработанный документ Markdown в виде строки.
  • (Только для Markdown) compiledContent() - Функция, возвращающая документ Markdown, скомпилированный в HTML-строку.

Пример записи блога в формате Markdown может передавать в макет следующий объект Astro.props:

Astro.props = {
file: "/home/user/projects/.../file.md",
url: "/en/guides/markdown-content/",
frontmatter: {
/** Frontmatter из записи в блоге */
title: "Astro 0.18 Release",
date: "Tuesday, July 27 2021",
author: "Matthew Phillips",
description: "Astro 0.18 is our biggest release since Astro launch.",
/** Сгенерированные значения */
file: "/home/user/projects/.../file.md",
url: "/en/guides/markdown-content/"
},
headings: [
{
"depth": 1,
"text": "Astro 0.18 Release",
"slug": "astro-018-release"
},
{
"depth": 2,
"text": "Responsive partial hydration",
"slug": "responsive-partial-hydration"
}
/* ... */
],
/** Доступно только для Markdown */
rawContent: () => "# Astro 0.18 Release\nA little over a month ago, the first public beta [...]",
compiledContent: () => "<h1>Astro 0.18 Release</h1>\n<p>A little over a month ago, the first public beta [...]</p>",
}

Вам может понадобиться передать в MDX макет информацию, которая не существует (или не может существовать) в frontmatter. В этом случае вы можете импортировать и использовать компонент <Layout /> и передавать ему входные параметры, как любому другому компоненту:

src/pages/posts/first-post.mdx
---
layout: ../../layouts/BaseLayout.astro
title: 'My first MDX post'
publishDate: '21 September 2022'
---
import BaseLayout from '../../layouts/BaseLayout.astro';
export function fancyJsHelper() {
return "Try doing that with YAML!";
}
<BaseLayout title={frontmatter.title} fancyJsHelper={fancyJsHelper}>.
Welcome to my new Astro blog, using MDX!
</BaseLayout>

Затем ваши значения будут доступны вам через Astro.props в вашем макете, и ваш MDX-контент будет внедрен на страницу, где прописан ваш компонент <slot />:

src/layouts/BaseLayout.astro
---
const { title, fancyJsHelper } = Astro.props;
---
<!-- -->
<h1>{title}</h1>
<slot /> <!-- здесь вставляется ваш контент -->
<p>{fancyJsHelper()}</p>
<!-- -->
Подробнее о поддержке в Astro Markdown и MDX вы можете узнать из нашего руководства по Markdown/MDX.

Использование одного макета для .md, .mdx и .astro

Заголовок раздела Использование одного макета для .md, .mdx и .astro

Можно написать один макет Astro, который будет принимать объект frontmatter из файлов .md и .mdx, а также любые именованные входные параметры, передаваемые из файлов .astro.

В приведенном ниже примере макет будет отображать заголовок страницы либо из свойства title в frontmatter YAML, либо из атрибута title, переданного компонентом Astro:

src/components/MyLayout.astro
---
const { title } = Astro.props.frontmatter || Astro.props;
---
<html>
<head></head>
<body>
<h1>{title}</h1>
<slot />
</body>
</html>

Компоненты макета не обязательно должны содержать целую страницу HTML. Вы можете разбить свои макеты на более мелкие компоненты и комбинировать их, чтобы создавать еще более гибкие шаблоны страниц. Этот шаблон полезен, когда вы хотите совместно использовать некоторый код в нескольких макетах.

Например, макет компонента BlogPostLayout.astro может стилизовать заголовок, дату и автора статьи. Затем, глобальный макет BaseLayout.astro может обрабатывать остальную часть вашего шаблона страницы, такую как навигация, нижние колонтитулы, мета-теги SEO, глобальные стили и шрифты. Вы также можете передавать входные параметры, полученные из вашей статьи, в другой макет, так же как и любой другой вложенный компонент.

src/layouts/BlogPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout url={frontmatter.url}>
<h1>{frontmatter.title}</h1>
<h2>Post author: {frontmatter.author}</h2>
<slot />
</BaseLayout>