Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Edge components

A component is a template for a repeated block with its own parameters: a post card, a button, an error message. You write it once and use it on different pages with different data. The layout from the previous lesson was a component too.

A component with props

Create a post card:

node ace make:view components/post/card
{{-- resources/views/components/post/card.edge --}}
<article class="post-card">
  <h2>
    <a href="{{ route('posts.show', { id: post.id }) }}">{{ post.title }}</a>
  </h2>
  <p>{{ post.excerpt }}</p>
</article>

The post variable comes from outside as a component prop. The file is in the nested post folder, so the tag is called @post.card.

Using the component

{{-- resources/views/pages/posts/index.edge --}}
@layout({ title: 'All posts' })
  @each(post in posts)
    @!post.card({ post })
  @end
@end

The exclamation mark in @!post.card means a tag without content: no closing @end is needed. The page shows each post as a separate card.

The default slot

To pass markup into a component, use a slot. Let us make a notice block:

{{-- resources/views/components/alert.edge --}}
<div class="alert alert-{{ type ?? 'info' }}">
  {{{ await $slots.main() }}}
</div>
{{-- resources/views/pages/posts/show.edge --}}
@alert({ type: 'warning' })
  This post is not published yet. <a href="/posts">Back to the list</a>
@end

The content between the tags goes into $slots.main(), and the type prop picks the CSS class. Without the prop the block gets the class alert-info.

Named slots

Sometimes a component needs several places for markup. They are named with the @slot tag:

{{-- resources/views/components/panel.edge --}}
<section class="panel">
  <header>{{{ await $slots.header() }}}</header>
  <div>{{{ await $slots.main() }}}</div>
</section>
{{-- resources/views/pages/posts/show.edge --}}
@panel()
  @slot('header')
    Comments
  @end
 
  <p>No comments yet.</p>
@end

The text "Comments" ends up in the panel header, and the paragraph in the main part. If a slot may be missing, check for it: @if($slots.header).

Another syntax

Docs and older projects use the @component tag. It does the same thing:

{{-- resources/views/pages/posts/index.edge --}}
@!component('components/post/card', { post })

Common mistake

Components are looked up only in resources/views/components/. If you put card.edge into resources/views/partials/, the @card tag fails with an unknown tag error. Use @include for pieces without parameters and keep components in components.

Thanks for reading!

Donate to the site — we work hard for you.