I have a string "products_2016-05-09" where 2016-05-09 is date appended in the string. I want to extract this date. If the date is minus 1 day I want to display string "products". How can I do this in liquid syntax?
To extract the date from the string, use the remove and split filters:
{% assign pdate = string | remove: "products_" %}
{% assign pdate = pdate | split: '-' %}
To check if that product date (pdate) is within 24 hours (86400 seconds) back, use something like this:
{% assign today = "now" | date: "%s" %}
{% assign yesterday = today | minus: 86400 %}
{% if pdate[0] == yesterday | date: "%Y" and pdate[1] == yesterday | date: "%m" and pdate[2] == yesterday | date: "%d" %}
Display string "products"
{% endif %}
Note: This only check if the product date is yesterday (24 hours ago from now) for a more accurate time verification, you need to do more arithmetics. You could also do all of this on the front-end using JavaScript.
The below code worked for me:
{% assign var = {{custom_attribute.${producttype}}} %}
{% assign words = var | split: '_' %}
{% assign yestDate = 'now' | date: "%s" | minus: 86400 | date: "%F" %}
{% assign varDate = words[1] %}
{% if varDate | convert: "date" == yestDate %}
Dynamic String {{words[0]}}
{% else %}
sorry!
{% endif %}
Related
I'm using liquid on Shopify. And new to liquid.
Now, I'm trying to indicate "new" sign for products within 7 days.
{% assign today_date = 'now' | date: '%s' %}
{% assign create_date = product.created_at | date: '%s' %}
{% assign dif = today_date - create_date %}
<div>Time diff is {{ dif }}</div>
{% if dif < 30000 %}
<div>New</div>
{% endif %}
It shows errors like this.
Time diff is 1607714358
Liquid error: comparison of String with 30000 failed
What should I do?
Thanks in advance.
All liquid operations (+,-,/,*/%) are done via filters.
So this one here {% assign dif = today_date - create_date %} is incorrect.
It should be like so {% assign dif = today_date | minus: create_date %}.
This is your only mistake in the code.
Final code should be:
{% assign today_date = 'now' | date: '%s' %}
{% assign create_date = product.created_at | date: '%s' %}
{% assign dif = today_date | minus: create_date %}
<div>Time diff is {{ dif }}</div>
{% if dif < 30000 %}
<div>New</div>
{% endif %}
I'm looking to turn a string that you can be edited in Shopify theme settings into an array of object key values in my Liquid file.
For example:
var text = 'key1:value1,key2:value2,anotherKey:anotherValue'
in to:
var array = [{key1: value1}, {key2: value2}, {anotherKey: anotherValue}]
Each object will be separated by a ',' in the string and the key will be to the left of a ':' with the value to the right.
I need to write this inside a theme.liquid file but unsure how to achieve this. Any help would be most appreciated.
I've so far only got as far as:
{% assign text = 'key1:value1,key2:value2,anotherKey:anotherValue' %}
{% assign splitText = text | split: ',' %}
{% assign array = '' | split: '' %}
{% for data in splitText %}
{% assign key = data | split: ':' | first %}
{% assign value = data | split: ':' | last %}
{% assign array = array | concat: key | append: ':' | concat: value %}
{% endfor %}
{{ array }}
Creating associative arrays or arrays with named indexes is not possible in Liquid. However, as a work around, you can create 2 arrays. Treat the same indexes of one array as key while other as value.
A sample implementation would look like
{% assign text = 'key1:value1,key2:value2,anotherKey:anotherValue' %}
{% assign objArr = text | split: ',' %}
{% assign keyArr = ''%}
{% assign valArr = ''%}
{% for obj in objArr %}
{% assign key = obj | split: ':' | first %}
{% assign value = obj | split: ':' | last %}
{% assign keyArr = keyArr| append: ',' | append: key %}
{% assign valArr = valArr| append: ',' | append: value %}
{% endfor %}
{% assign keyArr = keyArr | remove_first: ',' | split: ',' %}
{% assign valArr = valArr | remove_first: ',' | split: ',' %}
{% for obj in objArr %}
{{keyArr[forloop.index0]}} : {{valArr[forloop.index0]}}
<br/>
{% endfor %}
The above code does a basic job. Do not forget to compare both array lengths to identify if all key value pairs were created perfectly as per logic.
I'm working with Liquid templates for Shopify. I want some elements to show up only if the month happens to be December. Since there are multiple elements that need this, I want to set a variable at the top of the document and refer to it later. Here's what I've got that's working:
<!-- At the top of the page -->
{% assign month = 'now' | date: "%m" %}
{% if month == "12" %}
{% assign isDecember = true %}
{% else %}
{% assign isDecember = false %}
{% endif %}
<!-- Only show in December -->
{% if isDecember %}
Happy Holidays
{% endif %}
This works (for testing I change "12" to the current month) but it is pretty ugly. In most languages I would do something like this:
{% assign isDecember = (month == "12") %}
Liquid doesn't accept parentheses, so obviously this won't work. And it doesn't work without parentheses either. The documentation has examples for using operators and for assigning static values to variables, but nothing about combining the two.
I can assign the output of a | filter to a variable, but there don't seem to be filters to cover every operator (or even the necessary "=="), so that's unsatisfactory.
Is there any way to assign the output of an operator to a variable in Liquid?
There isn't a way to do that elegantly and according to this, they won't support ternary operators. There's a mention of someone trying a similar thing.
A slightly shorter/different version would be:
{% assign month = 'now' | date: "%m" %}
{% liquid
case month
when '12'
assign isDecember = true
else
assign isDecember = false
endcase %}
You could altogether avoid using an intermediary boolean flag variable isDecember as Liquid assign with only boolean variables seems to not working within if/endif. Here are the solutions.
Just use plain strings:
{% assign month = 'now' | date: "%m" %}
{% if month == "12" %}
Happy Holidays
{% endif %}
Or use plain string assignments (not boolean values assignments) within ifs:
{% if month == "12" %}
{% assign phrase = "Happy Holidays" %}
{% else %}
{% assign phrase = "Happy usual time of the year" %}
{% endif %}
Now my message to you is: {{ phrase }}
Still want unsing intermediary isDecember? If you would put some dummy text assignment within either clause of if/else that would work too.
{% if month == "12" %}
{% assign dummy = "summy" %}
{% assign isDecember = true %}
{% else %}
{% assign isDecember = false %}
{% endif %}
Hope that helps.
{% for orders in checkout.customer.orders %}
//count the orders
{% endfor %}
I need to count orders made only after a certain date?
How can I do this in Liquid / Shopify?
All Orders have a created_at date that you can output in various formats using the Liquid date filter — you would loop thru the Orders as above and compare that with whatever the "threshold date" in question is, using unix-format dates for comparison:
{% assign ordersThresholdUnix = '2019-01-01' | date: '%s' %}
{% assign ordersCount = 0 %}
{% for orders in checkout.customer.orders %}
{% assign orderDateUnix = order.created_at | date: '%s' %}
{% if orderDateUnix > ordersThresholdUnix %}
{% assign ordersCount = 0 %}
{% endif %}
{% endfor %}
You can then output {{ ordersCount }}.
Note: that I don't think Shopify will allow you to paginate further back than 50 Orders.
I tried lots of things but didn't get what exactly I am looking for.
Below is the example of what type of array I am looking for in Shopify,
$array['bag'] = 2; $array['shoes'] = 3; $array['xyz'] = 6;
Here is the sample of what and how I am looking for my array variable in shopify.
Where
bag, shoes, xyz
are product type
and 2,3,6
are number of products added for specific product type.
I know it's easy in PHP, but don't know how to do in Shopify liquid code.
As per Shopify documentation, you cannot initialize arrays. However, you can use split filter to create one dimensional array. You cannot create associative arrays using this. However, as a workaround, use 2 arrays of same length where same index in both arrays point to related key and value as of associated array. Example code
{% assign product_type = "type-1|type-2|type-3" | split: '|' %}
{% assign product_count = "1|2|3" | split: '|' %}
{% for p_type in product_type %}
{{ p_type }}
{{ product_count[forloop.index0] }}
{% endfor %}
Expected output
Product Type Count
type-1 1
type-2 2
type-3 3
For your particular scenario explained in comments, have a look at below code and code comments. I have used checkout object for sample code. You may adjust according to your need.
// declare 2 vars to create strings - that will be converted to arrays later
{% assign product_type = "" %}
{% assign product_count = "" %}
// iterate over line_items in checkout to build product_type string
{% for line_tem in checkout.line_items %}
// if product_type exists , then skip -- unique product types
{% if product_type contains line_tem.product.type%}
{% else %}
{% assign product_type = product_type | append: '#' | append: line_tem.product.type %}
{% endif %}
{% endfor %}
// remove first extra hash and convert to array
{% assign product_type = product_type | remove_first: "#" | split: '#' %}
// iterate over unique product type array generated earlier
{% for product_type_item in product_type %}
// set product count for this product type to zero initially
{% assign total_count = 0 %}
// iterate over all lin items and +1 if same product type
{% for line_tem in checkout.line_items %}
{% if product_type_item == line_tem.product.type%}
{% assign total_count = total_count | plus: 1 %}
{% endif %}
{% endfor %}
// append count to product count string
{% assign product_count = product_count | append: '#' | append: total_count %}
{% endfor %}
// remove first extra hash and convert to array
{% assign product_count = product_count | remove_first: "#" | split: '#'%}
{{-product_type-}}
{{-product_count-}}