How do I shorten this liquid code? - shopify

I want to update the "New Order Notification" mail for my Shopify store with custom HTML code, but while pasting the code it simply doesn't paste 100% of it. I've contacted Shopify and they've told me there is no character limit but a file size limit of 64 or 128 kb.
The store has 18 main categories (collections). What I'm trying to do is make sure the products get sorted based on category name.
The following piece of code appears 18 times (for every category) in the custom template:
{% if verse_kantenklaar_maaltijden_salades != blank %}
<tr>
<td colspan="2">
<h2 style="margin-bottom:15px;margin-top:5px!important;font-weight:bold;">Verse kant-en-klaar maaltijden - salades</h2>
</td>
</tr>
{% for line_item_id in verse_kantenklaar_maaltijden_salades %}
{% for line_item in line_items %}
{% capture line_item_string %}{{line_item.id}}{% endcapture %}
{% if line_item_id == line_item_string %}
{% assign bonus = 'no' %}
{% for tag in line_item.product.tags %}
{% if tag == 'Bonus' %}
{% assign bonus = 'yes' %}
{% endif %}
{% endfor %}
<tr>
<td>
<img alt="" src="{{ line_item.product.featured_image | product_img_url: 'large' }}" style="width: 400px;">
</td>
<td style="text-align:left;">{{ line_item.title }} ({{ line_item.product.metafields.global.item_size }})<br>
<span style="font-size:34px;font-weight:bold;">
{% if bonus == 'yes' %}
{{ line_item.product.metafields.global.wpob | round: 2 }}
{% else %}
{{ line_item.product.metafields.global.wpo | round: 2 }}
{% endif %}
</span>
{% if bonus == 'yes' %}
<span style="font-size:18px;font-weight:bold;">BONUS</span>
{% endif %}
{% if line_item.quantity > 1 %}<span class="item_count" style="display: block;position: relative;width: 50px;text-align: center;background-color: #d14836;color: white;font-weight: 700;min-width: 80px;line-height: 40px;border-radius: 50px;">{{ line_item.quantity }}</span>{% endif %}
</td>
</tr>
{%endif%}
{% endfor %}
{% endfor %}
{% endif %}
For the full code (with 3 categories) take a look at this gist.
Is there a way to simplify (using loops) or compress this to make sure the total template stays within Shopify limits?
Or might this be caused by something else? The total code length is around 1500 lines.

For anyone interested, here's the more efficient version (thanks to Evulse):
{% assign sort_array = "" %}
{% for line_item in cart.items %}
{% for tag in line_item.product.tags %}
{% if tag == 'Tag I want second' %}
{% assign sort_array = sort_array | append: 'B:' | append: line_item.id | append: ',' %}
{% endif %}
{% if tag == 'Tag I want First' %}
{% assign sort_array = sort_array | append: 'A:' | append: line_item.id | append: ',' %}
{% endif %}
{% if tag == 'Tag I want Third' %}
{% assign sort_array = sort_array | append: 'C:' | append: line_item.id | append: ',' %}
{% endif %}
{% endfor %}
{% endfor %}
{% assign sort_array = sort_array | split: ',' | sort %}
{% for prefixed_line_item_id in sort_array %}
{% for line_item in cart.items %}
{% capture line_item_string %}{{line_item.id}}{% endcapture %}
{% assign line_item_id = prefixed_line_item_id | split: ':' | last %}
{% if line_item_id == line_item_string %}
{{line_item.product.title}}
{%endif%}
{% endfor %}
{% endfor %}

Related

Adding custom data in shopify order confirmation

