Skip to content

Person Template

The person template renders individual person/staff pages. It displays biographical information, images, and can link to events where the person has participated.

└── theme
└── templates
└── person.liquid

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

PropertyTypeDescription
idstringUnique identifier
namestringFull display name
firstNamestringFirst name
lastNamestringLast name
slugstringURL-safe identifier
imagemediaProfile image
PropertyTypeDescription
pronounsstringPreferred pronouns
rolestringJob title or role
biographystringPlain text biography
biography_htmlstringRich text biography (HTML)
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="person">
<header class="person-header">
{% if person.image %}
<img
src="{{ person.image | image_url: width: 400, height: 400 }}"
alt="{{ person.name }}"
class="person-header__image"
>
{% endif %}
<div class="person-header__content">
<h1>{{ person.name }}</h1>
{% if person.role %}
<p class="person-role">{{ person.role }}</p>
{% endif %}
{% if person.pronouns %}
<p class="person-pronouns">({{ person.pronouns }})</p>
{% endif %}
</div>
</header>
{% if person.biography_html %}
<div class="person-bio">
{{ person.biography_html }}
</div>
{% endif %}
<div class="person-content">
{% stageblocks person %}
</div>
</article>
{% endcapture %}

Display names in various formats:

{# Full name (pre-computed) #}
<h1>{{ person.name }}</h1>
{# Last name, First name format #}
<span>{{ person.lastName }}, {{ person.firstName }}</span>
{# First name only #}
<span>{{ person.firstName }}</span>
{# With pronouns inline #}
<h1>
{{ person.name }}
{% if person.pronouns %}
<small>({{ person.pronouns }})</small>
{% endif %}
</h1>
{# Basic profile image #}
{% if person.image %}
<img
src="{{ person.image | image_url: width: 300, height: 300 }}"
alt="{{ person.name }}"
class="profile-image"
>
{% else %}
{# Fallback placeholder #}
<div class="profile-placeholder">
<span>{{ person.firstName | slice: 0 }}{{ person.lastName | slice: 0 }}</span>
</div>
{% endif %}
{# Responsive profile image #}
{% if person.image %}
<picture class="profile-picture">
<source
media="(min-width: 768px)"
srcset="{{ person.image | image_url: width: 400, height: 400 }}"
>
<img
src="{{ person.image | image_url: width: 200, height: 200 }}"
alt="{{ person.name }}"
>
</picture>
{% endif %}

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

{# Template schema defines: social_links, contact_email, department #}
{% if person.theme.department %}
<p class="department">{{ person.theme.department }}</p>
{% endif %}
{% if person.theme.contact_email %}
<a href="mailto:{{ person.theme.contact_email }}" class="contact-link">
Contact {{ person.firstName }}
</a>
{% endif %}
{% if person.theme.social_links %}
<div class="social-links">
{% if person.theme.social_links.twitter %}
<a href="{{ person.theme.social_links.twitter }}">Twitter</a>
{% endif %}
{% if person.theme.social_links.linkedin %}
<a href="{{ person.theme.social_links.linkedin }}">LinkedIn</a>
{% endif %}
</div>
{% endif %}
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<article class="person-page">
<header class="person-hero">
<div class="person-hero__image-wrapper">
{% if person.image %}
<img
src="{{ person.image | image_url: width: 500, height: 500 }}"
alt="{{ person.name }}"
class="person-hero__image"
>
{% else %}
<div class="person-hero__placeholder">
{% render 'snippets/icon' name: 'user' %}
</div>
{% endif %}
</div>
<div class="person-hero__content">
<h1 class="person-hero__name">
{{ person.name }}
{% if person.pronouns %}
<span class="person-hero__pronouns">({{ person.pronouns }})</span>
{% endif %}
</h1>
{% if person.role %}
<p class="person-hero__role">{{ person.role }}</p>
{% endif %}
{% if person.theme.department %}
<p class="person-hero__department">{{ person.theme.department }}</p>
{% endif %}
{# Contact and social links #}
<div class="person-hero__links">
{% if person.theme.contact_email %}
<a href="mailto:{{ person.theme.contact_email }}" class="btn btn--secondary">
{% render 'snippets/icon' name: 'email' %}
Contact
</a>
{% endif %}
{% if person.theme.social_links.linkedin %}
<a href="{{ person.theme.social_links.linkedin }}"
target="_blank"
rel="noopener"
class="social-link">
{% render 'snippets/icon' name: 'linkedin' %}
</a>
{% endif %}
{% if person.theme.social_links.twitter %}
<a href="{{ person.theme.social_links.twitter }}"
target="_blank"
rel="noopener"
class="social-link">
{% render 'snippets/icon' name: 'twitter' %}
</a>
{% endif %}
</div>
</div>
</header>
{# Biography section #}
{% if person.biography_html %}
<section class="person-bio">
<h2 class="visually-hidden">Biography</h2>
<div class="person-bio__content">
{{ person.biography_html }}
</div>
</section>
{% endif %}
{# Additional content blocks #}
<div class="person-content">
{% stageblocks person %}
</div>
{# Back to people listing #}
<nav class="person-nav">
<a href="/people" class="back-link">
&larr; Back to All People
</a>
</nav>
</article>
{% endcapture %}
{% schema %}
{
"name": "person",
"settings": [
{
"type": "text",
"name": "department",
"label": "Department"
},
{
"type": "email",
"name": "contact_email",
"label": "Contact Email"
},
{
"type": "group",
"name": "social_links",
"label": "Social Links",
"fields": [
{ "type": "text", "name": "twitter", "label": "Twitter URL" },
{ "type": "text", "name": "linkedin", "label": "LinkedIn URL" },
{ "type": "text", "name": "instagram", "label": "Instagram URL" }
]
}
],
"blocks": [
"content",
"image-gallery",
"video-gallery",
"well"
]
}
{% endschema %}

Create a reusable person card component:

{# components/person-card.liquid #}
{#
Required: person (person object)
Optional: show_role (boolean), image_size (string)
#}
{% assign show_role = show_role | default: true %}
{% assign image_size = image_size | default: 'medium' %}
{% case image_size %}
{% when 'small' %}{% assign img_width = 100 %}
{% when 'large' %}{% assign img_width = 300 %}
{% else %}{% assign img_width = 200 %}
{% endcase %}
<a href="/people/{{ person.slug }}" class="person-card person-card--{{ image_size }}">
{% if person.image %}
<img
src="{{ person.image | image_url: width: img_width, height: img_width }}"
alt="{{ person.name }}"
class="person-card__image"
loading="lazy"
>
{% endif %}
<div class="person-card__content">
<h3 class="person-card__name">{{ person.name }}</h3>
{% if show_role and person.role %}
<p class="person-card__role">{{ person.role }}</p>
{% endif %}
</div>
</a>

Usage:

{# In a template or block #}
<div class="people-grid">
{% for person in all_people limit: 6 %}
{% render 'components/person-card' person: person, show_role: true %}
{% endfor %}
</div>

Create variations for different person types:

templates/
├── person.liquid # Default person template
├── person.artist.liquid # Artist profile with portfolio
├── person.staff.liquid # Staff member with contact info
└── person.board.liquid # Board member profile

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