Working with PocketPages Layouts
PocketPages provides a powerful layout system that allows you to create consistent page structures by defining layouts that can wrap your content. Layouts are defined using +layout.ejs files and are applied in a bottom-up order, meaning that each higher-level layout wraps the content of the child layout. This guide will explain how layouts work in PocketPages and how to use them effectively.
What is a Layout?
A layout in PocketPages is an EJS template file named +layout.ejs. Layouts are used to define the overall structure of your pages, such as headers, footers, and common navigation elements, which can be shared across multiple pages. Layouts are traversed in a bottom-up order, meaning that the layout closest to the content is applied first, and each parent layout wraps the child layout.
Example Directory Structure
pb_hooks/pages/
+layout.ejs
products/
+layout.ejs
[productId]/
index.ejs
details.ejs
How Layouts are Applied
- Leaf Page: The
index.ejsordetails.ejsfile is the leaf page, where the final content is rendered. - Child Layout: The
+layout.ejsin the[productId]/directory is applied first, wrapping the content ofindex.ejsordetails.ejs. - Parent Layout: The
+layout.ejsin theproducts/directory is then applied, wrapping the content from the child layout. - Root Layout: Finally, the
+layout.ejsat the root level (pages/+layout.ejs) wraps the entire content, providing the final structure of the page.
Using the slot Variable
In +layout.ejs files, a special slot variable is provided in the context. This variable represents the content that will be placed inside the layout. The slot variable is available only in +layout.ejs files.
Example Usage of slot
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Application</title>
</head>
<body>
<header>
<h1>Welcome to My Application</h1>
</header>
<main>
<%- slot %>
</main>
<footer>
<p>© <%= new Date().getFullYear() %> My Application</p>
</footer>
</body>
</html>
In this example, the slot variable is used to place the interior content (from the child layout or the leaf page) within the <main> tag of the layout.
Multiple Slots
PocketPages provides two ways to work with content in layouts: the slot string which always contains the full content, and a slots object for accessing named sections of that content.
Basic Slot Usage
For simple layouts with a single content area, you can use the slot variable which contains all the content:
<!DOCTYPE html>
<html>
<body>
<%- slot %>
</body>
</html>
Working with Multiple Slots
For more complex layouts, you can divide your content into named sections using HTML comments and access them through the slots object, while slot continues to contain the complete content:
<!-- In your content file (e.g., index.ejs) -->
<!-- slot:header -->
<h2>Product Details</h2>
<!-- slot:sidebar -->
<nav>Navigation items...</nav>
<!-- slot:body -->
<p>This is the main content of the product page.</p>
Then in your layout, access these named slots using the slots object:
<!DOCTYPE html>
<html>
<head>
<title>Product Page</title>
</head>
<body>
<header>
<%- slots.header || 'Default Header' %>
</header>
<div class="sidebar">
<%- slots.sidebar %>
</div>
<main>
<!-- slots.body falls back to showing the full content if body slot isn't defined -->
<%- slots.body || slot %>
</main>
<!-- slot always contains the complete content, regardless of slot definitions -->
<div class="debug">
<%- slot %>
</div>
</body>
</html>
Note the following patterns:
- The
slotvariable always contains the complete content, whether or not slots are defined - Use
slots.nameto access a specific named section - Provide defaults with
slots.name || 'Default Content' - Use
slots.body || slotto create a main content area that shows either the body slot or all content
Leaf +load.js Data Availability
In layouts, the data object from the +load.js file at the leaf level (e.g., index.ejs) is available. However, it is important to note that the data object from the +load.js file at the layout level is not available in the layout itself. This means that the layout can access only the data passed from the leaf page.
When Layouts are Not Applied
Layouts are only applied to leaf EJS files that return HTML content. If an EJS file returns a JSON response, the layouts will not be executed. This ensures that layouts are used only for rendering HTML pages, keeping API responses clean and efficient.