Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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>
@end

Everything 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

TaskTool
Wrap a page in shared markupA layout component, $slots.main()
Insert a repeated piece@include('partials/...')
A block with its own parametersA 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.

Thanks for reading!

Donate to the site — we work hard for you.