Shopify Theme Development | Creating a 're-order' link for previous orders | Unable to chain multiple ID:quantity query strings - themes

I am using Shopify and creating a re-order button within the file named order.liquid.
while trying to create the re-order button I have had a moderate level of success.
The script I attach does indeed add the items to the cart that were previously ordered. However, I have tried without adding the quantity (just adds 1 of each). Without the [] after the &quantityHERE= (just adds two of each even if it was previously only one item bought).
Heres the code that creates my half-working URL:
{% assign line_items_string = '/cart/' %}
{% for line_item in order.line_items %}
{% if forloop.first == true %}
{% assign line_items_string = line_items_string | append: 'add?id[]=' %}
{% assign line_items_string = line_items_string | append: line_item.variant_id %}
{% assign line_items_string = line_items_string | append: '&quantity[]=' %}
{% assign line_items_string = line_items_string | append: line_item.quantity %}
{% else %}
{% assign line_items_string = line_items_string | append: '&id[]=' %}
{% assign line_items_string = line_items_string | append: line_item.variant_id %}
{% assign line_items_string = line_items_string | append: '&quantity[]=' %}
{% assign line_items_string = line_items_string | append: line_item.quantity %}
{% endif %}
{% endfor %}
Re-order
I am unable to get it to add the correct amount of items per line item even though the URL appears correct:
/cart/add?id[]=16220586868785&quantity[]=3&id[]=16220587360305&quantity[]=6&id[]=16220587622449&quantity[]=4&id[]=16221376479281&quantity[]=11&id[]=16221376348209&quantity[]=2&id[]=16221063938097&quantity[]=1&id[]=16221393682481&quantity[]=2
The fact the string ends with quantity 2 and will then add 2 of each item suggests it only uses the last declaration of quantity when dealing with the link. Therefore there must be a separator that can be used to distinguish between line items.
What is the separator that would go between each line items addition to the query string please? What goes after?
add?id[]=16220586868785&quantity[]=3**HERE**
I have tried using a , but admittedly this looks out of place followed by an &.
Edit
To help describe further what I have tried.
I am able to use the format ID:quantity if I:
want to go straight to checkout, the format is ID:quantity,ID:quantity.. so on.
only wish to add one item of a certain quantity to cart using add?ID:Quantity.
I need to know how to chain multiple to only add to cart. I don't know the separator (that is a comma when pushing straight to checkout).

Using permalinks to re-order things is always the ID:quantity. Have you tried that?

I would consider implementing this using jquery or javascript. You can create an ajax post using the cart/add.js call described here: https://help.shopify.com/en/themes/development/getting-started/using-ajax-api#add-to-cart

Related

Use variable and filter within tag in nunjucks + eleventy

I am a nunjucks newbie - trying it out along with eleventy.
Short version: can I use variables and filters within tags in nunjucks? For example:
{% set myVar = {{ title | lower }} %}
(assume the {{ title }} variable is set correctly)
Longer version / my specific use case:
I am trying to create a layout file called section.njk and use it for several pages (basically the section frontpages of each section of my site - similar idea to a section.html layout file in Hugo) I have a data file for each section, containing the menu for that section.
Given the following files:
guides.json
index.md with frontmatter including title: "Guides"
This does not work:
{% for item in {{ title | lower }} %}
<div>{{ item.title }}</div>
{% endfor %}
This works:
{% for item in guides %}
<div>{{ item.title }}</div>
{% endfor %}
So I'm wondering if the problem is using variables within tags in Nunjucks, and if so, if there's a way round it?
Entire project source is here: https://github.com/StarfallProjects/tech-writer-toolkit/tree/11ty (the 11ty stuff is in src)
Thanks for any help.
Yes, you can.
{% set myVar = title | lower %}
{% set myVar = title | lower + var2 | upper %}
{% set myVar = (title | lower + var2) | trim %}
...
{% for item in items | sort(false, true) %}
<div>{{ item.title | lower}}</div>
{% endfor %}
The lower, upper and trim filters are applyed to number/string vars. They can't be applyed for some array (or object).
On the another side, the sort-filter expects an array as input.
The filter "type" is obvious by its description in docs.

and/or on a where_exp expression on Jekyll

I'm trying to use where_exp to filter Jekyll pages based on two categories using or operator:
{% assign sortedPages = site.pages | sort:"date" | reverse | where_exp:"page","page.categories contains 'design-pattern'" %}
But I'm getting this error:
Expected end_of_string but found pipe
Ar or/and operators really supported? I can't figure out how to filter pages using where_exp as shown in my code snippet.
I've managed to solve my issue with some workarounds... It's not a very elegant solution, but as Jekyll isn't about creating actual software architecture... For now, it works flawlessly:
{% assign patterns = "" | split,"" %}
{% for page in site.pages %}
{% if page.categories contains "design-pattern" or page.categories contains "anti-pattern" %}
{% assign patterns = patterns | push:page %}
{% endif %}
{% endfor %}
{% assign sortedPages = patterns | sort:"date" | reverse %}
I create an empty array.
I loop over all pages and I filter them by two possible categories.
I push pages that fulfill the whole condition.
Once I get the filtered page array, I sort and reverse it.
I was unable to replicate the error message you included with your original question. However, as far as filtering based on multiple conditions goes, it is supported. You can also put all of your filters together. The result is much cleaner code 😊
Example
If one wants to set a variable named "sortedPages" equal to "site.pages", but with the following filters:
Sort by date
Sort in reverse order
Only include a page if it has design-pattern and/or anti-pattern as a category
they can do so with the following one-liner:
{% assign sortedPages = site.pages | sort:"date" | reverse | where_exp: "item", "item.categories contains 'design-pattern' or item.categories contains 'anti-pattern'" %}
Answer as multiple lines
Splitting up statements across multiple lines is also supported. Doing so can sometimes improve readability:
{%
assign sortedPages = site.pages
| sort:"date"
| reverse
| where_exp: "item", "item.categories contains 'design-pattern' or item.categories contains 'anti-pattern'"
%}

