Basker Docs

Smart collection template

Reference for the smart-collection object — dynamic listings

The collection template renders Smart Collection pages. Smart Collections are dynamic, filtered groupings of content based on automated queries or manual selections. A collection targets one content type — events, posts, pages, people, organizations, venues, works, seasons, series, or blogs — and the resolved records of that type are passed to the template.

Location

└── theme
    └── templates
        └── collection.liquid

URL Structure

Smart Collections are accessible at:

  • /collections/:slug
  • /smart-collections/:slug (alias)

The collection Object

The collection template has access to the collection object with these properties:

Core Properties

PropertyTypeDescription
idstringUnique identifier
titlestringCollection title
descriptionstringCollection description
slugstringURL-safe identifier
imagemediaCollection image

Collection Configuration

PropertyTypeDescription
typestringquery (automated) or manual (hand-picked)
targetCollectionstringTarget content type — events, posts, pages, people, organizations, venues, works, seasons, series, or blogs
conditionTypestringall (match all) or any (match any)
limitnumberMaximum items to display (automated collections)
sortstringSort order

Items

PropertyTypeDescription
itemsarrayResolved records of the target content type

Content

PropertyTypeDescription
blocksarrayContent blocks from the Content tab
entriesarrayHand-picked records (manual collections)

Metadata

PropertyTypeDescription
createdAtstringCreation timestamp
updatedAtstringLast update timestamp

The resolved records are always available as items and as collection.items. They're also available under a variable named after the target content type — posts, people, organizations, and so on. When the target is events, that variable is events.

Basic Template Example

{% layout 'layouts/default.liquid' %}

{% capture content_for_layout %}
<div class="collection">
  <header class="collection-header">
    {% if collection.image %}
      <img
        src="{{ collection.image | image_url: width: 1200, height: 400 }}"
        alt="{{ collection.title }}"
        class="collection-header__image"
      >
    {% endif %}

    <div class="collection-header__content">
      <h1>{{ collection.title }}</h1>

      {% if collection.description %}
        <p class="lead">{{ collection.description }}</p>
      {% endif %}
    </div>
  </header>

  <div class="collection-items">
    {% if items.size > 0 %}
      <div class="event-grid">
        {% for event in items %}
          {% render 'components/event-item' event: event %}
        {% endfor %}
      </div>
    {% else %}
      <p class="no-results">No items found in this collection.</p>
    {% endif %}
  </div>

  {% stageblocks collection %}
</div>
{% endcapture %}

Working with Collection Items

Direct Items Access

The resolved items are available as both collection.items and the shorthand items:

