Demonstrate Testimonial Slider.
View this pattern on the live demo site
Rotating quotes from the testimonials datastore.
{% comment %}
Displays the selected testimonials as a slider
Inputs:
section_class
section_id
Custom Fields:
show_testimonials
testimonials_slider_count
testimonials
Outputs:
section_rendered - true when this section outputs markup, false otherwise
{% endcomment -%}
{%- if entity.show_testimonials.on -%}
<section{% if section_class %} class="{{ section_class }}"{% endif %}{% if section_id %} id="{{ section_id }}"{% endif %}>
<div class="container">
{%- var testimonial_on_dark_bg = false %}{% if section_class contains 'text-bg-dark' or section_class contains 'text-bg-secondary' %}{% set testimonial_on_dark_bg = true %}{% endif -%}
{%- var headinglevel = headinglevel %}{% comment %}Copy to current scope{% endcomment -%}
{%- include '/common/_title_with_subtitle.liquid' title:'What Our Customers Say' subtitle:'Neighbors, chefs, and ranch families who trust the Vaughn counter' title_classname:'text-center text-white' subtitle_classname:'text-center text-white opacity-75 mb-4' postincrement_headinglevel:true -%}
{%- include "/partials/_testimonial_slider.liquid" testimonials:entity.testimonials testimonials_slider_count:entity.testimonials_slider_count testimonial_on_dark_bg:testimonial_on_dark_bg -%}
</div>
</section>
{%- set section_rendered = true -%}
{%- else -%}
{%- set section_rendered = false -%}
{%- endif -%}Custom fields owned by the testimonial slider.
[
{
"Type": "toggle",
"FieldID": "show_testimonials",
"Label": "Show Testimonials",
"OnLabel": "Show",
"OnValue": "On",
"OnColor": "green",
"OffLabel": "Hide",
"OffValue": "Off",
"OffColor": "red",
"DefaultValue": true
},
{
"Type": "group",
"Label": "Testimonials Slider",
"Collapsible": true,
"Collapsed": true,
"Condition": {
"Type": "exists",
"FieldID": "show_testimonials"
},
"Fields": [
{
"Type": "text",
"FieldID": "testimonials_slider_count",
"Label": "Number of Testimonials to Show",
"Validators": [
{
"Type": "number"
},
{
"Type": "max",
"Value": 10
},
{
"Type": "min",
"Value": 1
}
],
"Subtext": "The number of testimonials to include in the slider dynamically. Leave blank to only include the testimonials that you select below."
},
{
"Type": "datastoreitemlist",
"FieldID": "testimonials",
"Label": "Testimonials",
"DatastoreGUID": "Testimonials",
"Subtext": "Select one or more testimonials to always include them before any dynamically-pulled testimonials."
}
]
}
]
Swiper (or a single quote) that loads testimonials from the datastore.
{% comment %}
Renders one or more testimonials as a slider
If only one testimonial is passed in, it will be rendered without the slider
Inputs:
testimonials_slider_count - set this to a positive integer to dynamically pull random testimonials from the datastore
testimonials - list of testimonial datastore items
testimonial_on_dark_bg - when true, adjusts subtitle contrast for dark section backgrounds
{% endcomment -%}
{%- var testimonials_to_show = testimonials -%}
{%- if testimonials_slider_count is_int -%}
{%- unless testimonials_to_show is_list and testimonials_to_show.size >= testimonials_slider_count -%}
{% datastore_items testimonials_to_show = datastore:'Testimonials' prepend:testimonials_to_show exclude_prepended:true max:testimonials_slider_count sort_by:'random' cache_random:true -%}
{%- endunless -%}
{%- endif -%}
{%- if testimonials_to_show.is_valid -%}
{%- if testimonials_to_show.size > 1 -%}
{%- id testimonial_slider_id = prefix:'ts_' -%}
<div class="position-relative px-lg-5">
<div class="swiper testimonial-slider" id="{{testimonial_slider_id}}">
<div class="swiper-wrapper">
{%- for testimonial in testimonials_to_show -%}
{%- include "/partials/_testimonial_card.liquid" testimonial: testimonial testimonial_classname:'swiper-slide d-flex flex-column h-auto' testimonial_on_dark_bg:testimonial_on_dark_bg -%}
{%- endfor -%}
</div>
<div class="swiper-pagination mt-3"></div>
</div>
<button type="button" class="btn btn-light btn-sm rounded-circle position-absolute top-50 start-0 translate-middle-y d-none d-lg-inline-flex align-items-center justify-content-center testimonial-slider-prev" style="width: 2.75rem; height: 2.75rem;" aria-label="Previous testimonial">
<i class="bi bi-chevron-left" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-light btn-sm rounded-circle position-absolute top-50 end-0 translate-middle-y d-none d-lg-inline-flex align-items-center justify-content-center testimonial-slider-next" style="width: 2.75rem; height: 2.75rem;" aria-label="Next testimonial">
<i class="bi bi-chevron-right" aria-hidden="true"></i>
</button>
</div>
{%- add_stylesheet "https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" -%}
{%- add_javascript "https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js" defer:true position:'body' -%}
{%- add_javascript inline testimonialSliderInit = position:'body' -%}
document.addEventListener('DOMContentLoaded', function() {
var sliderEl = document.getElementById('{{testimonial_slider_id}}');
if (!sliderEl || typeof Swiper === 'undefined') {
return;
}
var swiper = new Swiper(sliderEl, {
slidesPerView: 1,
spaceBetween: 24,
loop: true,
a11y: {
prevSlideMessage: 'Previous testimonial',
nextSlideMessage: 'Next testimonial'
},
pagination: {
el: sliderEl.querySelector('.swiper-pagination'),
clickable: true
},
navigation: {
nextEl: sliderEl.parentElement.querySelector('.testimonial-slider-next'),
prevEl: sliderEl.parentElement.querySelector('.testimonial-slider-prev')
}
});
});
{%- end_javascript -%}
{%- else -%}
{%- var testimonial = testimonials_to_show | first -%}
{%- include "/partials/_testimonial_card.liquid" testimonial_on_dark_bg:testimonial_on_dark_bg -%}
{%- endif -%}
{%- endif -%}
One testimonial quote used as a slider slide.
{% comment %}
Renders a single testimonial card.
Inputs:
testimonial (entity or object with quote, author, etc.)
testimonial_classname - an optional classname to use for the div that the testimonial is inside
hidePicture
hideRate
hideQuotes
img_preset_testimonial_thumb - The image preset to use for the testimonial author thumbnail
testimonial_on_dark_bg - when true, uses light subtitle text for dark section backgrounds
{% endcomment -%}
{%- var meta_classname = 'fs-6 mb-3 text-center text-muted fst-italic' -%}
{%- if testimonial_on_dark_bg %}{% set meta_classname = 'fs-6 mb-3 text-center text-white opacity-75 fst-italic' %}{% endif -%}
<div{% if testimonial_classname is_valid %} class="{{testimonial_classname | escape}}"{% endif %}>
{%- unless hidePicture -%}
{%- if testimonial.picture.is_valid -%}
<div class="d-flex justify-content-center">
{% img testimonial.picture preset:img_preset_testimonial_thumb link:false class:"rounded-circle img-fluid mb-3" style:"width: 96px; height: 96px; object-fit: cover;" -%}
</div>
{%- endif -%}
{%- endunless -%}
<div>
<p class="h4 text-center{% if testimonial_on_dark_bg %} text-white{% endif %}">{{testimonial.title}}</p>
{%- if testimonial.designation.is_valid or testimonial.organization.is_valid -%}
<p class="{{meta_classname}}">
{{testimonial.designation}}
{%- if testimonial.designation.is_valid and testimonial.organization.is_valid %} - {% endif -%}
{{testimonial.organization}}
</p>
{%- endif -%}
{%- unless hideRate -%}
<p class="text-center">
<span>
{%- for number in (1..5) -%}
<i class="bi fs-4 bi-star{% if testimonial.rate.value >= forloop.index %}-fill" style="color: #ffb03b;{% endif %}"></i>
{%- endfor -%}
</span>
</p>
{%- endunless -%}
{%- unless hideQuotes -%}
<p class="text-center mx-auto mb-4{% if testimonial_on_dark_bg %} text-white{% endif %}" style="max-width: 38rem;">
<i class="bi bi-quote pe-2 fs-2 align-bottom{% if testimonial_on_dark_bg %} text-white opacity-75{% endif %}"></i>
{{testimonial.testimonial_comment.value | escape}}
<i class="bi bi-quote ps-2 fs-2 icon-flipped align-top{% if testimonial_on_dark_bg %} text-white opacity-75{% endif %}"></i>
</p>
{%- endunless -%}
</div>
</div>