Jekyll: How to use for loop to generate table row within the same table inside markdown

I am trying to generate a table, based on the posts that I have. Now, the challenge here is that this is inside a markdown file, so for each row that I generate, liquid seems to generate a new table for each generated row. Is there a way to fit all rows inside one single table?
Here is my code:
|Title |Link |
|---|---|
{% for my_post in site.posts %}
{% if my_post.title %}
|{{ my_post.title }} |[Click Here]({{ my_post.url }}) |
{% endif %}
{% endfor %}
The generated output looks like this
As you can see, the outcome is actually a messed-up table header row + two separate tables. Can I really generate rows and fit them all inside one table? or am I better off switching to html code?
The liquid markup introduces line breaks in markdown.
Edit : you can now manage use whitespace control in Liquid
In Liquid, you can include a hyphen in your tag syntax {{-, -}}, {%-, and -%} to strip whitespace from the left or right side of a rendered tag.
|Title |Link |
|---|---|
{% for my_post in site.posts -%}
{% if my_post.title -%}
|{{ my_post.title }} |[Click Here]({{ my_post.url }}) |
{% endif %}
{%- endfor -%}
old answer
If you put your liquid tags on same line you'll have a valid table outputed.
| Title | Link |
|---|---|{% for my_post in site.posts %}{% if my_post.title %}
|{{ my_post.title }} |[Click Here]({{ my_post.url }}) |{% endif %}{% endfor %}

Business Catalyst Liquid sorting

I can see that Liquid allows you to sort a collection using the below syntax:
{% assign sorted_items = items.all|sort:'Email' %}
{% for item in sorted_items %}
<div>Name: {{item.name}}</div>
<div>Email: {{item.email}}</div>
{% endfor %}
However this does not appear to work in Business Catalyst.
If I use this to render the result to the page it simply renders "null".
{{sorted_items | json }}
Should I be able to do this in Business Catalyst, or am I completely wasting my time trying to find a solution to sort my WebApp data?
You can sort the data like this:
{module_data resource="customers" version="v3" fields="firstName,email1" collection="myData"}
<pre>{{myData|json}}</pre>
{% capture emails -%}
{% for item in myData.items -%}
,{{ item.email1.value }} - {{ item.firstName }};
{% endfor %}
{% endcapture %}
<pre>{{ emails | split: "," | sort }}</pre>
The comma is not spelling mistake : )
After you split the string in array you can do whatever you need to do with it.
The answer from Daut is not good. Any solution in the for loop will only sort the number of items fetched from the module and the max amount for that is 500.
If you are using module_data you just use its actual sort!
{module_data resource="customers" version="v3" order="firstName" fields="firstName,email1" collection="myData"}
module_data supports both WHERE for filtering and ORDER to order the results.

Create a filter list of items where a filter item appears only if there is a story for the product

I'm trying to figure out how to create a filter list where it grabs the product title from a _products directory and it will show the title in the list only if there is a story with the title of the product.
I have a _products list with 11 items and I can show them all, but I want to remove an item from the list of filter items if it's title != a element in the front matter of a list of stories in a separate directory.
{% assign product = site.products %}
{% for product in site.products %}
{% for success in site.success-stories %}
{% if product.title == success.product %}
<li><p class="filter label label-default" data-filter=".{{product.title | downcase}}">{{product.title}}</p></li>
{% endif %}
{% endfor %}
{% endfor %}
What this does is shows only the items that have a matching success-story but if there are multiple stories with the same product in it's front matter it will show that product more than once.
I've got the filtering down, it's just showing the items I can't get down.
Thanks!
I have a feeling you are looking for the contains filter.
Taken directly from the Liquid for Designers wiki:
# array = 1,2,3
{% if array contains 2 %}
array includes 2
{% endif %}
In your case, I'm guessing you want:
{% assign product = site.products %}
{% assign successfulProducts = site.success-stories | map: 'product' %}
{% for product in site.products %}
{% if successfulProducts contains product.title %}
... {{ product }} ...
{% endif %}
{% endfor %}
All I've done here in line 2 is mapping success-stories to successfulProducts. Essentially each story element is replaced by its story.product property.
Then I loop through all the products like you and check each one if it should be displayed. But I don't loop through all the stories - instead I put a simple condition that checks if successfulProducts contains the product title, just as you specified.

Resources