Skip to content

Commit 4fd081d

Browse files
docs: #217 latest guidelines and behaviors for pages and layouts (#247)
1 parent d735e36 commit 4fd081d

3 files changed

Lines changed: 54 additions & 39 deletions

File tree

src/pages/docs/pages/layouts.md

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,17 @@ src/
3131

3232
> **Note:** You can use either relative (_../_) or absolute (_/_) paths in your layouts since using _../_ will allow for IDE autocomplete on your filesystem, but is marginally slower than using _/_.
3333
34-
## Pages
34+
## Page Layout
3535

36-
Pages in your project will generally want a layout so you can control the output of the HTML and include all your own custom components and styles to wrap the content. By default all pages will default to looking for a _page.html_ in the _layouts/_ directory. A placeholder of `<content-outlet></content-outlet>` can be used to position where the processed content from the incoming page will go.
36+
Pages in your project will generally want a layout so you can control the output of the HTML and include all your own custom components and styles to wrap your content; think of a shared layout for all blog posts, which might be distinct from your home or docs pages. By default all pages will default to looking for a _page.html_ in the _layouts/_ directory. A placeholder of `<content-outlet></content-outlet>` can be used to position where the content from the incoming page will go.
37+
38+
> Dynamic layouts are [also supported](/docs/pages/server-rendering/#layouts).
3739
3840
Below is an example of a _page.html_ layout:
3941

4042
<!-- prettier-ignore-start -->
4143

42-
<app-ctc-block variant="snippet">
44+
<app-ctc-block variant="snippet" heading="src/pages/layouts/page.html">
4345

4446
```html
4547
<!doctype html>
@@ -81,15 +83,15 @@ You can create more layouts and use them for pages with the following steps:
8183

8284
<!-- prettier-ignore-end -->
8385

84-
## App
86+
## App Layout
8587

86-
To customize the outer most wrapping HTML of your layouts, create an _app.html_ file. Like a page layout, this will just be another HTML document and a `<page-outlet></page-outlet>` placeholder that can be used to position where the content from the processed page layout will appear.
88+
To customize the outer most wrapping HTML of _all_ your pages, create an _app.html_ file. This is most useful for global page elements like headers, navigation, and footers. Like a page layout, this will just be another HTML document (or JS / TS file) with a `<page-outlet></page-outlet>` placeholder that can be used to position where the content from the processed page layout will appear.
8789

88-
As with Page layouts, App layouts are just HTML:
90+
Below is an HTML example of an app layout:
8991

9092
<!-- prettier-ignore-start -->
9193

92-
<app-ctc-block variant="snippet">
94+
<app-ctc-block variant="snippet" heading="src/pages/layouts/app.html">
9395

9496
```html
9597
<!doctype html>
@@ -114,34 +116,43 @@ As with Page layouts, App layouts are just HTML:
114116

115117
<!-- prettier-ignore-end -->
116118

117-
> When an app layout is present, Greenwood will merge the `<head>` and `<body>` tags for both app and page layouts into one HTML document structure for you.
119+
> In general, you will want to start with an app layout, then create page specific layouts as needed for more specific custom layout needs.
118120
119121
## Server Rendering
120122

121123
Server rendered layouts can also be authored using Web Components:
122124

123-
```js
124-
// src/layouts/app.js
125-
export default class AppLayout extends HTMLElement {
126-
async connectedCallback() {
127-
const year = new Date().getFullYear();
128-
129-
this.innerHTML = `
130-
<!DOCTYPE html>
131-
<html>
132-
<head>
133-
<title>My App</title>
134-
</head>
135-
136-
<body>
137-
<h1>My App</h1>
138-
<page-outlet></page-outlet>
139-
<footer>&copy; ${year}</footer>
140-
</body>
141-
</html>
142-
`;
125+
<!-- prettier-ignore-start -->
126+
127+
<app-ctc-block variant="snippet" heading="src/pages/layouts/page.js">
128+
129+
```js
130+
export default class PageLayout extends HTMLElement {
131+
constructor({ compilation, page }) {
132+
super();
133+
this.route = page.route;
134+
this.numPages = compilation.graph.length;
135+
}
136+
137+
async connectedCallback() {
138+
this.innerHTML = `
139+
<html>
140+
<head>
141+
<title>My App</title>
142+
</head>
143+
<body>
144+
<h2>Page Layout for ${this.route}</h2>
145+
<span>Number of pages ${this.numPages}</span>
146+
<content-outlet></content-outlet>
147+
</body>
148+
</html>
149+
`;
150+
}
143151
}
144-
}
145-
```
152+
```
153+
154+
</app-ctc-block>
155+
156+
<!-- prettier-ignore-end -->
146157

