Layout
Layouty to komponenty Astro używane do tworzenia ponownie używalnej struktury UI, takiej jak szablon strony.
Umownie korzystamy z terminu “layout” dla komponentów, które zapewniają wspólne elementy interfejsu wspóldzielone na stronach, takie jak stopki, nagłówki czy nawigacja. Najczęściej layout przekazuje stronom Astro, Markdown bądź MDX:
- powłokę strony (tagi
<html>
,<head>
i<body>
) - tag
<slot />
aby okreslić miejsce gdzie treść ma zostać wstrzyknięta.
Ale w komponencie układu nie ma nic szczególnego! Layouty mogą akceptować propy oraz importować i korzystać z innych komponentów jak każdy inny komponent Astro. Potrafią też zawierać w sobie komponenty frameworków UI i skrypty client-side. Nie muszą nawet posiadać całej powłoki strony, a jedynie być wykorzystywane jako cząstkowe szablony UI.
Jednakże, jeśli komponent layout’u zawiera powłokę strony, to jego tag <html>
musi być elementem nadrzędnym wszystkich innych elementów. Wszystkie znaczniki <style>
lub <script>
muszą zostać zawarte w elemencie <html>
.
Komponenty layout’u zazwyczaj znajdują się w folderze src/layouts
Twojego projektu, aby zadbać o organizację. Nie jest to jednak wymóg; możesz je umieszczać w dowolnym miejscu projektu. Mogą one nawet istnieć obok swoich stron, przez dodanie prefiksu _
do nazw layout’ów.
Przykładowy layout
Dział zatytułowany Przykładowy layout---import BaseHead from '../components/BaseHead.astro';import Footer from '../components/Footer.astro';const { title } = Astro.props;---<html lang="pl"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <BaseHead title={title}/> </head> <body> <nav> <a href="#">Strona główna</a> <a href="#">Posty</a> <a href="#">Kontakt</a> </nav> <h1>{title}</h1> <article> <slot /> <!-- tutaj jest wstrzykiwany Twój komponent --> </article> <Footer /> </body> <style> h1 { font-size: 2rem; } </style></html>
---import MySiteLayout from '../layouts/MySiteLayout.astro';---<MySiteLayout title="Strona domowa"> <p>Hej, to moja zawartość strony w layout'cie!</p></MySiteLayout>
Używanie TypeScript w layout’ach
Dział zatytułowany Używanie TypeScript w layout’achKażdy layout Astro można zmodyfikować tak, aby wprowadzić bezpieczeństwo typów i automatyczne uzupełnianie, podając typy dla swoich propów:
---interface Props { title: string; description: string; publishDate: string; viewCount: number;}const { title, description, publishDate, viewCount } = Astro.props;---<html lang="pl"> <head> <meta charset="UTF-8"> <meta name="description" content={description}> <title>{title}</title> </head> <body> <header> <p>Opublikowano {publishDate}</p> <p>Wyświetlone przez {viewCount} osób</p> </header> <main> <slot /> </main> </body></html>
Layouty Markdown
Dział zatytułowany Layouty MarkdownLayouty stron są szczególnie użyteczne w przypadku pojedynczych stron Markdown, które w innym wypadku nie miałyby żadnego formatowania.
Astro udostępnia specjalną właściwość frontmatter layout
, która pozwala określić, który komponent .astro
ma zostać użyty jako layout strony. Domyślnie ten określony komponent może automatycznie odbierać dane z pliku Markdown.
---layout: ../layouts/BlogPostLayout.astrotitle: "Witaj świecie!"author: "Matthew Phillips"date: "09 Aug 2022"---Wszystkie właściwości frontmatter są dostępne jako propy dla komponentu layout'u Astro.
Właściwość `layout` jest jedyną specjalną, którą udostępnia Astro.
Możesz ją używać w swoich plikach Markdown znajdujących się w `src/pages/`.
Typowy layout strony Markdown zawiera:
- Prop
frontmatter
umożliwiający dostęp do frontmatteru strony Markdown i innych danych. - Domyślny tag
<slot />
wskazujący miejsce, gdzie ma wyrenderować się zawartość strony Markdown.
---// 1. Prop frontmatter umożliwia dostęp do frontmatteru strony Markdown i innych danych.const { frontmatter } = Astro.props;---<html> <head> <!-- Tutaj dodaj inne elementy <head>, jak style czy tagi meta. --> <title>{frontmatter.title}</title> </head> <body> <!-- Tutaj wstaw inne elementy UI, jak nagłówki czy stopki. --> <h1>{frontmatter.title} przez {frontmatter.author}</h1> <!-- 2. Wyrenderowany HTML będzie przekazany do domyślnego slotu. --> <slot /> <p>Napisane dnia: {frontmatter.date}</p> </body></html>
Możesz ustawić typ Props
layout’u z pomocnikiem MarkdownLayoutProps
:
---import type { MarkdownLayoutProps } from 'astro';
type Props = MarkdownLayoutProps<{ // Tu zdefiniuj propy frontmatteru title: string; author: string; date: string;}>;
// Teraz, `frontmatter`, `url`, i inne właściwości layout'u Markdown// są dostępne z bezpiecznymi typami.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} przez {frontmatter.author}</h1> <slot /> <p>Napisane dnia: {frontmatter.date}</p> </body></html>
Propy layout’u Markdown
Dział zatytułowany Propy layout’u MarkdownLayout Markdown będzie miał dostęp do tych informacji dzięki Astro.props
:
file
- Ścieżka absolutna do pliku (np./home/user/projects/.../file.md
).url
- Adres URL strony (np./pl/guides/markdown-content
).frontmatter
- Każdy element frontmatter z dokumentów Markdown lub MDX.frontmatter.file
- Taka sama jak właściwośćfile
najwyższego poziomu.frontmatter.url
- Taka sama jak właściwośćurl
najwyższego poziomu.
headings
- Lista nagłówków (h1 -> h6
) w dokumencie Markdown lub MDX z powiązanymi metadanymi. Ta lista jest zgodna z typem:{ depth: number; slug: string; text: string }[]
.rawContent()
- Funkcja zwracająca surowy dokument Markdown jako ciąg znaków.compiledContent()
- Funkcja zwracająca dokument Markdown skompilowany do ciągu HTML.
Layout Markdown będzie miał dostęp do wszystkich dostępnych właściwości pliku Markdown z Astro.props
z dwoma kluczowymi różnicami:
-
Informacje o nagłówku (czyli elementy
h1 -> h6
) są dostępne za pomocą tablicyheadings
, a nie funkcjigetHeadings()
. -
file
iurl
także są dostępne jako zagnieżdżone właściwościfrontmatter
(czylifrontmatter.url
ifrontmatter.file
).
Importowanie layout’ów ręcznie (MDX)
Dział zatytułowany Importowanie layout’ów ręcznie (MDX)Możesz również użyć specjalnej właściwości layout
w frontmatter plików MDX, aby przekazać frontmatter
i headings
bezpośrednio do określonego komponentu layout’u w ten sam sposób.
Aby przekazać informacje do layout’u MDX, które nie istnieją (lub nie mogą istnieć) w Twoim frontmatter, możesz zamiast tego zaimportować i użyć komponentu <Layout />
. Działa to jak każdy inny komponent Astro i nie otrzyma automatycznie żadnych propów. Przekaż mu niezbędne propy bezpośrednio:
---layout: ../../layouts/BaseLayout.astrotitle: 'Mój pierwszy post MDX'publishDate: '21 Wrzesień 2022'---import BaseLayout from '../../layouts/BaseLayout.astro';
export function fancyJsHelper() { return "Spróbuję to zrobić za pomocą YAML'a!";}
<BaseLayout title={frontmatter.title} fancyJsHelper={fancyJsHelper}> Witaj na moim nowym Astro blogu MDX!</BaseLayout>
Potem Twoje wartości będą dostępne dla Ciebie poprzez Astro.props
w layout’cie, a Twoja zawartość MDX zostanie wstrzyknięta na stronę tam, gdzie jest napisany komponent <slot />
:
---const { title, fancyJsHelper } = Astro.props;---<!-- --><h1>{title}</h1><slot /> <!-- tutaj jest wstrzykiwana Twoja zawartość strony --><p>{fancyJsHelper()}</p><!-- -->
Zagnieżdżanie layout’ów
Dział zatytułowany Zagnieżdżanie layout’ówKomponenty layout’u nie muszą zawierać całej strony HTML. Możesz podzielić swoje Layouty na mniejsze komponenty, a następnie łączyć je, aby stworzyć jeszcze bardziej elastyczne szablony stron. Ten wzorzec jest przydatny, gdy chcesz współdzielić kod między wieloma layout’ami.
Dla przykładu, layout BlogPostLayout.astro
mógłby stylować tytuł, datę i autora posta. Następnie, globalny layout BaseLayout.astro
mógłby obsługiwać resztę szablonu strony, takie jak nawigację, stopki, tagi meta SEO, globalne style i czcionki. Możesz również przekazać propy otrzymane z Twojego posta do innego layout’u, tak jak każdy inny zagnieżdzony komponent.
---import BaseLayout from './BaseLayout.astro';const { frontmatter } = Astro.props;---<BaseLayout url={frontmatter.url}> <h1>{frontmatter.title}</h1> <h2>Autor posta: {frontmatter.author}</h2> <slot /></BaseLayout>