{# Both work the same #}
{% for event in items %}
  {{ event.title }}
{% endfor %}

{% for event in collection.items %}
  {{ event.title }}
{% endfor %}

Target-typed access

The resolved records are also available under a variable named after the target content type. For an events collection that variable is events; for posts it's posts, and so on. Use whichever name reads best for the collection your template renders:

{% for event in events %}
  <article class="event-card">
    <h3><a href="/events/{{ event.slug }}">{{ event.title }}</a></h3>
    {% if event.startDate %}
      <time>{{ event.startDate | date: '%B %d, %Y' }}</time>
    {% endif %}
  </article>
{% endfor %}

When a template can render more than one target type, iterate over items instead, since it's present whatever the target is.

Item Count

<p class="results-count">
  {{ items.size }} {% if items.size == 1 %}event{% else %}events{% endif %} found
</p>

Working with Collection Types

Display Collection Type

{% case collection.type %}
  {% when 'query' %}
    <span class="badge">Dynamic Collection</span>
  {% when 'manual' %}
    <span class="badge">Curated Collection</span>
{% endcase %}

Type-Based Messaging

{% if items.size == 0 %}
  {% if collection.type == 'query' %}
    <p>No events match the current criteria. Check back as new events are added.</p>
  {% else %}
    <p>This collection is being curated. Check back soon for events.</p>
  {% endif %}
{% endif %}

Complete Template Example

{% layout 'layouts/default.liquid' %}

{% capture content_for_layout %}
<div class="collection-page">
  {# Hero section #}
  <header class="collection-hero">
    {% if collection.image %}
      <picture class="collection-hero__image">
        <source
          media="(min-width: 768px)"
          srcset="{{ collection.image | image_url: width: 1920, height: 500 }}"
        >
        <img
          src="{{ collection.image | image_url: width: 800, height: 400 }}"
          alt="{{ collection.title }}"
        >
      </picture>
    {% endif %}

    <div class="collection-hero__content">
      <h1>{{ collection.title }}</h1>

      {% if collection.description %}
        <p class="lead">{{ collection.description }}</p>
      {% endif %}

      <p class="collection-meta">
        {{ items.size }} {% if items.size == 1 %}event{% else %}events{% endif %}
      </p>
    </div>
  </header>

  {# Content blocks (before items) #}
  {% stageblocks collection %}

  {# Events listing #}
  <section class="collection-items">
    {% if items.size > 0 %}
      <div class="event-grid">
        {% for event in events %}
          <a href="/events/{{ event.slug }}" class="event-card">
            {% if event.image %}
              <img
                src="{{ event.image | image_url: width: 400, height: 250 }}"
                alt="{{ event.title }}"
                class="event-card__image"
                loading="lazy"
              >
            {% endif %}

            <div class="event-card__content">
              <h3 class="event-card__title">{{ event.title }}</h3>

              {% if event.startDate %}
                <time class="event-card__date" datetime="{{ event.startDate }}">
                  {{ event.startDate | date: '%B %d, %Y' }}
                </time>
              {% endif %}

              {% if event.venue %}
                <p class="event-card__venue">{{ event.venue.name }}</p>
              {% endif %}

              {% if event.series %}
                <span class="event-card__series">{{ event.series.title }}</span>
              {% endif %}
            </div>
          </a>
        {% endfor %}
      </div>
    {% else %}
      <div class="collection-empty">
        <h2>No Events Available</h2>
        {% if collection.type == 'query' %}
          <p>No events currently match this collection's criteria. New events will appear here automatically.</p>
        {% else %}
          <p>This curated collection is being updated. Check back soon!</p>
        {% endif %}

        <a href="/events" class="btn btn--secondary">View All Events</a>
      </div>
    {% endif %}
  </section>

  {# Navigation #}
  <nav class="collection-nav">
    <a href="/events" class="back-link">
      &larr; All Events
    </a>
  </nav>
</div>
{% endcapture %}

{% schema %}
{
  "name": "collection",
  "settings": [
    {
      "type": "select",
      "name": "layout_style",
      "label": "Layout Style",
      "options": [
        { "value": "grid", "label": "Grid" },
        { "value": "list", "label": "List" },
        { "value": "calendar", "label": "Calendar" }
      ],
      "defaultValue": "grid"
    },
    {
      "type": "checkbox",
      "name": "show_filters",
      "label": "Show Filter Options",
      "defaultValue": false
    }
  ],
  "blocks": [
    "content",
    "well"
  ]
}
{% endschema %}

Smart Collection Use Cases

Smart Collections create dynamic, curated views of any supported content type:

Collection NameTargetTypePurpose
"Upcoming Concerts"EventsQueryAuto-filters future events
"This Weekend"EventsQueryEvents in the next 7 days
"Recent News"PostsQueryPosts published in the last 30 days
"Our Sponsors"OrganizationsQueryOrganizations of type sponsor
"Editor's Picks"EventsManualHand-selected featured events

Query-Based Collections

Automated collections that update dynamically based on the conditions set for the target content type — for example date ranges, season or series membership, venue, organization type, category, tag, or any custom attribute. See Conditions and rules for what each content type can filter on.

Manual Collections

Hand-curated collections where editors select specific records. Useful for:

  • Featured records
  • Staff picks
  • Themed collections
  • Special promotions

Linking to Collections

{# In navigation or page content #}
<a href="/collections/upcoming-concerts">Upcoming Concerts</a>
<a href="/collections/family-events">Family Events</a>

{# Or with smart-collections path #}
<a href="/smart-collections/editors-picks">Editor's Picks</a>

Alternate Collection Templates

Create variations for different collection presentations:

templates/
├── collection.liquid           # Default collection template
├── collection.calendar.liquid  # Calendar view
├── collection.featured.liquid  # Featured/hero layout
└── collection.minimal.liquid   # Simple list view

Editors select templates per collection in the CMS.

On this page