If product tags contains - in shopify - ruby

So i'm basically trying to use the logic of shopify to show an image if the tags of the product contains the words "related"
(there is a json query that picks up the tags containing 'related-x' where x is the name of the product and it uses this to show the related products.)
Preceding the Json query is an image that says "related products" basically. what i would like to do is to only display this when there are "related" tags present.
I have tried this:
{% if product.tags contains 'related' %}
<img src="{{ 'complete-this-look.gif' | asset_url }}" alt="" align="left;" style="vertical-align:top; margin-right:8px; padding-top:0px;" width="130" height="175"/>
{% endif %}
Which doesnt display anything. I also tried:
{% for t in product.tags %}
{% if t contains 'related-' %}
<img src="{{ 'complete-this-look.gif' | asset_url }}" alt="" align="left;" style="vertical-align:top; margin-right:8px; padding-top:0px;" width="130" height="175"/>
{% endif %}
{% endfor %}
However this will display the image every time a related product is returned by the query.
What im after is for it to go (Image) (Query Results) - and if there is no query results then it displays nothing.
Any ideas?

The reason your first piece of code is not working is because contains is looking for a tag called 'related', not a tag containing the substring 'related'.
See the Shopify Wiki for contains where it states:
It can check for the presence of a string in another string, or it can check for the presence of a string in an array of simple strings.
In your instance, contains is checking for a string in an array of simple strings (and is looking for the whole string, not a string containing the specified string as a substring).
See also the Shopify wiki for product.tags:
Returns a list of the product's tags (represented by simple strings).
You can use the contains keyword with an array of simple strings, so
you can use this with a product's tags:
{% if product.tags contains 'custom to order' %}
<!-- Output custom to order form HTML here -->
{% endif %}
So, Gerard Westerhof's suggestion to use Join in the comment above is a good one. If you first join the product.tags array, then contains will search for the 'related' string inside the string of tags returned by join.
Try this:
{% if product.tags | join: ' ' contains 'related' %}
<img src="{{ 'complete-this-look.gif' | asset_url }}" alt="" align="left;" style="vertical-align:top; margin-right:8px; padding-top:0px;" width="130" height="175"/>
{% endif %}
EDIT:
Try this instead:
{% assign product_tags_string = product.tags | join: ' ' %}
{% if product_tags_string contains 'related' %}
<img src="{{ 'complete-this-look.gif' | asset_url }}" alt="" align="left;" style="vertical-align:top; margin-right:8px; padding-top:0px;" width="130" height="175"/>
{% endif %}

Related

Is it possible to create multiple "mj-column" using a for loop?

I would like something like below
{% for item in list %}
<mj-column>
{{ item }}
</mj-column>
{% endfor %}
But after giving it a try and convert to HTML via the official editor, the HTML file cannot find item.

How to apply correct filter to {{ current_tags }} to display tag names not tag slugs