I'm currently trying to find away to pass some custom data to each one of my shopify order confirmations. Specifically I need to pass a custom URL that will be displayed in the order confirmation email. According to the shopify documentation I can receive a property from a product and pass it to my confirmation form like so.
{% assign property_size = item.properties | size %}
{% if property_size > 0 %}
{% for p in item.properties %}
{% assign first_character_in_key = p.first | truncate: 1, '' %}
{% unless p.last == blank or first_character_in_key == '_' %}
{{ p.first }}:
{% if p.last contains '/uploads/' %}
<a class="lightbox" href="{{ p.last }}">{{ p.last | split: '/' | last }}</a>
{% else %}
{{ p.last }}
{% endif %}
<br>
{% endunless %}
{% endfor %}
{% endif %}
Using this I figure I can pass a custom url by doing something like this:
mycustomurl.com/linepropertyitem
My problem is that each line property includes the tittle of the line property item and the input value. So my url using this method would be
mycustomurl.com/linepropertyitem = linepropertyitemtext
Any ideas or pointers how this can be done?
which wouldn't work in a URL.
You could do it like this:
{% assign property_size = item.properties | size %}
{% if property_size > 0 %}
{% for p in item.properties %}
{% assign first_character_in_key = p.first | truncate: 1, '' %}
{% unless p.last == blank or first_character_in_key == '_' %}
{% if p.last contains '/uploads/' %}
<a class="lightbox" href="{{ p.last }}">{{ p.last | split: '/' | last }}</a>
{% else %}
{{ p.first }}:
{{ p.last }}
{% endif %}
<br>
{% endunless %}
{% endfor %}
{% endif %}
But the best thing you could do would be to analyze the code from Shopify and understand what is going on. That way you'll be able to do a lot more on your own.

forloop img src is /no-image

Trying to pull images into a into a wrapper after assigning a specific collection but my images are all returning - //cdn.shopify.com/s/assets/no-image
<div id="NewColorOptions" class="color-select">
{% assign color_options = '' %}
{% for collection in collections %}
{% if product.handle contains collection.handle %}
{% assign collection = collection.handle %}
{% for p in collection.products %}
{% assign p_handle = '--' | append: p.handle | append: '--' %}
{% if color_options contains p_handle %}
{% comment %} Probably Duplicates {% endcomment %}
{% else %}
{% assign color_options = color_options | append: p_handle %}
{% assign product_text = p.title | handleize | remove : collection.handle | replace : '-', ' ' %}
<a href="{{ p.url }}" datattitle="{{ product_text | textilize | upcase }}" {% if p.url contains product.handle %}class="ActiveThumb"{%endif%}>
<img {% if forloop.first == true %} class="imgOne" {% endif %} src="{{ image.src | product_img_url: 'compact' }}">
</a>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
I assume my error is within my <img> tag but I'm not sure why that would be breaking.

Shopify - get unique articles based off current article's tags

