Shopify themes, liquid, logos, and UX
We're moving the community! Starting July 7, the current community will be read-only for approx. 2 weeks. You can browse content, but posting will be temporarily unavailable. Learn more
Hi All, i have a empty tile in my collection on desktop. Is there a way i can add a collection tile here amongst the product cards to fill the space? Thanks
Hi @DASCPA ,
I am from Mageplaza - Shopify solution expert.
You can either create a new product or customize the code to add a "Promo" in the empty spot.
Please let me know which theme you're using and how you'd prefer to implement this customization.
Best regards!
Mageplaza | Top-Rated Shopify Agency | Trusted by 230,000+ worldwide merchants
If our suggestion works for you, please give it a Like or mark it as a Solution!
Should you have any questions or concerns, feel free to contact us via consultant@mageplaza.com
I would like to use a promo (link to another collection) using the shopify Savor theme
Hi @DASCPA
Yes, absolutely. Please follow the steps below to apply the promo in a simple and effective way:
Step 1: Update the product-grid.liquid file in the snippets folder with the following code:
{%- doc -%}
This snippet is used to render the product grid on collection and search pages.
@param {object} section - The section object
@param {object} paginate - Pagination object
@param {object} products - Array of product objects
@param {string} [title] - Header of the collection or search results
@param {string} children - List or grid of product cards
{%- enddoc -%}
{% capture product_card_size %}
{% render 'util-product-grid-card-size' section: section %}
{% endcapture %}
{% assign product_card_size = product_card_size | strip %}
{% style %}
@media (min-width: 750px) {
{% case section.settings.layout_type %}
{% when 'grid' %}
.product-grid--{{ section.id }}:is(.product-grid--grid) {
--product-grid-columns-desktop: repeat(auto-fill, minmax({{ product_card_size }}, 1fr));
}
{% when 'organic' %}
{% assign large_span = 2 %}
{% assign row_cycle = 3 %}
{% assign product_cycle = row_cycle | times: 2 %}
{% assign right_large_start_col = 3 %}
.product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + 1) {
grid-column: 1 / span {{ large_span }};
}
.product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + 2),
.product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + 5) {
align-self: end;
}
.product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + {{ product_cycle }}) {
grid-column: {{ right_large_start_col }} / span {{ large_span }};
}
.product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) {
--product-grid-columns-desktop: repeat(4, 1fr);
}
{% endcase %}
/* This logic helps prevent displaying one column for an large or extra-large product card size on a small screen. We want it to display at least two columns. */
{% case section.settings.product_card_size %}
{% when 'extra-large' or 'large' %}
@container product-grid (width < calc({{ product_card_size }} * 3 + {{ section.settings.columns_gap_horizontal }}px * 2)) {
.product-grid--{{ section.id }}:is(.product-grid--grid) {
--product-grid-columns-desktop: repeat(2, 1fr);
}
}
{% endcase %}
/* When zoomed out, fit as many 100px-wide columns as possible */
.product-grid--{{ section.id }}:is([product-grid-view='zoom-out']) {
--product-grid-columns-desktop: repeat(auto-fill, minmax(6.25rem, 1fr));
}
.product-grid--{{ section.id }}:is([product-grid-view='zoom-out']) .product-grid-view-zoom-out--details {
display: block;
}
.product-grid--{{ section.id }}:is([product-grid-view='zoom-out']) .product-grid__card {
padding-inline-start: var(--zoom-out-padding-inline-start, 0);
padding-inline-end: var(--zoom-out-padding-inline-end, 0);
padding-block-start: var(--zoom-out-padding-block-start, 0);
padding-block-end: var(--zoom-out-padding-block-end, 0);
}
}
{% endstyle %}
<div
id="ResultsList"
class="
grid main-collection-grid
{%- if section.settings.inherit_color_scheme == false %} color-{{ section.settings.color_scheme }}{% endif %}
{%- if section.settings.product_grid_width == 'full-width' %} collection-wrapper--full-width{% endif %}
{%- if section.settings.full_width_on_mobile == true %} collection-wrapper--full-width-on-mobile{% endif %}
spacing-style
"
style="
--grid--margin--mobile: 0{% if section.settings.product_grid_width == 'centered' and section.settings.full_width_on_mobile == false %} var(--margin-lg){% else %} 0{% endif %};
--grid-column--desktop: var(--{% if section.settings.product_grid_width == 'centered' %}centered{% else %}full-width{% endif %});
--grid-column--mobile: var(--{% if section.settings.full_width_on_mobile %}full-width{% else %}{% if section.settings.product_grid_width == 'centered' %}centered{% else %}full-width{% endif %}{% endif %});
--padding-inline-start: {{ section.settings.padding-inline-start }}px;
--padding-inline-end: {{ section.settings.padding-inline-end }}px;
"
>
<div
style="
grid-column: var(--full-width);
--product-grid-gap-mobile: {{ section.settings.columns_gap_vertical | at_most: 12 }}px {{ section.settings.columns_gap_horizontal | at_most: 12 }}px;
--product-grid-gap-desktop: {{ section.settings.columns_gap_vertical }}px {{ section.settings.columns_gap_horizontal }}px;
container-type: inline-size;
container-name: product-grid;
"
>
{% if products.size == 0 %}
<div class="main-collection-grid__empty">
<h2 class="main-collection-grid__empty-title h2">
{{ 'content.no_products_found' | t }}
</h2>
<p>
{{ 'content.use_fewer_filters_html' | t: link: collection.url, class: 'main-collection-grid__empty-link' }}
</p>
</div>
{% else %}
<span ref="viewMorePrevious"></span>
{% if title %}
<h4 class="main-collection-grid__title">{{ title }}</h4>
{% endif %}
<ul
class="product-grid product-grid--{{ section.id }} product-grid--{{ section.settings.layout_type }} {% if section.settings.mobile_product_card_size == 'large' %} product-grid-mobile--large{% endif %}"
product-grid-view="default"
ref="grid"
last-page="{{ paginate.pages }}"
role="list"
data-product-card-size="{{ section.settings.product_card_size }}"
>
{{ children }}
{% comment %}promo block{% endcomment %}
{% if section.settings.show_promo_block %}
<li class="product-grid__item product-grid__item--promo">
<div class="product-grid__card product-grid__card--promo">
<div class="product-grid__card-content">
<h3 class="product-grid__card-title">{{ section.settings.promo_block_title }}</h3>
<p class="product-grid__card-description">{{ section.settings.promo_block_description }}</p>
<a href="{{ section.settings.promo_block_link }}" class="button button--primary">
{{ section.settings.promo_block_button_text }}
</a>
</div>
</div>
</li>
{% endif %}
</ul>
<span ref="viewMoreNext"></span>
{% endif %}
</div>
</div>
{% comment %}
This script is used to set the grid view on the product grid stored in sessionStorage. Keeping it here helps us prevent seeing the default state.
{% endcomment %}
{% unless request.design_mode %}
<script>
(() => {
const grid = document.querySelector('.product-grid');
if (grid) {
const currentDevice = window.innerWidth >= 750 ? 'desktop' : 'mobile';
const storedLayout = sessionStorage.getItem(`product-grid-view-${currentDevice}`);
if (storedLayout) {
const options = document.querySelectorAll(`input[type="radio"][name="grid"]`);
grid.setAttribute('product-grid-view', storedLayout);
for (const option of options) {
option.checked = option.value === storedLayout;
}
}
}
})();
</script>
{% endunless %}
{% stylesheet %}
.product-grid {
--product-grid-gap: var(--product-grid-gap-mobile);
isolation: isolate;
@media screen and (width >= 750px) {
--product-grid-gap: var(--product-grid-gap-desktop);
}
}
.product-grid slideshow-arrows .slideshow-control {
display: none;
@media screen and (width >= 750px) {
display: grid;
}
}
.main-collection-grid {
padding: var(--grid--margin--mobile);
@media screen and (width >= 750px) {
padding: var(--padding-block-start) var(--padding-inline-end) var(--padding-block-end) var(--padding-inline-start);
}
}
.main-collection-grid__empty {
padding-block: var(--padding-6xl);
padding-inline: var(--page-margin);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: var(--padding-sm);
}
.main-collection-grid__empty-title {
margin: 0;
}
.collection-wrapper--full-width .main-collection-grid__title {
margin-left: var(--page-margin);
}
.collection-wrapper--full-width-on-mobile .main-collection-grid__title {
@media screen and (width < 750px) {
margin-left: var(--page-margin);
}
}
{% endstylesheet %}
Step 2: Update the main-collection.liquid file in the sections folder with the following code:
{% liquid
# Onboarding: When no products are available, we show placeholder items
assign products = ''
if request.design_mode and shop.products_count == 0
for i in (1..16)
assign products = products | append: ' ,'
endfor
assign products = products | split: ','
endif
%}
<script
src="{{ 'results-list.js' | asset_url }}"
type="module"
></script>
{% javascript %}
const url = new URL(window.location.href);
if (url.hash) {
document.addEventListener(
'DOMContentLoaded',
() => {
const card = document.getElementById(url.hash.slice(1));
if (card) {
card.scrollIntoView({ behavior: 'instant' });
}
},
{ once: true }
);
}
{% endjavascript %}
{% comment %} We always render this full-width, as the child blocks have width: page/full settings {% endcomment %}
<div class="section-background color-{{ section.settings.color_scheme }}"></div>
<results-list
class="section product-grid-container color-{{ section.settings.color_scheme }}"
style="--padding-block-start: {{ section.settings.padding-block-start }}px; --padding-block-end: {{ section.settings.padding-block-end }}px;"
section-id="{{ section.id }}"
>
{% render 'skip-to-content-link', href: '#ResultsList', text: 'accessibility.skip_to_results_list' %}
<div
class="collection-wrapper grid gap-style"
>
{% content_for 'block',
type: 'filters',
id: 'filters',
results: collection,
results_size: collection.products_count
%}
{% if request.design_mode and shop.products_count == 0 %}
{% paginate products by 24 %}
{% capture children %}
{% for product in products %}
<li
class="product-grid__item product-grid__item--{{ forloop.index0 }}"
data-page="{{ paginate.current_page }}"
data-product-id="{{ product.id }}"
data-view-transition-id="{{ product.id }}"
ref="cards[]"
>
{% content_for 'block', type: 'product-card', id: 'product-card', closest.product: product %}
</li>
{% endfor %}
{% endcapture %}
{% render 'product-grid', section: section, children: children, products: products, paginate: paginate %}
{% endpaginate %}
{% else %}
{% paginate collection.products by 24 %}
{% capture children %}
{% for product in collection.products %}
<li
id="{{ section.id }}-{{ product.id }}"
class="product-grid__item product-grid__item--{{ forloop.index0 }}"
data-page="{{ paginate.current_page }}"
data-product-id="{{ product.id }}"
ref="cards[]"
>
{% # theme-check-disable %}
{% content_for 'block', type: 'product-card', id: 'product-card', closest.product: product %}
{% # theme-check-enable %}
</li>
{% endfor %}
{% endcapture %}
{% render 'product-grid',
section: section,
children: children,
products: collection.products,
paginate: paginate
%}
{% endpaginate %}
{% endif %}
</div>
</results-list>
{% stylesheet %}
.main-collection-grid {
grid-column: var(--grid-column--mobile);
@media screen and (width >= 750px) {
grid-column: var(--grid-column--desktop);
}
}
.collection-wrapper {
@media screen and (width >= 750px) {
grid-template-columns:
1fr repeat(
var(--centered-column-number),
minmax(0, calc((var(--page-width) - var(--page-margin) * 2) / var(--centered-column-number)))
)
1fr;
}
}
.collection-wrapper:has(.facets-block-wrapper--full-width),
.collection-wrapper:has(.collection-wrapper--full-width) {
@media screen and (width >= 750px) {
grid-column: 1 / -1;
grid-template-columns:
minmax(var(--page-margin), 1fr) repeat(
var(--centered-column-number),
minmax(0, calc((var(--page-width) - var(--page-margin) * 2) / var(--centered-column-number)))
)
minmax(var(--page-margin), 1fr);
}
}
.collection-wrapper:has(.facets--vertical) .facets-block-wrapper--vertical:not(.hidden) ~ .main-collection-grid {
@media screen and (width >= 750px) {
grid-column: var(--facets-vertical-col-width) / var(--full-width-column-number);
}
}
.collection-wrapper:has(.facets-block-wrapper--vertical:not(#filters-drawer)):has(.collection-wrapper--full-width) {
@media screen and (width >= 750px) {
grid-column: 1 / -1;
grid-template-columns: 0fr repeat(var(--centered-column-number), minmax(0, 1fr)) 0fr;
}
}
:is(.collection-wrapper--full-width, .collection-wrapper--full-width-on-mobile)
[product-grid-view='default']
.product-grid__item
.group-block {
@media screen and (width < 750px) {
padding-inline-start: max(var(--padding-xs), var(--padding-inline-start));
padding-inline-end: max(var(--padding-xs), var(--padding-inline-end));
}
}
:is(.collection-wrapper--full-width, .collection-wrapper--full-width-on-mobile)
[product-grid-view='mobile-single']
.product-grid__item
.group-block {
@media screen and (width < 750px) {
padding-inline-start: max(var(--padding-xs), var(--padding-inline-start));
padding-inline-end: max(var(--padding-xs), var(--padding-inline-end));
}
}
{% endstylesheet %}
{% schema %}
{
"name": "t:names.collection_container",
"enabled_on": {
"templates": ["collection"]
},
"settings": [
{
"type": "select",
"id": "layout_type",
"label": "t:settings.type",
"options": [
{
"value": "grid",
"label": "t:options.grid"
},
{
"value": "organic",
"label": "t:options.editorial"
}
],
"default": "grid"
},
{
"type": "select",
"id": "product_card_size",
"label": "t:settings.card_size",
"options": [
{
"value": "small",
"label": "t:options.small"
},
{
"value": "medium",
"label": "t:options.medium"
},
{
"value": "large",
"label": "t:options.large"
},
{
"value": "extra-large",
"label": "t:options.extra_large"
}
],
"default": "medium",
"visible_if": "{{ section.settings.layout_type == 'grid' }}"
},
{
"type": "select",
"id": "mobile_product_card_size",
"label": "t:settings.mobile_card_size",
"options": [
{
"value": "small",
"label": "t:options.small"
},
{
"value": "large",
"label": "t:options.large"
}
],
"default": "small"
},
{
"type": "header",
"content": "t:content.layout"
},
{
"type": "select",
"id": "product_grid_width",
"label": "t:settings.width",
"options": [
{
"value": "centered",
"label": "t:options.page"
},
{
"value": "full-width",
"label": "t:options.full"
}
],
"default": "centered"
},
{
"type": "checkbox",
"id": "full_width_on_mobile",
"label": "t:settings.full_width_on_mobile",
"default": true,
"visible_if": "{{ section.settings.product_grid_width != 'full-width' }}"
},
{
"type": "range",
"id": "columns_gap_horizontal",
"label": "t:settings.horizontal_gap",
"min": 0,
"max": 50,
"step": 1,
"unit": "px",
"default": 16
},
{
"type": "range",
"id": "columns_gap_vertical",
"label": "t:settings.vertical_gap",
"min": 0,
"max": 50,
"step": 1,
"unit": "px",
"default": 16
},
{
"type": "range",
"id": "padding-inline-start",
"label": "t:settings.left_padding",
"min": 0,
"max": 100,
"step": 1,
"unit": "px",
"default": 0
},
{
"type": "range",
"id": "padding-inline-end",
"label": "t:settings.right_padding",
"min": 0,
"max": 100,
"step": 1,
"unit": "px",
"default": 0
},
{
"type": "header",
"content": "t:content.section_layout"
},
{
"type": "color_scheme",
"id": "color_scheme",
"label": "t:settings.color_scheme",
"default": "scheme-1"
},
{
"type": "range",
"id": "padding-block-start",
"label": "t:settings.top_padding",
"min": 0,
"max": 100,
"step": 1,
"unit": "px",
"default": 8
},
{
"type": "range",
"id": "padding-block-end",
"label": "t:settings.bottom_padding",
"min": 0,
"max": 100,
"step": 1,
"unit": "px",
"default": 8
},
{
"type": "header",
"content": "Promo Block"
},
{
"type": "text",
"id": "promo_block_title",
"label": "Promo Title",
"default": "Special Offer",
"info": "The title of the Block Promotion"
},
{
"type": "textarea",
"id": "promo_block_description",
"label": "Promo Description",
"default": "This is a limited time offer for our customers.",
"info": "Promotion description"
},
{
"type": "text",
"id": "promo_block_button_text",
"label": "Button Text",
"default": "Shop Now",
"info": "Written button calling for action"
},
{
"type": "url",
"id": "promo_block_link",
"label": "Promo Link",
"info": "Links when clicking the button"
},
{
"type": "checkbox",
"id": "show_promo_block",
"label": "Show Promo Block",
"default": true,
"info": "Show the promotion block in Grid"
}
],
"presets": []
}
{% endschema %}
Step 3: Fill in the appropriate promo banner information in the 'default collection' section
*Result:
If you like this approach, don’t forget to rate it as a solution.
Best regards.
Mageplaza | Top-Rated Shopify Agency | Trusted by 230,000+ worldwide merchants
If our suggestion works for you, please give it a Like or mark it as a Solution!
Should you have any questions or concerns, feel free to contact us via consultant@mageplaza.com