Page layout and partials
All blog pages share the same <head>, header and footer. Copying them into every template is bad: changing the menu would mean editing every file. The shared markup goes into a layout — a wrapper template that the page content is placed into. In Edge 6 a layout is an ordinary component.
The layout file
Edge turns templates from resources/views/components/ into tags: the file components/layout.edge becomes the @layout tag. Create the layout:
node ace make:view components/layout{{-- resources/views/components/layout.edge --}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ title ?? 'My blog' }}</title>
</head>
<body>
<header>
<a href="/">My blog</a>
</header>
<main>
{{{ await $slots.main() }}}
</main>
<footer>A blog on AdonisJS</footer>
</body>
</html>$slots.main() returns whatever the page put inside the tag. Triple braces are needed because it is ready HTML, and await because the slot content is rendered asynchronously.
A page with the layout
Rewrite the post list so it uses the layout:
{{-- resources/views/pages/posts/index.edge --}}
@layout({ title: 'All posts' })
<h1>All posts</h1>
<ul>
@each(post in posts)
<li>{{ post.title }}</li>
@end
</ul>
@endEverything between @layout(...) and @end goes into $slots.main(). The object in parentheses holds the component's props: title becomes a variable inside the layout. Open /posts: the page now has a header, a footer and the tab title "All posts".
Partials
A piece of markup that repeats on several pages but does not wrap them goes into a partial, included with the @include tag:
{{-- resources/views/partials/nav.edge --}}
<nav>
<a href="{{ route('posts.index') }}">Posts</a>
<a href="/about">About</a>
</nav>{{-- resources/views/components/layout.edge --}}
<header>
<a href="/">My blog</a>
@include('partials/nav')
</header>A partial sees the same variables as the template that included it.
What to use when
| Task | Tool |
|---|---|
| Wrap a page in shared markup | A layout component, $slots.main() |
| Insert a repeated piece | @include('partials/...') |
| A block with its own parameters | A component (next lesson) |
Common mistake
If the layout uses {{ await $slots.main() }} with double braces, the page shows the HTML code as text instead of markup: Edge escapes it like any output. Always use triple braces {{{ }}} for slots.