I want to alter this code to display the text within the anchor in readable format. I wish to display the tags name or title but it is currently displaying the tags as slugs.
Here is the snippet:
<!-- Creates the link as a variable, which is in 'tag_slug+tag_slug' format -->
{%- capture tag_url -%}{{ collection.url }}/{{ current_tags | join: "+"}}{%- endcapture -%}
<!-- HELP ME display the text inside the anchor in 'tag_title + tag_title' format. It currently displays the text of the anchor in 'tag_slug + tag_slug' format which is not very readable -->
<a class="breadcrumbs__link" href="{{ tag_url }}" aria-current="page">{{ current_tags | join: " + "}}</a>
I have tried a handful of things but have been unsuccessful. One of which was:
{{ current_tags.title | join: " + " }}
What is the equivalent to current_tags.title in liquid?
Here is an example output of the link:
<a class="breadcrumbs__link" href="/collections/example/tag-one+tag-two" aria-current="page">tag-one + tag-two</a>
This would be much easier to follow as a user if it was:
<a class="breadcrumbs__link" href="/collections/example/tag-one+tag-two" aria-current="page">Tag one + Tag two</a>
Where the tags would not have spaces removed, and the first letter will be capitalised. One thing to consider is that some tags require the dash to remain if it is already present in the tag title. So replacing dashes for spaces will not work. It will just create another issue.
EDIT - Another method that does not work:
{%- capture tag_url -%}{{ collection.url }}/{{ current_tags | join: "+"}}{%- endcapture -%}
<a class="breadcrumbs__link" href="{{ tag_url }}" aria-current="page">
{% for tag in collection.all_tags %}
{% if current_tags contains tag %}
<div class="current-tag">{{ tag.title }}</div>
{% endif %}
{% endfor %}
</a>
EDIT 2 - Another failed attempt:
{% for tag in current_tags %}
<div class="current-tag">{{ tag.title }}</div>
{% endfor %}
This solution is not by the book. I have not been able to find any documentation on how to iterate through the current_tags, display the tags by their readable name & add a join value such as ' + '.
However I have managed to loop through the current tags, then use CSS to change their appearance to better suit the style we wished for. So again this is not the textbook way of acheiving this and the results will not be 100% correct all the time but it is a substantial improvement on the previous display.
This will take the value of for example 'balances-scales-accessories+bench-scales' and convert it into 'Balances Scales Accessories + Bench Scales'. The 100% answer would look a little more like 'Balances, Scales & Accessories + Bench Scales'.
Where this solution fails is:
The ',' and '&' characters are removed.
The '-' are removed when in very niche situations these are actually a desired character like in the word 'Semi-gloss'.
Liquid:
<!-- Generate link as previously achieved -->
{%- capture tag_url -%}{{ collection.url }}/{{ current_tags | join: "+"}}{%- endcapture -%}
<!-- Add generated link to anchor tag -->
<a class="breadcrumbs__link" href="{{ tag_url }}" aria-current="page">
<!-- Loop through tags present in current tags list -->
{% for tag in current_tags %}
<!-- Wrap echoed tag in a span so it is targetable, replace the dashes for spaces, and make the whole thing lowercase -->
<span class="breadcrumb-tag">{{ tag | replace: '-', ' ' | downcase }}</span>
{% endfor %}
</a>
CSS:
/* Capitalise first letter of each word of the breadcrumb */
.breadcrumbs__link .breadcrumb-tag {
text-transform: capitalize;
}
/* Add a before on each tag that is not the first, to display a '+' symbol indicating there are multiple tags selected */
.breadcrumbs__link .breadcrumb-tag + .breadcrumb-tag:before {
content: ' + ';
}
Again not perfect but will do until someone can create a more reliable solution in liquid.

How do I create a loop that display each category and its post count?

I have a blog that I built with Jekyll. On the side bar I want to include a nav bar that list each category along with total number of posts for each. This is what I have right now:
<h2>Post Categories</h2>
<nav>
{% for category in site.categories %}
<h3>{{ category }} ({{ category | size }})</h3>
{% endfor %}
</nav>
I'm not on my computer that has Ruby and Jekyll installed so I can't build the site locally. But is this something that will work?
From the Liquid docs for the size filter:
Size: Returns the number of characters in a string or the number of items in an array.
Here's a full listing of the available vars using Jekyll, including site.categories.
Instead of calling size on your category var itself, you need to call it on the last argument, which is where the array of posts are hiding:
<h2>Post Categories</h2>
<nav>
{% for category in site.categories %}
<h3>{{ category | first }} ({{ category | last | size }})</h3>
{% endfor %}
</nav>

Liquid - if contains statement not working in for loop

I have a very basic conditional inside a loop that isn't working:
{% for tag in collections.all.tags %}
<li class="mb-1 ">
<a class="text-white" title="{{ tag }}" href="#">
{{ tag | handle }}
{% if canonical_url contains tag | handle %}
active
{% endif %}
</a>
</li>
{% endfor %}
Right now, my tag | handle is "dodge" and if I print my {{ canonical_url }} I get https://localhost:3000/collections/all/dodge so my conditional should evaluate to truthy and print the word 'active'.
If I modify my statement to {% if canonical_url contains 'dodge' %} it works fine but I need it to be dynamic. Any suggestions?
Set the handle into a variable and use the variable for the comparison instead of the handle.
First You have to assign value of tag handle to shopify liquid variable & then you will be able to use variable in condition And then every thing will be working fine & dynamic. Thanks !!

An easy way to support tags in a jekyll blog

