Skip to content

Series Template

The series template renders series pages that group related events together. A series typically represents a concert series, festival, or recurring event program that spans multiple dates.

└── theme
└── templates
└── series.liquid

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

PropertyTypeDescription
idstringUnique identifier
titlestringSeries name
descriptionstringSeries description
slugstringURL-safe identifier
imagemediaMain series image
PropertyTypeDescription
startDatestringSeries start date (ISO 8601)
endDatestringSeries end date (ISO 8601)
PropertyTypeDescription
eventsarrayEvents in this series
PropertyTypeDescription
blocksarrayContent blocks
customAttributesobjectCustom attribute values
themeobjectTheme-specific field values
PropertyTypeDescription
meta.titlestringSEO title
meta.descriptionstringSEO description
meta.imagemediaSEO/OG image
createdAtstringCreation timestamp
updatedAtstringLast update timestamp
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<article class="series">
<header class="series-header">
{% if series.image %}
<img
src="{{ series.image | image_url: width: 1200, height: 600 }}"
alt="{{ series.image.alt | default: series.title }}"
class="series-header__image"
>
{% endif %}
<div class="series-header__content">
<h1>{{ series.title }}</h1>
{% if series.description %}
<p class="lead">{{ series.description }}</p>
{% endif %}
{% if series.startDate %}
<p class="series-dates">
{{ series.startDate | date: '%B %d' }}{{ series.endDate | date: '%B %d, %Y' }}
</p>
{% endif %}
</div>
</header>
<div class="series-body">
{% stageblocks series %}
</div>
</article>
{% endcapture %}
{# Same year format #}
{% assign start_year = series.startDate | date: '%Y' %}
{% assign end_year = series.endDate | date: '%Y' %}
<p class="series-dates">
{% if start_year == end_year %}
{{ series.startDate | date: '%B %d' }}{{ series.endDate | date: '%B %d, %Y' }}
{% else %}
{{ series.startDate | date: '%B %d, %Y' }}{{ series.endDate | date: '%B %d, %Y' }}
{% endif %}
</p>
<div class="date-badge">
<span class="date-badge__month">{{ series.startDate | date: '%b' }}</span>
<span class="date-badge__day">{{ series.startDate | date: '%d' }}</span>
<span class="date-badge__year">{{ series.startDate | date: '%Y' }}</span>
</div>
{% if series.events.size > 0 %}
<section class="series-events">
<h2>Events in This Series</h2>
<div class="event-list">
{% for event in series.events %}
<article class="event-item">
{% if event.image %}
<img
src="{{ event.image | image_url: width: 400, height: 250 }}"
alt="{{ event.title }}"
loading="lazy"
>
{% endif %}
<div class="event-item__content">
<h3>
<a href="/events/{{ event.slug }}">{{ event.title }}</a>
</h3>
{% if event.startDate %}
<time datetime="{{ event.startDate }}">
{{ event.startDate | date: '%B %d, %Y' }}
</time>
{% endif %}
{% if event.venue %}
<p class="venue">{{ event.venue.name }}</p>
{% endif %}
</div>
</article>
{% endfor %}
</div>
</section>
{% endif %}
{% if series.events.size > 0 %}
<section class="series-events">
<h2>{{ series.events.size }} Events</h2>
<div class="event-grid">
{% for event in series.events %}
{% render 'components/event-item' event: event %}
{% endfor %}
</div>
</section>
{% endif %}
{% if series.events.size > 0 %}
<section class="series-events">
<h2>Schedule</h2>
{% assign current_month = '' %}
{% for event in series.events %}
{% assign event_month = event.startDate | date: '%B %Y' %}
{% if event_month != current_month %}
{% unless current_month == '' %}</ul>{% endunless %}
<h3>{{ event_month }}</h3>
<ul class="event-list">
{% assign current_month = event_month %}
{% endif %}
<li>
<time datetime="{{ event.startDate }}">
{{ event.startDate | date: '%A, %B %d' }}
</time>
<a href="/events/{{ event.slug }}">{{ event.title }}</a>
</li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
</section>
{% endif %}

Access custom fields defined in the template schema via series.theme:

{# Template schema defines: subscription_link, brochure, sponsor_logos #}
{% if series.theme.subscription_link %}
<a href="{{ series.theme.subscription_link }}" class="btn btn--primary">
Subscribe to Series
</a>
{% endif %}
{% if series.theme.brochure %}
<a href="{{ series.theme.brochure | file_url }}" class="btn btn--secondary" download>
Download Brochure (PDF)
</a>
{% endif %}
{% if series.theme.sponsor_logos.size > 0 %}
<div class="sponsors">
<h3>Series Sponsors</h3>
{% for logo in series.theme.sponsor_logos %}
<img src="{{ logo | image_url: width: 200 }}" alt="{{ logo.alt }}">
{% endfor %}
</div>
{% endif %}
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<article class="series-page">
{# Hero section #}
<header class="series-hero">
{% if series.image %}
<picture class="series-hero__image">
<source
media="(min-width: 768px)"
srcset="{{ series.image | image_url: width: 1920, height: 600 }}"
>
<img
src="{{ series.image | image_url: width: 800, height: 400 }}"
alt="{{ series.image.alt | default: series.title }}"
>
</picture>
{% endif %}
<div class="series-hero__content">
<h1>{{ series.title }}</h1>
{% if series.startDate %}
<p class="series-hero__dates">
{{ series.startDate | date: '%B %d' }}{{ series.endDate | date: '%B %d, %Y' }}
</p>
{% endif %}
{% if series.description %}
<p class="lead">{{ series.description }}</p>
{% endif %}
<div class="series-hero__actions">
{% if series.theme.subscription_link %}
<a href="{{ series.theme.subscription_link }}" class="btn btn--primary">
Subscribe Now
</a>
{% endif %}
{% if series.theme.brochure %}
<a href="{{ series.theme.brochure | file_url }}" class="btn btn--secondary" download>
Download Brochure
</a>
{% endif %}
</div>
</div>
</header>
{# Content blocks #}
<div class="series-content">
{% stageblocks series %}
</div>
{# Events listing #}
{% if series.events.size > 0 %}
<section class="series-events">
<h2>Events in This Series</h2>
<p class="series-events__count">{{ series.events.size }} performances</p>
<div class="event-grid">
{% for event in series.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 %}
</div>
</a>
{% endfor %}
</div>
</section>
{% endif %}
{# Sponsors #}
{% if series.theme.sponsor_logos.size > 0 %}
<section class="series-sponsors">
<h2>Series Sponsors</h2>
<div class="sponsor-logos">
{% for logo in series.theme.sponsor_logos %}
<img
src="{{ logo | image_url: width: 200 }}"
alt="{{ logo.alt | default: 'Sponsor' }}"
loading="lazy"
>
{% endfor %}
</div>
</section>
{% endif %}
{# Navigation #}
<nav class="series-nav">
<a href="/series" class="back-link">
&larr; All Series
</a>
</nav>
</article>
{% endcapture %}
{% schema %}
{
"name": "series",
"settings": [
{
"type": "text",
"name": "subscription_link",
"label": "Subscription Link"
},
{
"type": "upload",
"name": "brochure",
"label": "Series Brochure (PDF)",
"relationTo": "media"
},
{
"type": "array",
"name": "sponsor_logos",
"label": "Sponsor Logos",
"fields": [
{
"type": "upload",
"name": "logo",
"label": "Logo",
"relationTo": "media"
}
]
},
{
"type": "group",
"name": "cta",
"label": "Call to Action",
"fields": [
{ "type": "text", "name": "title", "label": "Button Text" },
{ "type": "text", "name": "link", "label": "Button Link" }
]
}
],
"blocks": [
"accordion",
"content",
"feature-panel",
"image-gallery",
"people-panel",
"well"
]
}
{% endschema %}

Create variations for different series types:

templates/
├── series.liquid # Default series template
├── series.festival.liquid # Festival with multiple venues
├── series.concert.liquid # Concert series layout
└── series.education.liquid # Educational program series

Alternate templates appear in the CMS for editors to select per series.