Skip to content

Commit 13b9030

Browse files
committed
12 layout ok
1 parent 4c13c7e commit 13b9030

1 file changed

Lines changed: 239 additions & 0 deletions

File tree

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Layouts
2+
3+
Hasta ahora hemos estado repetiendo headers y footers en cada página, eso no es muy buena idea, ¿Os acordáis del concepto de layout que vimos en React? Pues en Astro tenemos cosas parecidas, vamos a verlas.
4+
5+
# Manos a la obra
6+
7+
Vamos a definir el layout base para nuestro sitio:
8+
9+
_./src/layouts/base.astro_
10+
11+
```astro
12+
---
13+
import Header from '../components/header.astro';
14+
import Footer from '../components/footer.astro';
15+
import '../styles/global.css';
16+
const pageTitle = "Home Page";
17+
---
18+
<html lang="en">
19+
<head>
20+
<meta charset="utf-8" />
21+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
22+
<meta name="viewport" content="width=device-width" />
23+
<meta name="generator" content={Astro.generator} />
24+
<title>{pageTitle}</title>
25+
</head>
26+
<body>
27+
<Header />
28+
<h1>{pageTitle}</h1>
29+
<Footer />
30+
<script>
31+
import "../scripts/hamburger.ts";
32+
</script>
33+
</body>
34+
</html>
35+
```
36+
37+
Hasta aquí más o menos, pero entre el _header_ y el _footer_ tiene que ir el contenido ¿Qué hacemos? En React tenemos la propiedad _children_ que nos permite hacer esto, en Astro tenemos algo parecido, se llama _slot_.
38+
39+
```diff
40+
<body>
41+
<Header />
42+
<h1>{pageTitle}</h1>
43+
+ <slot />
44+
<Footer />
45+
<script>
46+
import "../scripts/menu.js";
47+
</script>
48+
</body>
49+
```
50+
51+
Vamos ahora a usarlo en la página principal:
52+
53+
_./src/pages/index.astro_
54+
55+
```diff
56+
---
57+
- import "../styles/global.css";
58+
- import Header from "../components/header.astro";
59+
- import Footer from "../components/footer.astro";
60+
+ import BaseLayout from '../layouts/base.astro';
61+
---
62+
63+
- <html lang="en">
64+
- <head>
65+
- <meta charset="utf-8" />
66+
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
67+
- <meta name="viewport" content="width=device-width" />
68+
- <meta name="generator" content={Astro.generator} />
69+
- <title>Mi Blog de Ejemplo</title>
70+
- </head>
71+
- <body>
72+
- <Header />
73+
+ <BaseLayout>
74+
- <h1>Mi blog de Ejemplo 3</h1>
75+
+ <p>contenido de la página</p>
76+
+ </BaseLayout>
77+
- <Footer />
78+
- <script>
79+
- import "../scripts/hamburger.ts";
80+
- </script>
81+
- </body>
82+
-</html>
83+
```
84+
85+
Nos falta un detalle, para el _h1_ del layout base, lo suyo es poder pasarle el contenido por prop, vamos a ello:
86+
87+
_./src/layouts/base.astro_
88+
89+
```diff
90+
---
91+
import Header from "../components/header.astro";
92+
import Footer from "../components/footer.astro";
93+
import "../styles/global.css";
94+
- const pageTitle = "Home Page";
95+
+ interface Props {
96+
+ pageTitle: string;
97+
+ }
98+
+
99+
+ const { pageTitle } = Astro.props as Props;
100+
---
101+
102+
<html lang="en">
103+
```
104+
105+
Y ahora en Index:
106+
107+
_./src/pages/index.astro_
108+
109+
```diff
110+
---
111+
import BaseLayout from "../layouts/base.astro";
112+
---
113+
114+
<BaseLayout
115+
+ pageTitle="Página principal"
116+
>
117+
<p>Contenido de la página</p>
118+
</BaseLayout>
119+
```
120+
121+
Ahora podemos aplicar esto en las otras dos páginas:
122+
123+
_./src/pages/blog.astro_
124+
125+
```diff
126+
---
127+
- import "../styles/global.css";
128+
- import Navigation from "../components/navigation.astro";
129+
+ import BaseLayout from "../layouts/base.astro";
130+
---
131+
```
132+
133+
```diff
134+
- <html lang="en">
135+
- <head>
136+
- <meta charset="utf-8" />
137+
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
138+
- <meta name="viewport" content="width=device-width" />
139+
- <meta name="generator" content={Astro.generator} />
140+
- <title>Acerca de</title>
141+
- </head>
142+
- <body>
143+
- <Navigation />
144+
+ <BaseLayout pageTitle="Blog">
145+
- <h1>Blog</h1>
146+
<h2>Aqui va mi listado de posts</h2>
147+
<ul>
148+
<li><a href="/posts/post-1/">Post 1</a></li>
149+
<li><a href="/posts/post-2/">Post 2</a></li>
150+
<li><a href="/posts/post-3/">Post 3</a></li>
151+
</ul>
152+
+ <BaseLayout>
153+
</body>
154+
</html>
155+
```
156+
157+
_./src/pages/about.astro_
158+
159+
```diff
160+
---
161+
- import "../styles/global.css";
162+
import type { Identity } from "./about.model.ts";
163+
- import Navigation from "../components/navigation.astro";
164+
165+
const pageTitle = "Acerca de dinámico";
166+
167+
const identity: Identity = {
168+
firstName: "Paquillo",
169+
country: "Argentina",
170+
occupation: "Programador",
171+
hobbies: ["fotografía", "beber cerveza", "futbol"],
172+
};
173+
174+
const skills = ["HTML", "CSS", "JavaScript", "React", "Astro"];
175+
const happy = true;
176+
const finished = false;
177+
const goal = 3;
178+
179+
const skillColor = "navy";
180+
---
181+
```
182+
183+
```diff
184+
- <html lang="en">
185+
- <head>
186+
- <meta charset="utf-8" />
187+
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
188+
- <meta name="viewport" content="width=device-width" />
189+
- <meta name="generator" content={Astro.generator} />
190+
- <title>{pageTitle}</title>
191+
- <style define:vars={{ skillColor }}>
192+
- h1 {
193+
- color: purple;
194+
- font-size: 4rem;
195+
- }
196+
- .skill {
197+
- color: var(--skillColor);
198+
- font-weight: bold;
199+
- }
200+
- </style>
201+
- </head>
202+
- <body>
203+
- <Navigation />
204+
-
205+
- <h1>{pageTitle}</h1>
206+
+ <BaseLayout pageTitle={pageTitle}>
207+
<h2>Y mi nuevo blog</h2>
208+
209+
<p>Esta es la página de "acerca de".</p>
210+
211+
<ul>
212+
<li>Me llamo {identity.firstName}.</li>
213+
<li>vivo en {identity.country} y trabajo com {identity.occupation}.</li>
214+
{
215+
identity.hobbies.length >= 2 && (
216+
<li>
217+
Dos de mis hobbies son: {identity.hobbies[0]} and{" "}
218+
{identity.hobbies[1]}
219+
</li>
220+
)
221+
}
222+
</ul>
223+
<p>Mis skills</p>
224+
<ul>
225+
{skills.map((skill) => <li class="skill">{skill}</li>)}
226+
</ul>
227+
{happy && <p>Estoy mu contento !</p>}
228+
229+
{finished && <p>He completado este tutorial</p>}
230+
231+
{
232+
goal === 3 ? (
233+
<p>Mi meta es completarlo en 3 días.</p>
234+
) : (
235+
<p>Pues no llevo tres días.</p>
236+
)
237+
}
238+
+ </BaseLayout>
239+
```

0 commit comments

Comments
 (0)