Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Компоненты 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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.