I am using the standard jekyll installation to maintain a blog, everything is going fine. Except I would really like to tag my posts.
I can tag a post using the YAML front matter, but how do I generate pages for each tag that can will list all posts for a tag?
Here is a solution with alphabetically sorted tags on a single page.
It uses Liquid only, which means that it works on GitHub Pages:
{% capture tags %}
{% for tag in site.tags %}
{{ tag[0] }}
{% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}
{% for tag in sortedtags %}
<h3 id="{{ tag }}">{{ tag }}</h3>
<ul>
{% for post in site.tags[tag] %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% endfor %}
You can see it in action here.
EDIT:
There's also a way to generate a separate page for each tag without plugins (which will work on GitHub Pages).
I have a more detailed explanation on my blog:
Separate pages per tag/category with Jekyll (without plugins)
First, you need a new layout file:
/_layouts/tagpage.html:
---
layout: default
---
<h1>{{ page.tag }}</h1>
<ul>
{% for post in site.tags[page.tag] %}
<li>
{{ post.date | date: "%B %d, %Y" }}: {{ post.title }}
</li>
{% endfor %}
</ul>
With this layout file, you can add a new tag page by adding a new file with just two lines of YAML front-matter.
Here's an example for the jekyll tag:
/tags/jekyll/index.html:
---
layout: tagpage
tag: jekyll
---
The only disadvantage of this approach: each time you use a new tag for the first time, you have to remember to create a new two-line file for it.
To generate the root index file (i.e. the list of tags that links to /tags/jekyll/index.html etc.), you can use a similar solution like the one on top of this answer where I generate a single page with alphebetically sorted tags:
{% capture tags %}
{% for tag in site.tags %}
{{ tag[0] }}
{% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}
{% for tag in sortedtags %}
{{ tag }}<br>
{% endfor %}
This will generate a list of links like this:
<ul>
<li>.net</li>
<li>authentication</li>
<li>backup</li>
</ul>
Note that this solution uses a blank to split tags, so it doesn't work when your tags contain blanks and Yevgeniy Brikman's comment applies here as well.
This gist will generate a page per category for you: https://gist.github.com/524748
It uses a Jekyll Generator plugin, plus a Page subclass.
Have a look at sites using jekyll. There are a few custom forks which have implemented tagging functionality, hopefully also in the way you want :-)
I had the same question, and stumbled upon this: http://gist.github.com/143571.
It's a rake task which generates a tag list. I modified it slightly, and my version is at:
http://github.com/mattfoster/mattfoster.github.com/blob/master/Rakefile.
Whilst this doesn't give you a page per tag, you can use anchors, which is half way there!
I use the great Jekyll Tagging plugin that automatically generates a tags cloud and tag pages. Easy to install and use.
Here is a page for the "photo" tag on my blog (in french), and you can see the tags cloud in the bottom.
Based on Christian's answer above I made a bash script that does what he described.
https://github.com/ObjectiveTruth/objectivetruth.github.io/blob/master/rebuild_tags.sh
Be sure to have the accompanying 14 line vim script in the /non_website_resources/ directory
AND
Make the /_layouts/tagpage.html shown in Christian's answer above but rename it to /_layouts/tag_pages.html
File structure should be like this:
.jekyll_website_root
├── _posts
├── _layout
│ ├── tag_pages.html
├── rebuild_tags.sh
Run from the root directory ./rebuild_tags.sh
If you get permission denied error be sure to run chmod 777 rebuild_tags.sh
If you look at scripts comments its fairly simple:
Uses sed to find all the tags in every .md file in _post directory
Uses sed to massage the data to proper format
Takes all the unique tags and makes a directory and a index.html for each
This way, if you have any new tags, just run the script to rebuild the pages before pushing to github
A nice simple non-plugin way to do tags
EDIT
Removed dependency on other files. Just need the one script!
I do these with CSS. First lists an element and use the tag name as its id.
<span id="{{ site.posts | map: 'tags' | uniq | join: '"></span><span id="' }}"></span>
And then lists all the post and use its tags as a value for the "tags" custom attribute.
{% for post in site.posts %}
<article class="post" tags="{% for tag in post.tags %}{{tag}}{% if forloop.last == false %}{{" "}}{% endif %}{% endfor %}">
<h3>{{post.title}}</h3>
</article>
{% endfor %}
And then in CSS, hide all the posts by default, and only show posts with tags matches the url id/ hash
.post {
display: none;
}
{% for tag in site.tags %}#{{tag[0]}}:target ~ [tags~={{tag[0]}}]{% if forloop.last == false %}, {% endif %}{% endfor %} {
display: block;
}
/*
The compiled version will look like this
#tagname:target ~ [tags~="tagname"], #tagname2:target ~ [tags~="tagname2"] {
display: block;
}
*/
I made an article about this here.

Resources