Justin Duke

Liquid trinkets

I’ve been messing around with a lot of Shopify development the past couple months. It’s a pretty neat platform that I want to talk about more in depth at some point in the future, but the number one cause of frustration 1 is dealing with Liquid, their in-house template rendering engine which seems to pride itself on straddling the line between “holy shit this is awesome” and “holy shit why can’t you do this basic task.”

Below is a smattering of one-liners and helpful patterns/tricks to do common things with Liquid. Feel free to email me if you have more – I’ll be updating this post as I find more useful stuff.

Instantiating arrays with assign

The grossest – and easiest – way of doing this to my knowledge is using the split command on a delimited list. Like so:

{% assign anArray = "orange,blue,crimson" | split: "," %}
{% for item in anArray %}
  {{ item }}
{% endfor %}

Which, should compile to:

{{ orange }}
{{ blue }}
{{ crimson }}

Adding or removing from a date

Basically – get a given timestamp (in this example, {{ 'now' }}, which returns the current timestamp), convert it into unix time, and then add or remove milliseconds from that and recast it into a date.

This, for example, would go back a week from right now:

{{ 'now' | date: "%s" | minus : 604800 | date: "%b %d, %Y" }}

Whereas this would jump forward a month 2:

{{ 'now' | date: "%s" | plus : 2592000 | date: "%b %d, %Y" }}

(The final result is a parsed date, so you can do the standard stuff with it at that point.)

Getting more than ten search results

Just wrap everything in a {% paginate %} block:

{% paginate search.results by 9999 %}
  // All of your actual search.liquid code.
{% endpaginate %}

As one might expect, this basically “breaks” pagination, which is generally a UX win for user discovery anyway. Instead of just throwing the first ten search results out there, you’ll grab up to 9999 3.

Pinterest complaining about “invalid data uri”

Okay, this isn’t even a Liquid issue exactly, just a Shopify one. If you’re constructing images using Liquid tags so that it gets picked up by the Shopify CDN, which is (generally) a great idea, it might look something like this:

{{ product.featured_image | product_img_url: 'grande' }}

So setting the image metadata for the page might look something like this:

<meta property="og:image" content="{{ product.featured_image | product_img_url: 'grande' }}" />

This resolves to Shopify’s CDN, which is dope for same-domain stuff, making it look like something like this:

<meta property="og:image" content="//cdn.shopify.com/s/files/1/0270/4491/products/quote-5-2_grande.jpg?v=1431971498" />

The problem here is that if Pinterest tries to pick that up, it can’t resolve the //cdn part of the equation since it’s on a different domain. The clumsy but easy way to fix this is to just prefix the whole thing with http:

<meta property="og:image" content="http:{{ product.featured_image | product_img_url: 'grande' }}" />

There are more elegant ways to fix this problem then just hard-coding in the protocol, but you get the basic idea. Hope this saved you a bunch of random adding-and-removing of GET parameters!


  1. Well, besides the local development options (and lack thereof.) It would hugely benefit from a Wordpress-esque local staging solution. [return]
  2. Okay, not a month exactly, just thirty days. But you get my point. [return]
  3. Or some other suitably large number. [return]
Liked this post? You should subscribe to my newsletter and follow me on Twitter.

(I've got an RSS feed, too, if you'd prefer.)