147158
> ⚠ This layout component will _only run once at build time_. Dynamic "runtime" layouts are [planned](https://github.com/ProjectEvergreen/greenwood/issues/1248).

src/pages/docs/pages/routing.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ src/
8484
index.html
8585
```
8686

87+
> [SPA based projects](/docs/pages/routing/#spa) do **not** support layouts or (active) frontmatter.
88+
8789
## Not Found
8890

8991
As is a [common convention with most hosting providers](https://docs.netlify.com/routing/redirects/redirect-options/#custom-404-page-handling) and web servers, you can create a `404` page in your _pages/_ directory which will be used as the default **Not Found** page for your site.

src/pages/docs/pages/server-rendering.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ This is the recommended pattern for SSR in Greenwood:
6767

6868
<!-- prettier-ignore-start -->
6969

70-
<app-ctc-block variant="snippet" heading="src/pages/api/greeting.js">
70+
<app-ctc-block variant="snippet" heading="src/pages/user.js">
7171

7272
```js
7373
import "../components/card/card.js"; // <x-card></x-card>
@@ -106,6 +106,8 @@ A couple of notes:
106106
- WSCs run only on the server, thus you have full access to any APIs of the runtime, with the ability to perform one time `async` operations for [data loading](/docs/pages/server-rendering/#request-data) in `connectedCallback`.
107107
- Keep in mind that for these "page" components, you will likely want to _avoid_ rendering into a shadow root, as then your content and styles will be encapsulated.
108108

109+
> You can also author [dynamic layouts](/docs/pages/layouts/#server-rendering) in this way as well!
110+
109111
### Body
110112

111113
To return just the body of the page, you can use the `getBody` API. You will get access to the [compilation](/docs/reference/appendix/#compilation), page specific data, and the incoming request.
@@ -114,7 +116,7 @@ In this example, we return a list of users from an API as HTML:
114116

115117
<!-- prettier-ignore-start -->
116118

117-
<app-ctc-block variant="snippet">
119+
<app-ctc-block variant="snippet" heading="src/pages/my-page.js">
118120

119121
```js
120122
export async function getBody(/* compilation, page, request */) {
@@ -124,11 +126,11 @@ In this example, we return a list of users from an API as HTML:
124126
const { name, imageUrl } = user;
125127

126128
return `
127-
<tr>
128-
<td>${name}</td>
129-
<td><img src="${imageUrl}"/></td>
130-
</tr>
131-
`;
129+
<tr>
130+
<td>${name}</td>
131+
<td><img src="${imageUrl}"/></td>
132+
</tr>
133+
`;
132134
});
133135

134136
return `
@@ -159,7 +161,7 @@ You can pull in data from Greenwood's [compilation](/docs/reference/appendix/#co
159161

160162
<!-- prettier-ignore-start -->
161163

162-
<app-ctc-block variant="snippet">
164+
<app-ctc-block variant="snippet" heading="src/pages/my-page.js">
163165

164166
```js
165167
export async function getLayout(compilation, route) {
@@ -200,7 +202,7 @@ Any Greenwood [supported frontmatter](/docs/resources/markdown/#frontmatter) can
200202

201203
<!-- prettier-ignore-start -->
202204

203-
<app-ctc-block variant="snippet">
205+
<app-ctc-block variant="snippet" heading="src/pages/my-page.js">
204206

205207
```js
206208
export async function getFrontmatter(compilation, route) {

0 commit comments

Comments
 (0)