Shopify Partners Learning Liquid 2020
Shopify Partners Learning Liquid 2020
Liquid
Hints, Tips, and Tricks for Getting Started
with Shopify Theme Development
Introduction
• Plus, even more tips, tricks, and hacks for customizing Shopify
stores using Liquid!
Table of contents
An Overview
of Liquid: What
You Need to Know
However, that’s really where the similarities end. There’s a lot you can’t
do with Liquid — by design. For example, it has no concept of “state,” it
doesn’t let you get deep under the covers of the platform, and can
occasionally seem counterintuitive for seasoned coders. However, it
has been very well thought out, and what might at first seem like
a limitation is usually intended and for good reason.
Liquid’s function
Liquid, like any template language, creates a bridge between an HTML
file and a data store — in our context, the data is of course a Shopify
store. It does this by allowing us to access variables from within
a template with a simple to use, and readable, syntax.
When rendered, this would output the name of the currently viewed
product in place of the {{ }} . For example:
<h2>American Diner Mug</h2>
The first element preceding the . is the object. In this case, it’s the
shop object. This is a variable that represents all the data relating to
the shop that we have defined in the Shopify Admin. These data items
include:
• shop.address
• shop.collections_count
• shop.currency
• shop.description
• shop.domain
• shop.email
• shop.metafields
• shop.money_format
• shop.money_with_currency_format
• shop.name
• shop.password_message
• shop.permanent_domain
• shop.policies
• shop.products_count
• shop.secure_url
• shop.types
• shop.url
• shop.vendors
Collection properties
You’ll notice from the list above that a number of the properties are
plural, such as:
• shop.enabled_payment_types
• shop.metafields
• shop.types
When first using Shopify and Liquid, it’s easy to get confused
by collections. We’ll therefore refer to “product collections” and
“Liquid collections,” the former being a logical grouping of products
defined in the Shopify Admin, and the latter being a list
of items we can access in Liquid code.
Finally, it’s worth saying that each one of the list items in our Liquid
collection can also have properties. A good example of this is
product.images . This represents a list of all the images that have
been added to a particular product.
Each of the images in the list has multiple properties associated with it:
• image.alt
• image.attached_to_variant?
• image.id
• image.product_id
• image.position
• image.src
• image.variants
• image.height
• image.width
• image.aspect_ratio
Our aim with this loop is to output all of the images for a particular
product. Here’s a very simplistic loop that will output each image inline:
Step 1
{% for image in product.images %}
The first line introduces us to the second style of delimiter, the curly
brace percentage syntax {% %} . Here, we’re using a Liquid for
loop. Loops work with Liquid collections, and allow us to iterate over
each item in our list in turn. If the product we’re currently viewing had
six images associated with it, our for loop would loop six times, if
it had 10 then it would loop 10 times, and so on. Only once every list
item has been looked at (or unless we instruct it otherwise) will the
next part of the template be considered.
Step 2
<img src=”{{ image | img_url: ‘100x100’ }}”>
The second line of our code example consists of part HTML and part
Liquid. You’ll also notice that the src attribute is populated with
a Liquid output tag.
The final line of our example is our closing endfor statement. This tells
the template to carry on after all the loops have been executed.
<img src=“//cdn.shopify.com/s/files/1/2509/4288/products/
13038FAW_PRO_EarringsD_352_100x100.jpg?v=1509545613”>
<img src=“//cdn.shopify.com/s/files/1/2509/4288/products/
13039FAW_PRO_SQ_Jewellery4F_022_100x100.jpg?v=1509545613”>
<img src=“//cdn.shopify.com/s/files/1/2509/4288/products/
13039FAW_PRO_SQ_Jewellery4S_023_100x100.jpg?v=1509545613”>
Loops are really useful and something you’ll encounter daily in your
theme development. Outputting images and product variants are two
commonly found examples.
Liquid filters
Another very powerful feature of Liquid is output filters, which we
used in the code example above. Filters serve three main purposes:
You’ll notice the | character in the middle of the output tag. On the
left side of the pipe, we have the article object with its associated
published_at property, and on the right we have the date filter
with an argument to denote the date format — in this case %a, %b %d,
%y .
Without the filter, Shopify would simply output the date the blog
article was published in the format in which it’s stored in the database,
which may not be humanly readable. However, by adding in the |
and including the date filter, we can manipulate the format so it
outputs in a format we want. In this case the date would output in this
format:
Adding a stylesheet
Put simply, filters allow us to take a piece of data from our store and
change it. What we start with on the left-hand side gets piped through
our filter and emerges on the right-hand side changed. It’s this final
manipulated data that is then output in the template.
Here, we’re using two filters with the ultimate aim of creating a fully
formed style element in a layout file.
We start on the left with the name of our CSS file, which resides in the
theme’s assets folder. Next we apply our first filter — in this case the
asset_url filter. This is an incredibly useful filter and one you’ll
use a lot. We’ve mentioned before how Shopify themes, thanks to
The final filter in the chain, stylesheet_tag , takes the URL and
wraps it in a style element which is then output in our layout file.
Here’s the final result:
<link href=“//cdn.shopify.com/s/files/1/0087/0462/t/394/
assets/shop.css?28178” rel=“stylesheet” type=“text/css”
media=“all”>
Each filter takes the output from its preceding filter and in turn
modifies it. When there are no further filters to pass data into,
the result is output as HTML into the template.
There are many really useful filters. Here are just a few you’ll find
yourself using:
• asset_url
• stylesheet_tag
• date
• pluralize
• replace
• handle
• money
• money_with_currency
• img_url
• link_to
Liquid logic
The final aspect of Liquid we need to look at is logic.
Here’s an example:
{% if product.available %}
<h2>Price: £99.99</h2>
{% else %}
<h2 class=“sold-out”>Sorry - sold out</h2>
{% endif %}
It’s worth noting that unlike output tags, the inclusion of logic tags in
your templates does not result in anything being directly rendered —
rather, they allow us to control exactly what is rendered.
{% if cart.item_count > 0 %}
<p>You have {{ cart.item_count }} item(s) in your cart
</p>
{% else %}
<p>There’s nothing in your cart :( Why not have a
<a href= “/products”>look at our product range</a></p>
{% endif %}
This example demonstrates how you can either display the number of
items in a visitor’s cart or output a link to your products.
The full list of control flow tags that you can use to create conditions
are:
• if
• unless
• else
• elseif
• when
Operators
You’ll notice in this example we’re using the greater than > operator.
As the cart.item_count variable returns the number of items in
the current user’s cart, we can check to see if it’s greater than zero, i.e.
it has items in it.
If this returns true we can output the message with the current item
count; if not we can output <p>There’s nothing in your cart :(
Why not have a <a href=“/products”>look at our product
range</a></p> instead.
{% if cart.item_count > 0 %}
<p>You have {{ cart.item_count }} {{ cart.item_count |
pluralize: ‘item’, ‘items’ }} in your cart</p>
{% else %}
<p>There’s nothing in your cart :( Why not have a
<a href= “/products”>look at our product range</a></p>
{% endif %}
You’ll notice that the refactored example now includes the pluralize
filter which takes two parameters. The first is the singular word and
the second the plural.
Operator Function
== equals
or condition A or condition B
Whitespace control
Whitespace control in Liquid enables you to remove whitespace
rendered by Liquid output. In Liquid, you can use a hyphen in your tag
syntax, {{- , -}} , {%- , and -%} to strip whitespace from
the left or right side of a rendered tag.
For example:
{% assign my_variable = “coffee” %}
{{ my_variable }}
outputs to:
coffee
For example:
{%- assign my_variable = “coffee” -%}
{{ my_variable }}
outputs to:
coffee
Summary
We’ve covered a lot of ground in this chapter, but hopefully it‘s given
you a solid introduction to Liquid. Here’s a reminder of what we covered:
How to Setup
a “Local”
Shopify Theme
Development
Environment
Many developers and designers use and love the online Shopify
Theme Editor — it’s easy to work with and is conveniently located
within the Shopify Admin itself. But if you’re looking to develop
Shopify themes locally, you should know that you’re not limited
to the online theme editor.
Once Theme Kit is set up, you can more easily integrate workflow tools
like Git into your theme development — giving you the confidence to
work on a Shopify Theme with a team of developers, work within your
favorite text editor, and have a more localized experience when editing
themes. Theme Kit isn’t a truly local development environment, in that
it still requires a connection to Shopify servers. If you’re looking for a
local offline development tool, checkout Motifmate, which supports an
offline option.
If you’re working on Mac, you can use homebrew to install Theme Kit
by running the following commands:
brew tap shopify/shopify
brew install themekit
If you are on a Linux based system, you can use the following
installation script to automatically download and install the latest
Theme Kit for you:
curl -s https://shopify.github.io/themekit/scripts/
install.py | sudo python
Make sure you’re using the most up-to-date version of Theme Kit (you
can find versions here). To update Theme Kit, run:
theme update
To test that Theme Kit is installed and working, and to see available
commands, type:
theme --help
To do so, we need to log into the Shopify store, and create a private
app. In the Shopify Admin, go to Apps and click on the Manage private
apps link at the bottom of the page. From there, click Generate API
credentials to create your private app. You’ll need to provide a title
— we usually provide the name of the client and environment for
clarity. Make sure to set the permissions of Theme templates and
theme assets to have Read and write access in order to generate the
appropriate API credentials, then click Save.
Shopify will load a new page, which will provide you with a unique API
key and password.
Theme ID
To connect an existing theme, we need the theme’s ID number. There
are a few ways to get your theme’s ID number. The quickest way is to
go to the Theme Editor, by clicking on Actions > Edit Code, and copy
the theme ID number from the URL — it will be the last several digits
after mystore.myshopify.com/admin/themes/
If you want to build a theme from scratch, you can do that by running
the following in your command line, which creates a new, basic theme
in the directory you run it in:
theme new --password=[your-password] --store=
[your-store.myshopify.com]
For example:
theme configure
--password=01464d4e02a45f60a23193ffc3a8c1b3
--store=the-soap-store.myshopify.com
--themeid=170199178
This will automatically create a config.yml file for you. You can also
manually create a config.yml file in the directory with a text editor,
which would look something like this:
Then, you can run the following command to download and setup your
existing theme in the current directory:
theme download
Theme Kit will now watch for any changes made to your local files,
and automatically push them to your theme. To close the watch
connection, simply type ctrl + c .
If you’re looking for more reading on using Theme Kit, check out
the documentation and other amazing features.
However, if you are new to Shopify themes, you may not know exactly
when each template gets rendered, or be aware that the same
template gets used in various places around the store.
URLs to templates
Here’s an overview of which template is rendered as determined
by the URL:
/thisisntarealurl → 404.liquid
/blogs/{blog-name}/{article-id-handle} → article.liquid
/blogs/{blog-name} → blog.liquid
/cart → cart.liquid
/collections → list-collections.liquid
/collections/{collection-handle} → collection.liquid
/collections/{collection-handle}/{tag} → collection.liquid
/ → index.liquid
/pages/{page-handle} → page.liquid
/products → list-collections.liquid
/products/{product-handle} → product.liquid
/search?q={search-term} → search.liquid
Alternate templates
It’s also worth remembering that the above routing table can
be affected by alternate templates — something we’ll cover in a
later chapter.
URL parameters
As you’ll see above, a number of the routes have elements of the URL
path wrapped in { } . We have included this to denote a variable
that will have an impact on the data loaded into a template.
You’ll also notice that a number of different URL patterns share the
same template file. For example, /products and
/collections will both render the list-collections.
liquid template. Likewise, /collections/ , /collections/
{collection-handle}/ , and /collections/{collection-
handle}/{tag} all make use of collection.liquid .
Here’s a handy example that you can use in your own theme
development with the output shown in the screenshot below:
The
product.liquid
Template
So far in our book we’ve looked at how URLs are mapped in our
Shopify templates. In this chapter, we’d like to take a more in-depth
look at one particular template — product.liquid .
Next we add a select element that will output a drop down option to
pick a product variant. Within this element we create a for loop to
iterate over all the current product’s variants and display the variant’s
price, with currency formatting — thanks to the money filter.
This template makes use of both the product and variant objects. They
have a large range of properties that you can display in this template,
and are worth investigating as you develop your Shopify theme skills.
How to Use
Alternate
Templates
This chapter will run you through the basics of creating your first
alternate template so that you can start customizing your Shopify
themes even further.
If you’re using Theme Kit, or are uploading your theme using a ZIP file,
you can simply add a file to your theme’s templates folder using the
following filename syntax:
default_template_name.*.liquid
The name itself is irrelevant — the more obvious the better so your
clients can recognize its purpose easily.
Here’s an example for you to review (these links are for demo purposes
only):
http://store.myshopify.com/products/blue-t-
shirt?view=special
If the template requested does not exist, Shopify will fail gracefully and
use the default template, or the template specified in the admin.
A really common use case for this technique is for switching between
a list and grid view within a product collection.
However, if your new template includes a Liquid tag for a section that
contains the code you want to edit, you will need to create a new
section for that alternative code.
The Power
of Alternate
Layout Files
If you aren’t familiar with layouts you’ll find the default file, theme.
liquid , in the layouts folder within your theme directory. If you’ve
never seen one before you might be wondering what’s going on!
Alternate layouts
One layout file isn’t going to cover every eventuality, and there
will be situations where you’ll require a completely different layout.
You could start hiding elements with CSS, but that feels a little wrong
— the far better approach is to create an alternate layout complete
with different HTML markup.
In order to use this layout file, and effectively override the default
theme.liquid layout file, we use the following Liquid syntax as the
first line in any template file ( index.liquid , product.liquid ,
etc.):
{% layout ‘alternative’ %}
It’s also possible to request that the layout file isn’t applied.
The syntax to request that a layout file isn’t applied is:
{% layout none %}
This needs to be the first line at the top of the relevant template
( index.liquid , product.liquid , etc.). A use case for this
might be when rendering output from your store in an alternative
syntax such as JSON.
In order to use these, our base layout file would look as follows:
{% render html-header %}
{% render header %}
{% render footer %}
{% render html-footer %}
One of the most underused features in Shopify are link lists. As its
name suggests, a link list is a simple collection of links. The link
items can be created to point to a page, collection, or product within
Shopify, or to a URL outside of the store’s domain.
It’s possible to use a link list for a variety of reasons. In this chapter,
we’ll examine a common theme use case: nested navigation using
an unordered list. By using link lists and Liquid, we’ll have full
control over the menu from within the admin, giving flexibility to the
merchant running the store.
While it’s common to include the navigation in a layout file, the default
one being theme.liquid , you can test out the nested navigation
concept in any template.
Creating menus
We’ll begin by creating a new menu, our parent menu, by heading to
the Navigation tab in the Shopify Admin, which resides under
the Online Store link in the sidebar.
All new stores have a predefined default menu called “Main Menu.”
To add items to the list, simply click the add another link button,
and give your new item a “link name” and a destination. The select
drop down will allow you to easily link to internal sections, such as a
particular product or collection. Alternatively, you can enter your own
URL (either internal or external) by choosing “web address” from the
options.
Once we have this in place, we can start to consider the Liquid code
we’ll need to output this in our theme.
You can drag and drop nested menu items to create a multi-level
navigation, and with some JavaScript and CSS easily style it into
a “super-menu” or “drop-down menu.”
Let’s begin by outputting all the items from the Main Menu link list. We
can use a simple for loop we’ve used many times before to output
the link list items in turn:
<ul>
{% for link in linklists.main-menu.links %}
<li><a href= “{{ link.url }}”>{{ link.title }}</a></li>
{% endfor %}
</ul>
This Liquid syntax isn’t new to us, however it’s worth examining the
opening Liquid section:
{% for link in linklists.main-menu.links %}
Once again, we’re using the variable link to hold the data relating
to each item in the link list, as we loop over all the items. In order to
access the data, we need to access all the links in the link list with a
handle of main-menu .
Remember, the default Main Menu that exists in a Shopify store has
the handle of main-menu , which is why it’s being used above. If our
menu had a handle of uk-brands , the syntax would be refactored as:
{% for link in linklists.uk-brands.links %}
Multi-level navigation
Now that we have the basic Liquid structure in place for a single level
menu, we need to consider how to create a sub-menu for our top level
items. Firstly, we need to head back to the Shopify Admin and create
our first sub-menu.
It might not be 100 percent clear initially, but every link in a link list, in
addition to the menu itself, has a unique handle that we have access
to in Liquid.
What’s great about using nested menus in Shopify is that nested menu
items can be obtained directly from their parent link using Liquid.
This greatly simplifies the markup required to render a nested menu —
meaning you don’t need to know the handle of the parent to render its
children.
<ul class=“parent”>
{% for link in linklists.main-menu.links %}
<li><a href=“{{ link.url }}”>{{ link.title }}</a>
{% if link.links != blank %}
<ul class=“child”>
{% for child_link in link.links %}
<li><a href= “{{ child_link.url }}”>{{ child_link.
title }}</a>
{% if child_link.links != blank %}
<ul class=“grandchild”>
{% for grandchild_link in child_link.links %}
<li><a href= “{{ grandchild_link.url }}”>{{ grand
child_link.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
Final touches
We’d like to quickly mention one extra link property that will be very
useful when creating menus — link.active and link.child_
active . These are both boolean properties ( true/false ) that
allow you to easily tell if the current page is active, as well as if it’s
nested items are active. Here’s the syntax:
{% if link.active %} class=”active {% if link.child_
active %}child- active{% endif %}”{% endif %}
In this example, we’ll add a CSS class of active if the current page
URL is the same as the list item, and a class of active-child if
<ul class=“parent”>
{% for link in linklists.main-menu.links %}
<li {% if link.active %}class=“active {% if link.child_ac-
tive %}child-active{% endif %}”{% endif %}><a href=“{{
link.url }}”>{{ link.title }}</a>
{% if link.links != blank %}
<ul class=“child”>
{% for child_link in link.links %}
<li {% if child_link.active %}class=“active {% if
child_link.child_active %}child-active{% endif %}”
{% endif %}><a href= “{{ child_link.url }}”>
{{ child_link.title }}</a>
{% if child_link.links != blank %}
<ul class=“grandchild”>
{% for grandchild_link in child_link.links %}
<li {% if grandchild_link.active %} class=“active
{% if grandchild_link.child_active %}child-
active{% endif %}”{% endif %}><a href= “{{ grand
child_link.url }}”>{{ grandchild_link.title }}
</a></li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
Using Snippets
in Your Shopify
Theme
• They are most often used for code that appears on more than
one page but not across the entire theme.
As you can see, this if statement checks for the currently viewed
products handle. If the returned value contains coffee-cup , the
template will include the snippet special-offer . If the returned
value doesn’t match, the template will simply carry on rendering.
For example:
• product-limited-edition-coffee-cup.liquid
• product-showcase.liquid
• collections-coffee-cups.liquid
You’ll notice that these are very much in line with the template naming
conventions, making them much easier to integrate into your workflow.
Variable scope
When a snippet is rendered in a template file, the code inside it
does not automatically have access to the variables assigned using
variable tags within the snippet’s parent template. Similarly, variables
assigned within the snippet can’t be accessed by the code outside of
the snippet.
Here’s an example:
{% assign my_variable = ‘apples’ %}
{% render ‘name’, my_variable: my_variable, my_other_
variable: ‘oranges’ %}
The snippet will now have access to both the apples variable
and the oranges variable. We could also make a Liquid collection
Using with
To round out our look at snippets, let’s spend some time looking at an
example that uses the render tag parameter with . This approach
really shows off the power of snippets and allows us to create reusable
code that can be used in a variety of contexts.
To set the scene, let’s say we have a snippet that allows us to output a
product collection in a template. Here’s a very basic example that we
could save as collection-product-list.liquid :
<ul>
{% for product in collections.all.products %}
<li><a href=“{{ product.url }}”>{{ product.title }}</a>
{% endfor %}
</ul>
<ul>
{% for product in collection-product-list %}
<li><a href=“{{ product.url }}”>{{ product.title }}</a>
{% endfor %}
</ul>
Let’s have a look at how we make use of this more generic snippet:
{% assign c = collections.all.products %}
{% render ‘collection-product-list’ with c %}
Next, we move onto the render tag and reference the snippet
without the .liquid extension, following it with with c .
The with parameter assigns a value to a variable inside a snippet
that shares the same name as the snippet. While this might sound
confusing at first, have a quick look at the example above which has
the following line:
{% for product in collection-product-list %}
<ul>
{% for product in collection-product-list limit:
limit_count %}
<li><a href=“{{ product.url }}”>{{ product.title }}</a>
{% endfor %}
</ul>
And here’s how we would pass in a value for our limit clause
to reference:
{% assign c = collections.all.products %}
{% render ‘collection-product-list’ with c, limit_
count: 2 %}
When the snippet is rendered, it will exit after the second loop. This makes
our snippet even more generic and will allow us to use it in a variety of
situations.
Note that omitting this variable will mean all the items in the Liquid
collection are iterated over. Also, if the limit_count is higher than
the number of items in the list, it will exit the for loop after the
final list item.
Using Sections
and Blocks in Your
Shopify Theme
Sections are modular, customizable elements of a page, which
can have specific functions. Sections are similar to snippets, in
that they are partials, but they allow customization options on the
Online Store Editor.
{% schema %}
{
“name”: “Section name”,
“settings”: []
}
{% endschema %}
{% stylesheet %}
{% endstylesheet %}
{% javascript %}
{% endjavascript %}
To add content to a section, you’ll want to add HTML and Liquid tags
to the very top of the file. Sections use the Liquid syntax
{{ section.settings.name }} to be identified as fields or
custom content. Liquid tags can then be defined within the schema,
so the section can be customized in the Online Store Editor. You
can see the different input values that can be added to the schema
settings in our documentation.
{% schema %}
{
“name”: “Text Box”,
“settings”: [
{
“id”: “text-box”,
“type”: “text”,
“label”: “Heading”,
“default”: “Title”
},
{
“id”: “text”,
“type”: “richtext”,
“label”: “Add custom text below”,
“default”: “<p>Add your text here</p>”
}
]
}
{% endschema %}
{% stylesheet %}
{% endstylesheet %}
{% javascript %}
{% endjavascript %}
In the example above, we’ve created a plain text box and a rich text
box, but you can add a wide range of output types depending on your
requirements. Other valid input types include image_picker ,
radio , video_url , and font .
For example, presets for a call-to-action button section could look like
this:
“presets”: [
{
“name”: “Call to Action”,
“category”: “CTA button”
}
]
Once these presets are added to the end of the schema file, the
theme will automatically recognize this as a dynamic section, which
Value Application
checkbox Checkboxes
{% schema %}
{
“blocks”: [
{
“type”: “quote”,
“name”: “Quote”,
“settings”: [
{
“id”: “content”,
“type”: “text”,
“label”: “Quote”
}
]
}
]
}
{% endschema %}
{% when ‘text’ %}
<div class=“grid__item {{ column_width }}”>
<h3 class=“h4”>{{ block.settings.title }}</h3>
<div class=“rte”>{{ block.settings.richtext }} </div>
</div>
{% when ‘newsletter’ %}
<div class=“grid__item {{ column_width }}”>
<h3 class=“h4”>{{ ‘layout.footer.newsletter_title’
| t }}</h3>
<p>{{ ‘layout.footer.newsletter_caption’ | t }} </p>
{% render ‘newsletter-form’ %}
</div>
{% endcase %}
{% endfor %}
Now that you’ve seen how easy it is to add sections to your themes,
you can add endless options to your clients’ stores.
How to Use
all_products in a
Shopify Theme
Liquid handles
If you aren’t familiar with handles, the Shopify Help Center provides a
great explanation:
• all_products[“coffee-cup”].available all_
products[“coffee-cup”].collections
• all_products[“coffee-cup”].compare_at_price_
max
• all_products[“coffee-cup”].compare_at_price_
min
• all_products[“coffee-cup”].compare_at_price_
varies
• all_products[“coffee-cup”].content
• all_products[“coffee-cup”].first_available_
variant
• all_products[“coffee-cup”].handle
• all_products[“coffee-cup”].id all_
products[“coffee-cup”].images
• all_products[“coffee-cup”].image
• all_products[“coffee-cup”].options all_
products[“coffee-cup”].price
• all_products[“coffee-cup”].price_max all_
products[“coffee-cup”].price_min
• all_products[“coffee-cup”].price_varies
• all_products[“coffee-cup”].selected_variant
• all_products[“coffee-cup”].selected_or_first_
available_variant
• all_products[“coffee-cup”].tags all_
products[“coffee-cup”].template_suffix
• all_products[“coffee-cup”].title all_
products[“coffee-cup”].type
• all_products[“coffee-cup”].url all_
products[“coffee-cup”].variants
• all_products[“coffee-cup”].vendor
This example would output all of the images associated with the
coffee-cup product.
Using the Liquid assign tag, we create a new variable called favorites,
which are product handles separated by a | character. The | is
used as a delimiter to divide the string into an array that we can loop
over using for .
We now have access to both products in turn and can output any
property associated with it — in the example above we simply display
the title.
Manipulate Images
with the img_url
Filter
In this chapter, we’ll look at how to use the img_url filter and examine
the recently added parameters that allow you to manipulate images
within Shopify in new and exciting ways.
• product
• variant
• line item
• collection
• article
• image
You can also chain the img_url filter with the img_tag filter to
output the full <img> element:
{{ product.featured_image | img_url: ‘100x100’ |
img_tag }}
Additional parameters
Before moving on, it’s worth noting that the following techniques can
be used with a range of filters in addition to img_url . They are:
• product_img_url
• collection_img_url
• article_img_url
1. Size
Let’s begin by looking at how we can resize an image. In order to do
this, we replace the image “name” with a specific size in pixels.
Width only:
{{ product.featured_image | img_url: ‘450x’ }}
Height only:
{{ product.featured_image | img_url: ‘x450’ }}
When only specifying a single value, Shopify will calculate the other
dimension based on the original image size, keeping the original
image’s aspect ratio intact.
Going back to our original example, you might think that it would
result in a 450x450 version of your image being rendered.
This, however, isn’t always the case.
2. Crop
Thankfully, creating perfect squares won’t require you to upload
square images. All that it requires is the addition of another new
parameter called crop . You specify a crop parameter to ensure that
the resulting image’s dimensions match the requested dimensions.
If the entire image won’t fit in your requested dimensions, the crop
parameter specifies which part of the image to show.
• top
• center
• bottom
• left
• right
3. Scale
As well as dimensions, we can also request a certain pixel density
using the scale parameter.
• 3
You can simply add this as another argument to the img_url filter
as follows:
{ product.featured_image | img_url: ‘450x450’, crop:
‘center’, scale: 2 }}
4. Format
There’s one final parameter you can add, which is format.
• jpg
• pjpg
• PNG to JPG
• JPG to PJPG
It’s not practical to convert a lossy image format like JPG to a lossless
one like PNG, so those conversions aren’t possible.
Caching
Finally, it’s worth noting that once the requested image has been
created, it will be cached and made available on the Shopify CDN
(Content Delivery Network). Consequently, there’s no need to worry
about the image being created every time your template is rendered.
Conclusion
Thanks to these new parameters, it’s now possible to implement
responsive image techniques in your templates. Whether you want to
start using the srcset and sizes attributes, or the
<picture> element, you can start offering the most appropriate
image for screen size, resolution, and bandwidth.
Ways to Customize
the img Element
Now we’re going to have a look at the humble HTML img element.
When creating a Shopify theme, you can add any number of images,
in any format, and at any size to the assets folder within your theme
directory. Typically, these images are used for backgrounds, sprites,
and branding elements.
This approach uses two Liquid filters to create a fully formed HTML
<img> element. The first, asset_url , prepends the full path
to the assets folder for the current store’s theme, while the second,
img_tag , uses this URL and creates an HTML <img> element
complete with the alt attribute. If omitted, the alt attribute will
be blank.
You’ll notice that the src attribute references the Shopify CDN.
Every image that you add, regardless of its type, will be pushed out to
the Shopify CDN. You’ll never need to worry about the location of your
images, as the asset_url filter will work this out for you when the
page is rendered.
Here’s an approach that would allow you to add your own attributes
such as an id :
<img src=”{{ ‘logo.png’ | asset_url }}” alt=”Logo”
class=”cssclass1 cssclass2” id=”logo”>
Creating Useful
CSS Hooks
in Liquid
Many of us use the <body> class for CSS as well as JavaScript hooks
and, just like in WordPress, it’s pretty easy to add a number of useful
classes to our <body> element in Shopify.
Here are a few ideas that you might find useful placing in your main
(or alternate) layout file.
If you are using alternate product templates, you may wish to use the
contains operator instead:
<body class=”{{ template }}{% if template contains
“product” %}{{ product.handle }}{% endif %}”>
Note that in this example we’re using the Liquid filter handleize
to ensure that the id or class that we add is URL safe and
therefore easy to reference in our CSS and JS files. For example,
it will turn a page title of “Blue Jeans” into “blue-jeans”.
It’s pretty easy to adjust this logic for your own purposes.
Again, you may wish to use the contains operator if you are
utilizing alternate templates.
Summary
Hopefully you’ve seen how flexible Liquid is in the above examples.
Being able to add a variety of classes to the <body> element gives
us useful hooks that we can use in CSS and JavaScript.
Using Liquid’s
case/when
Control Tags
We’re sure many of you are more than familiar with Liquid control tags
such as if and else , but are you familiar with case/when ?
If you omit the else clause and the handle variable never evaluates
to true , no output will be output. This is because the
else clause acts as a fallback in the above example.
• Educational resources
• And more