What I'm trying to accomplish is when a user is on an individual blog article/post, I want to display unique "related articles" based off of matching tags.
Here's what I have so far:
{% for tag in article.tags %}
{% assign counter = 0 %}
{% for article in blog.articles %}
{% if article.tags contains tag and counter < 2 %}
{% assign counter = counter | plus: 1 %}
<li class="well">
{% if article.excerpt.size > 0 %}
<div class="thumb-article">
<a href="{{ article.url }}">
{{ article.excerpt }}
</a>
</div>
{% endif %}
<h3>{{ article.title }}</h3>
<p>{{ article.content | strip_html | strip_newlines | truncatewords: 40 }}</p>
</li>
{% endif %}
{% endfor %}
{% endfor %}
Surprisingly, (to me since this is my first experience with Shopify and liquid) it works, just a little too well as it gets duplicate posts.
Is there some way I can keep it from getting duplicate articles?
For those who also searching how to implement related blog posts to a blog not product like in the links provided, there is the fix for code above:
...
{% assign skip_articles = article.handle | split: '.....' %}
...
{% for ...
{% if ...
{% unless skip_articles contains related_article.handle %}
...
{% assign temp = related_article.handle | split: '.....' %}
{% assign skip_articles = skip_articles | concat: temp %}
...
split by anything you wouldn't find in handle to create array
ending up with something like this:
<div class='relatedArticles'>
{% for tag in article.tags %}
{% assign counter = 0 %}
{% assign skip_articles = article.handle | split: '.....' %}
{% for related_article in blog.articles %}
{% if related_article.tags contains tag and counter < 6 %}
{% unless skip_articles contains related_article.handle %}
{% assign counter = counter | plus: 1 %}
{% assign temp = related_article.handle | split: '.....' %}
{% assign skip_articles = skip_articles | concat: temp %}
<div class="well">
<h3>{{ related_article.title }}</h3>
{% if related_article.excerpt.size > 0 %}
<p>{{ related_article.excerpt }}</p>
{% else %}
<p>{{ related_article.content | truncatewords: 40 }}</p>
{% endif %}
</div>
{% endunless %}
{% endif %}
{% endfor %}
{% endfor %}
</div>
This thread has what you need: Shopify liquid get related blog posts
It creates an empty related posts variable then defines it in a loop that looks through other posts of that same category. To repeat its answer:
{% assign related_posts = "" %}
{% for article in blogs.blog.articles %}
{% if article.tags contains product.handle %}
{% capture post %}
<li><p>{{ article.title }}</p></li>
{% endcapture %}
{% assign related_posts = related_posts | append:post %}
{% endif %}
{% endfor %}
{% if related_posts.size > 0 %}
<ul> {{ related_posts }} </ul>
{% else %}
No related posts!
{% endif %}
Go to that link above to see the full response.

shopify Liquid error: Memory limits exceeded

I was trying to display all the product types of my site in one page , 2 days back it was listing all the all the product type.
But now when that page is loads its giving error like "shopify Liquid error: Memory limits exceeded"
Here is my code
<div class="rte">
{{ page.content }}
<ul class="vendor-list block-grid three-up mobile one-up">
{% for product_type in shop.types %}
{% assign its_a_match = false %}
{% capture my_collection_handle %} {{ type | handleize | strip | escape }} {% endcapture %}
{% assign my_collection_handle_stripped = my_collection_handle | strip | escape %}
{% for collection in collections %}
{% if my_collection_handle_stripped == collection.handle %}
{% assign its_a_match = true %}
{% endif %}
{% endfor %}
{% if its_a_match %}
<li class="vendor-list-item">{{ product_type }}</li>
{% endif %}
{% endfor %}
</ul>
</div>
how can i overcome this problem ?
Try the following. It's faster and more efficient.
<div class="rte">
{{ page.content }}
<ul class="vendor-list block-grid three-up mobile one-up">
{% for product_type in shop.types %}
{% assign type = product_type | strip | escape | handleize %}
{% assign collection = collections[type] %}
{% if collection.handle != '' %}
<li class="vendor-list-item">{{ product_type }}</li>
{% endif %}
{% endfor %}
</ul>
</div>

Shopify Products count

im currently face this problem where by tag count show current view count which is corrent.
IMG
but when i click to individual tag, the number will add up together.
IMG
{% for tag in collection.all_tags %}
{% assign products_count = 0 %}
{% for product in collection.products %}
{% if product.tags contains tag %}
{% assign products_count = products_count | plus: 1 %}
{% endif %}
{% endfor %}
{% assign is_advanced_tag = false %}
{% assign cat = tag | split: '_' | first %}
{% unless cat == tag %}
{% if cat_array contains cat %}
{% assign is_advanced_tag = true %}
{% if current_tags contains tag %}
<li class="active-filter ">{{ tag | remove_first: cat | remove_first: '_' }}</li>
{% else %}
<li>{{ tag | remove_first: cat | remove_first: '_' | link_to_tag: tag }}</li>
{% endif %}
{% endif %}
{% endunless %}
{% if is_advanced_tag == false %}
{% if current_tags contains tag %}
<li class="active-filter ">
{{ tag }}({{ collection.products_count }})
</li>
{% else %}
<li>{{ tag | link_to_tag: tag }} ({{ collection.products_count }})</li>
{% endif %}
{% endif %}
{% endfor %}
is there any where to show the non current view of product count. thanks