Includes with props in Stati 2

A card component, included by its path. The guard Stati 1 components needed on their first line can go.

SNP 149 #2B7 Filed stati eta

eta
<% /* site/partials/card.eta */ %>
<article class="card">
  <h2><a href="<%= stati.props.url %>"><%= stati.props.title %></a></h2>
  <% if (stati.props.description) { %>
    <p><%= stati.props.description %></p>
  <% } %>
</article>
eta
<%~ stati.include('partials/card', { title: 'Hello, Stati', url: '/blog/hello' }) %>

A template renders where it's included and nowhere else, with the props of that call, so there's no render without props for a guard to catch. When an include passes none, stati.props is undefined, and a template meant for both cases reads stati.props?.title. A nested include gets the props you hand it and nothing from its parent.

  • The name is the path from site/ without .eta: site/partials/ui/card.eta is partials/ui/card. Any folder will do. A _ in front of one only keeps Stati from making pages of the Markdown in it.
  • The lookup starts in the page's folder and walks up, so site/blog/partials/card.eta is the card on blog pages, even when the include sits in a root layout. /partials/card is always the root one, and ./icon sits next to the template making the call.
  • stati.include.has('partials/sidebar') says whether an optional template exists for the page. Include one that doesn't and the dev server stops with a list of similar paths, while a production build logs it and prints nothing.

The third argument is HTML for the template to wrap, and it arrives as stati.body:

eta
<% /* site/partials/panel.eta */ %>
<aside class="<%= stati.propValue('panel', `panel-${stati.props.tone}`) %>"><%~ stati.body %></aside>
eta
<%~ stati.include('partials/panel', { tone: 'note' }, stati.include('partials/card', { title: 'Inside a panel', url: '/blog/hello' })) %>

In the Stati docs: Template names, Passing props and Passing content.