Компоненты Edge
Компонент — это шаблон для повторяющегося блока со своими параметрами: карточка статьи, кнопка, сообщение об ошибке. Его пишут один раз, а используют на разных страницах с разными данными. Макет из прошлого урока тоже был компонентом.
Компонент со свойствами
Создайте карточку статьи:
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>Переменная post придёт снаружи как свойство компонента. Файл лежит во вложенной папке post, поэтому тег будет называться @post.card.
Использование компонента
{{-- resources/views/pages/posts/index.edge --}}
@layout({ title: 'Все статьи' })
@each(post in posts)
@!post.card({ post })
@end
@endВосклицательный знак в @!post.card означает тег без содержимого: закрывающий @end не нужен. На странице каждая статья выведется отдельной карточкой.
Слот по умолчанию
Если внутрь компонента нужно передать разметку, используйте слот. Сделаем блок-уведомление:
{{-- resources/views/components/alert.edge --}}
<div class="alert alert-{{ type ?? 'info' }}">
{{{ await $slots.main() }}}
</div>{{-- resources/views/pages/posts/show.edge --}}
@alert({ type: 'warning' })
Статья ещё не опубликована. <a href="/posts">К списку</a>
@endСодержимое между тегами попадает в $slots.main(), а свойство type выбирает CSS-класс. Без свойства блок получит класс alert-info.
Именованные слоты
Компоненту иногда нужно несколько мест для разметки. Их называют через тег @slot:
{{-- 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')
Комментарии
@end
<p>Комментариев пока нет.</p>
@endТекст «Комментарии» окажется в шапке панели, а абзац — в основной части. Если слот могут не передать, проверьте его наличием: @if($slots.header).
Другая запись
В документации и старых проектах встречается форма с тегом @component. Она делает то же самое:
{{-- resources/views/pages/posts/index.edge --}}
@!component('components/post/card', { post })Частая ошибка
Компонент ищется только в папке resources/views/components/. Если положить card.edge в resources/views/partials/, тег @card вызовет ошибку о неизвестном теге. Для кусков без параметров используйте @include, а компоненты держите в components.