Demonstrate Author Page.
View this pattern on the live demo site
Author archive page: includes the banner and the author-main section.
{% comment %}
Displays an author page, including the author name, image, bio, and recent blog posts by the author
{% endcomment -%}
{%- include "/_header.liquid" -%}
{%- include "/sections/_generic_banner.liquid" -%}
{%- include "/sections/_breadcrumbs.liquid" -%}
{%- include "/sections/_author_main.liquid" author:entity section_class:'bg-body' -%}
{%- include "/sections/_cta_snippet.liquid" section_class:'py-4 py-lg-5' -%}
{%- include "/_footer.liquid" -%}
Lists this author’s posts; fields stay on this section.
{% comment %}
Displays author information and blog posts for an author.
Inputs:
author - the author to display and filter posts by. Defaults to entity when entity is an author.
page_param - query parameter for pagination. Defaults to 'page'
limit - number of blog posts to show. Defaults to 12
exclude_current_author - true to exclude the author from blog post cards
Inputs passed through to _blog_feed.liquid:
section_class
section_id
Custom Fields:
linked_team_member - optional team member merged into the profile
blog_posts_title
blog_posts_subtitle
show_sidebar
show_sidebar_search
sidebar_related_content
sidebar_related_content_title
empty_posts_html
Outputs:
section_rendered - true when this section outputs markup, false otherwise
{% endcomment -%}
{%- var author = author | default: entity -%}
{%- if author.is_valid and author.object_type == 'author' -%}
{%- var page_param = page_param | default:'page' -%}
{%- var pageNum = request.query_params[page_param] | default:1 | to_int | at_least:1 -%}
{%- var limit = limit | default:12 | to_int | at_least:3 -%}
{%- blog_posts var posts = author:author page:pageNum sort_by:"post_date" sort_direction:"desc" limit:limit -%}
{%- var exclude_author = '' %}{% if exclude_current_author %}{% set exclude_author = author %}{% endif -%}
{%- var exclude_tag = '' -%}
{%- var headinglevel = headinglevel %}{% comment %}Copy to current scope{% endcomment -%}
{%- var has_posts = false %}{% if posts.is_valid and posts.size > 0 %}{% set has_posts = true %}{% endif -%}
{%- var show_author_in_sidebar = true -%}
{%- capture var blog_feed_header -%}
{%- var title = entity.blog_posts_title | default: 'From the Blog' -%}
{%- var subtitle = entity.blog_posts_subtitle -%}
{%- if pageNum > 1 -%}
<div class="container pt-4">
{%- include '/common/_title.liquid' title_classname:'text-center text-primary mt-3 mb-4' postincrement_headinglevel:true -%}
</div>
{%- else -%}
<div class="container pt-4 pt-lg-5">
{%- include '/partials/_person_profile.liquid' team_member:entity.linked_team_member prefer_author:true show_heading:false -%}
{%- if has_posts -%}
{%- include '/common/_title_with_subtitle.liquid' title_classname:'h3 text-primary mb-0 text-start' subtitle_classname:'text-muted mb-0 mt-2' postincrement_headinglevel:true -%}
{%- endif -%}
{%- set show_author_in_sidebar = false -%}
</div>
{%- endif -%}
<hr class="text-primary my-4">
{%- endcapture -%}
{%- if entity.show_sidebar.on -%}
{%- if show_author_in_sidebar -%}
{%- assign sidebar_context_title = 'About the Author' -%}
{%- capture assign sidebar_context_html -%}
{%- include '/partials/_person_profile.liquid' team_member:entity.linked_team_member prefer_author:true layout:'inline' show_link:false use_stretched_link:false -%}
{%- endcapture -%}
{%- endif -%}
{%- if has_posts -%}
{%- capture var sidebar_topics_title %}Topics by {{ author.title }}{% endcapture -%}
{%- unless sidebar_topics is_valid -%}
{%- var taglist = null -%}
{%- include '/common/_taglist_from_items.liquid' items:posts max_tags:12 taglist_autofill_with_random:false -%}
{%- assign sidebar_topics = taglist -%}
{%- endunless -%}
{%- var sidebar_recent_posts_title = 'Other Recent Posts' -%}
{%- assign sidebar_recent_posts_count = 5 -%}
{%- else -%}
{%- assign sidebar_topics = '' -%}
{%- assign sidebar_recent_posts_count = 5 -%}
{%- var sidebar_recent_posts_title = 'Recent From the Blog' -%}
{%- endif -%}
{%- endif -%}
{%- var empty_posts_html = entity.empty_posts_html -%}
{%- unless empty_posts_html is_valid -%}
{%- capture set empty_posts_html -%}
<p class="h4 text-primary mb-3">No articles yet</p>
<p class="text-muted mb-4 mx-auto" style="max-width: 28rem;">Check back soon for posts from {{ author.title }}.</p>
{%- endcapture -%}
{%- endunless -%}
{%- include '/partials/_blog_feed.liquid' only_show_header_on_first_page:false show_sidebar:entity.show_sidebar.on show_sidebar_search:entity.show_sidebar_search.on sidebar_related_content:entity.sidebar_related_content sidebar_related_content_title:entity.sidebar_related_content_title -%}
{%- set section_rendered = true -%}
{%- else -%}
{%- set section_rendered = false -%}
{%- endif -%}
Custom fields owned by the author listing section.
[
{
"Type": "datastoreitem",
"FieldID": "linked_team_member",
"Label": "Team Member",
"Subtext": "Select a team member to display on this page. Leave blank to display the author's profile.",
"DatastoreGUID": "Team Members"
},
{
"Type": "text",
"FieldID": "blog_posts_title",
"Label": "Blog Posts Title",
"Placeholder": "From the Blog"
},
{
"Type": "text",
"FieldID": "blog_posts_subtitle",
"Label": "Blog Posts Subtitle",
"Placeholder": "Latest articles by this author from the blog"
},
{
"Type": "toggle",
"FieldID": "show_sidebar",
"Label": "Show Sidebar",
"OnValue": "show",
"OffValue": "hide",
"OnColor": "green",
"OffColor": "red",
"OnLabel": "Show",
"OffLabel": "Hide",
"DefaultValue": true
},
{
"Type": "group",
"Label": "Sidebar Content",
"Condition": {
"Type": "exists",
"FieldID": "show_sidebar"
},
"Fields": [
{
"Type": "toggle",
"FieldID": "show_sidebar_search",
"Label": "Show Sidebar Search",
"DefaultValue": true,
"OnValue": "show",
"OffValue": "hide",
"OnColor": "green",
"OffColor": "red",
"OnLabel": "Show",
"OffLabel": "Hide"
},
{
"Type": "entitylist",
"FieldID": "sidebar_related_content",
"HasUrl": true
},
{
"Type": "text",
"FieldID": "sidebar_related_content_title",
"Label": "Sidebar Related Content Title",
"DefaultValue": "Related Content",
"IsRequired": true,
"Condition": {
"Type": "exists",
"FieldID": "sidebar_related_content"
}
}
]
},
{
"Type": "html",
"FieldID": "empty_posts_html",
"Label": "Empty Posts Message",
"Subtext": "Optional. Shown when this author has no published blog posts. Leave blank to use the built-in message."
}
]
Author (and optional linked team member) profile above the post list.
{% comment %}
Profile display for an author and/or team-member datastore item.
When both are passed in, fields are merged for consistent display across the site.
Inputs:
author - optional author to pull profile information from
team_member - optional team member datastore_item to pull profile information from
prefer_author - true to prefer author fields when both are valid (default false = prefer team_member)
layout - 'hero' (default, large photo + bio) or 'inline' (compact row, e.g. blog card footers / sidebar)
show_heading - when true (hero), output name+role as a heading block. When false, show role/tenure only (page banner already has the name). Default false for hero.
show_bio - show biography/summary. Default true for hero, false for inline.
show_email - show email link. Default true for hero, false for inline.
show_tenure - show tenure line when available. Default true for hero, false for inline.
show_card - wrap inline layout in a Bootstrap card
show_link - link the name to the person's page URL (author.full_url or team_member.full_url)
use_stretched_link - when true with show_link, wrap inline layout for stretched-link behavior
title_classname - classes for the name (inline layout). Defaults differ by layout.
title_link_classname - classes for the name link
subtitle_classname - classes for role/job title (inline)
img_preset_person_profile - image preset for hero photos
img_preset_person_thumb - image preset for inline circular thumbnails (falls back to img_preset_author_thumb)
{% endcomment -%}
{%- if author.is_valid or team_member.is_valid -%}
{%- var layout = layout | default: 'hero' -%}
{%- var prefer_author = prefer_author | default: false -%}
{%- var profile_title = team_member.title | default: author.title -%}
{%- var profile_image = team_member.image | default: author.image -%}
{%- var profile_role = team_member.role | default: author.job_title -%}
{%- var profile_tenure = team_member.tenure -%}
{%- var profile_bio = team_member.bio | default: author.bio -%}
{%- var profile_summary = team_member.summary -%}
{%- var profile_email = team_member.email | default: author.email -%}
{%- var profile_url = '' -%}
{%- if team_member.is_valid and team_member.has_url -%}
{%- set profile_url = team_member.full_url -%}
{%- elsif author.is_valid and author.has_url -%}
{%- set profile_url = author.full_url -%}
{%- endif -%}
{%- if prefer_author and author.is_valid -%}
{%- set profile_title = author.title -%}
{%- if author.image.is_valid %}{% set profile_image = author.image %}{% endif -%}
{%- if author.job_title.is_valid %}{% set profile_role = author.job_title %}{% endif -%}
{%- if author.bio.is_valid %}{% set profile_bio = author.bio %}{% endif -%}
{%- if author.email.is_valid %}{% set profile_email = author.email %}{% endif -%}
{%- if author.has_url %}{% set profile_url = author.full_url %}{% endif -%}
{%- endif -%}
{%- unless profile_bio.is_valid -%}
{%- if profile_summary.is_valid %}{% set profile_bio = profile_summary %}{% endif -%}
{%- endunless -%}
{%- if layout == 'inline' -%}
{%- var show_bio = show_bio | default: false %}{% unless profile_bio.is_valid %}{% set show_bio = false %}{% endunless -%}
{%- var show_email = show_email | default: false -%}
{%- var show_tenure = show_tenure | default: false -%}
{%- var show_link = show_link | default: true %}{% unless profile_url is_valid %}{% set show_link = false %}{% endunless -%}
{%- var use_stretched_link = use_stretched_link | default: true -%}
{%- var title_classname = title_classname | default: 'text-reset fw-bold' -%}
{%- unless title_link_classname.is_valid -%}
{%- if show_link and use_stretched_link -%}
{%- set title_link_classname = 'text-reset text-decoration-none stretched-link' -%}
{%- else -%}
{%- set title_link_classname = 'text-reset text-decoration-none' -%}
{%- endif -%}
{%- endunless -%}
{%- var subtitle_classname = subtitle_classname | default: 'text-muted small mb-0' -%}
{%- var thumb_preset = img_preset_person_thumb | default: img_preset_author_thumb -%}
{%- if show_card -%}
<div class="card"><div class="{% if show_bio %}card-header{% else %}card-body{% endif %}">
{%- elsif show_link and use_stretched_link -%}
<div class="position-relative">
{%- endif -%}
{%- if profile_image.is_valid -%}
<div class="d-flex">
{%- img profile_image class:'img-fluid rounded-circle' style:'width:48px;height:48px;object-fit:cover;' link:false preset:thumb_preset -%}
<div class="ms-3 d-flex flex-column justify-content-center">
{%- endif -%}
{%- var title_link = '' %}{% if show_link %}{% set title_link = profile_url %}{% endif -%}
{%- include '/common/_title_with_subtitle.liquid' title:profile_title subtitle:profile_role title_div:false title_classname:title_classname title_link:title_link title_link_classname:title_link_classname subtitle_classname:subtitle_classname -%}
{%- if profile_image.is_valid %}</div></div>{% endif -%}
{%- if show_tenure and profile_tenure.is_valid -%}
<p class="small text-muted mb-0 mt-2"><i class="bi bi-clock-history me-1" aria-hidden="true"></i>{{ profile_tenure }}</p>
{%- endif -%}
{%- if show_bio -%}
{%- if show_card %}</div><div class="card-body">{% else %}<div class="mt-3">{% endif -%}
{{ profile_bio }}
{%- endif -%}
{%- if show_email and profile_email.is_valid -%}
<p class="small mb-0 mt-2">
<a href="mailto:{{ profile_email.value | default: profile_email | escape }}" class="link-primary text-decoration-none"><i class="bi bi-envelope-fill me-1" aria-hidden="true"></i>{{ profile_email.value | default: profile_email }}</a>
</p>
{%- endif -%}
{%- if show_card -%}
</div></div>
{%- else -%}
{%- if show_bio %}</div>{% endif -%}
{%- if show_link and use_stretched_link %}</div>{% endif -%}
{%- endif -%}
{%- else -%}
{%- var show_heading = show_heading | default: false -%}
{%- var show_bio = show_bio | default: true -%}
{%- var show_email = show_email | default: true -%}
{%- var show_tenure = show_tenure | default: true -%}
<div class="person-profile rounded-4 border-0 shadow-sm overflow-hidden bg-white mb-4 mb-lg-5">
<div class="row g-0 align-items-stretch">
<div class="col-md-4 col-lg-3 bg-secondary-subtle">
{%- if profile_image.is_valid -%}
{%- img profile_image link:false preset:img_preset_person_profile class:"w-100 h-100" style:"min-height: 280px; object-fit: cover;" -%}
{%- else -%}
<div class="d-flex align-items-center justify-content-center h-100 py-5" style="min-height: 280px;" aria-hidden="true">
<i class="bi bi-person-fill text-secondary opacity-50" style="font-size: 4rem;"></i>
</div>
{%- endif -%}
</div>
<div class="col-md-8 col-lg-9">
<div class="p-4 p-lg-5 h-100 d-flex flex-column">
{%- if show_heading -%}
{%- include '/common/_title_with_subtitle.liquid' title:profile_title subtitle:profile_role title_classname:'h2 text-primary mb-1 text-start' subtitle_classname:'lead text-muted mb-0' title_div_classname:'mb-3 text-start' postincrement_headinglevel:true -%}
{%- else -%}
{%- if profile_role.is_valid -%}
<p class="text-uppercase small fw-semibold text-primary mb-2" style="letter-spacing: 0.06em;">{{ profile_role }}</p>
{%- endif -%}
{%- endif -%}
{%- if show_tenure and profile_tenure.is_valid -%}
<p class="small text-muted mb-3"><i class="bi bi-clock-history me-1" aria-hidden="true"></i>{{ profile_tenure }}</p>
{%- endif -%}
{%- if show_bio and profile_bio.is_valid -%}
<div class="person-bio flex-grow-1 mb-0 fs-6 lh-lg">{{ profile_bio }}</div>
{%- endif -%}
{%- if show_email and profile_email.is_valid -%}
<p class="small mb-0 mt-4">
<a href="mailto:{{ profile_email.value | default: profile_email | escape }}" class="link-primary text-decoration-none"><i class="bi bi-envelope-fill me-1" aria-hidden="true"></i>{{ profile_email.value | default: profile_email }}</a>
</p>
{%- endif -%}
</div>
</div>
</div>
</div>
{%- endif -%}
{%- endif -%}
This author’s posts as a feed with optional sidebar.
{% comment %}
Outputs a blog feed section with the given blog posts displayed as a list of cards.
Inputs:
section_class - an optional classname to apply to the section
section_id - an optional id to apply to the section
blog_feed_header - optional markup to include as the header above the blog feed
only_show_header_on_first_page - false to allow the header to be displayed past the first page of the collection
posts - the collection of blog posts to output
show_sidebar - true to show the blog sidebar next to the blog posts
empty_posts_html - optional markup when there are no posts to display
Inputs passed through to _blog_sidebar.liquid:
show_sidebar_search - when true, show the sidebar search widget
Inputs passed through to /common/_pagination.liquid:
page_param
Inputs passed through to _blogpost_card.liquid:
show_authors - true to show the blog post's authors in the card footer
show_tags - true to show the blog post's tags
card_classes (optional) - additional classes to include on <div class="card">
If show_sidebar is true, all relevant inputs are passed through to /partials/_blog_sidebar.liquid.
Additionally, sidebar_recent_posts_exclude is automatically updated to exclude all of the posts
{% endcomment -%}
<section{% if section_class %} class="{{ section_class }}"{% endif %}{% if section_id %} id="{{ section_id }}"{% endif %}>
{%- if blog_feed_header is_valid %}{% if posts.page == 1 or only_show_header_on_first_page == false %}{{blog_feed_header}}{% endif %}{% endif -%}
{%- var post_cols = 3 -%}
<div class="container py-4 py-lg-5">
{%- if show_sidebar -%}
<div class="row g-4 g-lg-5 align-items-start">
<div class="col-12 col-lg-8 order-2 order-lg-1">
{%- set post_cols = 2 -%}
{%- endif -%}
{%- if posts.is_valid and posts.size > 0 -%}
{%- comment %}
Use the following to display the blog feed as rows instead of cards:
{%- include "/partials/_blog_feed_rows.liquid" -%}
{% endcomment -%}
{%- include "/partials/_blog_feed_cards.liquid" -%}
{%- else -%}
<div class="text-center py-5 px-3 rounded-4 text-bg-light border">
{%- if empty_posts_html is_valid -%}
{{ empty_posts_html }}
{%- else -%}
<p class="h4 text-primary mb-3">No matching posts found</p>
{%- if show_sidebar -%}
<p class="text-muted mb-0">Try another search, or browse recent posts and topics in the sidebar.</p>
{%- endif -%}
{%- endif -%}
</div>
{%- endif -%}
{%- if show_sidebar -%}
</div>
<div class="col-12 col-lg-4 order-1 order-lg-2">
{%- var sidebar_recent_posts_exclude = sidebar_recent_posts_exclude | default: '' -%}
{%- if posts.is_valid %}{% set sidebar_recent_posts_exclude = sidebar_recent_posts_exclude | concat:posts %}{% endif -%}
{%- include '/partials/_blog_sidebar.liquid' -%}
</div>
</div>
{%- endif -%}
</div>
{%- if posts.is_valid and posts.size > 0 -%}
<div class="container mb-4">
{%- include '/common/_pagination.liquid' collection:posts pagination_justify:'center' -%}
</div>
{%- endif -%}
</section>