Shopify linking product using SEO handle coding - encoding

I followed the directions for the second way to tag a product to a blog
This is the website I used https://happypoints.io/shopify-add-products-to-blog-post-c2-stt-66/ This is the code that was entered {% assign my_description = article.content | split: '=== split content ===' %}
{% assign my_description_size = my_description.size | minus: 2 %}
{{ my_description | first}}
<div class="show-product-list">
{% if article.tags.size > 0 %}
{% for tag in article.tags %}
{% paginate collections.all.products by 100 %}
{%- for product in collections.all.products -%}
{% if product.handle == tag %}
<div class="product_item">
{% include 'product-card-list' %}
</div>
{% endif %}
{%- endfor -%}
{% endpaginate %}
{% endfor %}
{% endif %}
</div>
{{ my_description | last}}
after following all the directions I received an error message saying
Liquid error (sections/article-template.liquid line 42): Could not find asset snippets/product-card-list.liquid
I am not sure why the product wont link to the blog using the seo handle. I have copied and pasted this code correctly and still getting this error
Collection code:
{% if collection.title == blank %}
{% assign collection_image = blank %}
{% elsif collection.image %}
{% assign collection_image = collection.image %}
{% else %}
{% assign collection_image = collection.products.first.featured_media.preview_image %}
{% endif %}
{% unless collection.title == blank %}
{% include 'card-image', type: collection_image, grid_style: grid_style %}
{% else %}
<div class="card__image-wrapper">
{% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %}
{{ 'collection-' | append: current | placeholder_svg_tag: 'placeholder-svg' }}
</div>
{% endunless %}
<div class="card__info">
<h3 class="card__name h4">{% if collection.title != blank %}{{ collection.title }}{% else %}{{ 'homepage.onboarding.collection_title' | t }}{% endif %}</h3>
{% if section.settings.show_description and collection.description != blank %}
<div class="rte card__description{% if width == '2' %} card__description--padding{% endif %}">
{{ collection.description | strip_html | truncatewords: 15 }}
</div>
{% endif %}
</div>

You have correctly copy/pasted the code.
The problem is that your theme does not have a file named "product-card-list" in the snippets folder.
This is the file which contains code for the product tiles on the collection pages and the name for this file might differ in the theme that you're using.
You will need to find out the correct file name and replace "product-card-list" with that.
Can help you further if you share the code in your collection.liquid file.

Related

How to display tags in jekyll and get the tag to click through to all relevant collection posts

I am looking to display all the tags from my collection posts in a sidebar, and have each tag click through to all the relevant posts. I would also like to display the number of times the tag has been used like this:
tag_name (10)
This is what I have currently which has got all the tags as a list but I cant figure out how to get the tag to click through to all relevant pages and also display the size.
<ul class="">
{% assign tags = site.vacancies | map: 'tags' | join: ',' | split: ',' | uniq %}
{% for tag in tags %}
<li class="text-capitalize">
{{ tag }}
</li>
{% endfor %}
</ul>
First, retrieve all tags into an list by using site.tags provide by Jekyll Variables
{% capture site_tags %}{% for tag in site.tags %}{{ tag | first }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
{% assign tags_list = site_tags | split:',' | sort_natural %}
Secondly, get a link for each Tag with its post count correspondingly
<ul>
{% for item in (0..site.tags.size) %}{% unless forloop.last %}
{% capture this_word %}{{ tags_list[item] | strip_newlines }}{% endcapture %}
<li><span class="tag-name">{{ this_word }}</span> <span class="count">{{ site.tags[this_word].size }}</span></li>
{% endunless %}{% endfor %}
</ul>
Thirdly, show each tag's name and its posts' name and date.
{% for item in (0..site.tags.size) %}{% unless forloop.last %}
{% capture this_word %}{{ tags_list[item] | strip_newlines }}{% endcapture %}
<article id="{{ this_word }}">
<h2 class="tag-heading tag-name">{{ this_word }}</h2>
<ul>
{% for post in site.tags[this_word] %}{% if post.title != null %}
<li><a href="{{ site.url }}{{ post.url }}" title="{{ post.title }}" >{{ post.date | date: '%m/%d/%Y' }} ---- {{ post.title }}</a></li>
{% endif %}{% endfor %}
</ul>
</article>
{% endunless %}{% endfor %}
So there's a way to do it by creating an array of tags while iterating through posts in the collection and using lots of liquid... and I decided to do my own workaround.
I have a master list of all the tags that I use stored in /_data/tagList.yml. Each tag has a name and slug, and you can add more fields like a description if you want to. I iterate through the data in tagList, and for each tag have a link to a dedicated page that lists all the posts that contain that tag.
If you followed the Jekyll docs and used tags in the front matter and you are consistent in naming your tags, then you can use the site.tags[tag.name] | size filter to get a count on how many posts have that tag.
Drawbacks of this workaround are:
you need to update tagList.yml any time you make a new tag
you need to make a new page for that tag (not a big deal since you can just copy/paste code from other tag pages and just change the tag you're looking for)
you need to ensure you are consistent in naming and using tags
// /_data/tagList.yml
- name: Coding
slug: coding
- name: UnpopularOpinion
slug: unpopular-opinion
// /_posts/2019-01-01-example.html
---
tags: [Coding, UnpopularOpinion]
---
// /blog/tags.html
{% for tag in site.data.tagList %}
<div>
<h2>{{tag.name}}</h2>
{% assign postCount = site.tags[tag.name] | size %}
<em>
{% if postCount == 1 %}
{{postCount}} post
{% else %}
{{postCount}} posts
{% endif %}
</em>
</div>
{% endfor %}
// /blog/tags/coding.html
{% assign numPosts = site.tags.Coding | size %}
{% if numPosts == 0 %}
<p>No posts have this tag...yet.</p>
{% endif %}
{% for post in site.tags.Coding %}
...code to display a post...
{% endfor %}

Tag count automatically changing while clicking on the product tag

I am using Shopify. I am in collection page where I am getting all the filter with tag count something like,
All Products
Apple(4)
Banana(2)
Orange(1)
Mango(8)
Now when I click on any of the tag(For example I clicked on Banana) then It will display the banana products.
Now my issue is by clicking on the tag it's changing the tag count.
All Products
Apple(0)
Banana(2)
Orange(0)
Mango(4)
I am using below code
{% 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 %}
<a class="filter__link" href="/collections/{% if collection.handle != blank %}{{ collection.handle }}{% else %}all{% endif %}/{{ tag | handleize }}"{% if current_tags contains tag %} selected="selected" id="tag_active"{% endif %}>{{ tag }} ({{products_count }})</a>
{% endfor %}
Thanks in advance.
It looks like the step you're missing is the first line here:
{% assign collection = collections.all %}
You're iterating over the current collection, so as you've noticed when you click on a tag the results change.
If you don't have a collection with the handle all, you can create one by following this process:
Go to Products > Collections.
Click Add a collection.
Create the collection:
Give your collection the Title All.
In the Conditions section, select "Automatically select products based on conditions".
Set the product condition "Product price is greater than $0".
Save
Edit:
This fixes the issue where the product count changes when you click on a tag link:
{% for tag in collection.all_tags %}
{% assign products_count = 0 %}
{% for product in collections[collection.handle].products %}
{% if product.tags contains tag %}
{% assign products_count = products_count | plus: 1 %}
{% endif %}
{% endfor %}
<a class="filter__link" href="/collections/{% if collection.handle != blank %}{{ collection.handle }}{% else %}all{% endif %}/{{ tag | handleize }}"{% if current_tags contains tag %} selected="selected" id="tag_active"{% endif %}>{{ tag }} ({{products_count }})</a>
{% endfor %}
The key part is:
{% for product in collections[collection.handle].products %}
It looks like when you're filtering by tag with a URL like collections/collection_1/tag_1 then collection.products is also filtered by the selected tag. The line above looks a bit messy, but it appears to return the full set of products.
As I was saying in comment, the issue comes from your secondary loop:
{% for product in collection.products %}
Which accesses only to the current view and not the full collection products.
I've not tested it but I guess it worthes a try:
{% assign whole_collection = collections[collection.handle] %}
{% for product in whole_collection.products %}
{% if product.tags contains tag %}
{% assign products_count = products_count | plus: 1 %}
{% endif %}
{% endfor %}
Explanation, a code like this {{ collections['the-handle'].url }} allows access to any specific collection and its attributes.
HTH
Memo : this won't work accurately if your collection has more than 50 items.

Jekyll case-insensitive sorting

I'm trying to create a tags list in Jekyll. Some of the tags are "accessibility", "CSS", and "JavaScript". So my Jekyll code to create the list looks like this:
<ul>
{% for item in (0..site.tags.size) %}{% unless forloop.last %}
{% capture this_word %}{{ tag_words[item] }}{% endcapture %}
<li>
<a href="#{{ this_word | cgi_escape }}" class="tag">{{ this_word }}
<span>({{ site.tags[this_word].size }})</span>
</a>
</li>
{% endunless %}{% endfor %}
</ul>
However, the rending of the list isn't alphabetical. It's first case-sensitive, capital words first; so my example tags above are rendered in this order:
CSS
JavaScript
accessibility
Is there a way to make the sorted list case-insensitive?
There is a sort_natural filter in liquid, but it doesn't work with site.tags.
The trick is to generate an array with all tags names
{% comment %} Creates an empty array {% endcomment %}
{% assign tags = "" | split:"" %}
{% comment %}Creates an array of tags names{% endcomment %}
{% for t in site.tags %}
{% assign tags = tags | push: t[0] %}
{% endfor %}
Sort them naturally (case insensitive)
{% assign sorted_tags = tags | sort_natural %}
Based on this sort, print tags counts
<ul>
{% for t in sorted_tags %}
<li>{{ t }} : {{ site.tags[t].size }}</li>
{% endfor %}
</ul>
This becomes more complex once you have to find a post by its name. Here's a solution to sort posts in an archive list alphabetically:
{% assign post_names = "" | split:"" %}
{% for post in tag.last %}
{% assign post_names = post_names | push: post.title %}
{% endfor %}
{% assign sorted_post_names = post_names | sort_natural %}
{% for post_name in sorted_post_names %}
{% assign matched_post = site.posts | where:"title",post_name %}
{% assign post = matched_post[0] %}
…
{% endfor %}
The trick is to find the post with where from the overall list of posts.
It seems that the mentioned issue of sort_natural filter has been fixed. You may try to use it directly:
<ul>
{% for t in site.tags sort_natural %}
<li>{{ t }} : {{ site.tags[t].size }}</li>
{% endfor %}
</ul>

IvoryCKEditorBundle Symfony: How to use "ckeditor_widget" from IvoryCKEditorBundle TWIG template in my OWN redefined TWIG template

I've implemented IvoryCKEditorBundle in my SYMFONY 3.2 project.
I followed the guidelines from here and had an overview of the doc on the official Symfony site.
Now I see the following files exits in the IvoryCKEditorBundle directory:
[my
project]\vendor\egoloen\ckeditor-bundle\Resources\views\Form\ckeditor_widget.html.twig
[my
project]\vendor\egoloen\ckeditor-bundle\Twig\CKEditorExtension.php
And [my
project]\vendor\egoloen\ckeditor-bundle\Resources\views\Form\ckeditor_widget.html.twig defines {% block ckeditor_widget %}.
In my projet I have redefined my own template to render a form, using all the tricks given in the official doc. And under [my project]\src\MyBundle\Resources\views I have a file input_inline_template.html.twig which looks like that:
{% extends 'form_div_layout.html.twig' %}
{% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %}
{% block form_row %}
<div class='col-12' id={{ id ~ '_div_row_id'}}>
{% block form_label %}
<div class='col-4' id={{ id ~ '_div_label_id' }}>
{{ parent() }}
</div>
{% endblock %}
{% if form.vars.block_prefixes.2 == "textarea" %}
{% if (form.vars.block_prefixes.3 is defined) and (form.vars.block_prefixes.3 == "ckeditor") %}
{% block ckeditor_widget %}
<div class='col-8'>
{{ parent() }}
</div>
{% endblock %}
{% else %}
{% block textarea_widget %}
<div class='col-8'>
{{ parent() }}
</div>
{% endblock %}
{% endif %}
{% endif %}
</div>
{% endblock %}
This does not work. It tells me that it cannot find the ckeditor_widget if I don't have the line {% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %} it throws the error:
Block "ckeditor_widget" on template "form_div_layout.html.twig" does not exist in "form_div_layout.html.twig".
And when the line {% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %} is implemented, it throws an error that is:
Unable to find template "CKEditorBundle:Form:ckeditor_widget.html.twig"
It tells me it looks for CKEditorBundle:Form:ckeditor_widget.html.twig in:
[my_symf_project]\app/Resources/views, [my_symf_project]\vendor\symfony\symfony\src\Symfony\Bridge\Twig/Resources/views/Form, [my_symf_project]\vendor\knplabs\knp-menu\src\Knp\Menu/Resources/views.
I don't know how to configure in [my project]\app\config\config.yml that it should look in [my project]\vendor\egoloen\ckeditor-bundle\Resources\views\Form\ to find ckeditor_widget.html.twig.
I found a hint here.
In [my project]\src\MyBundle\Resources\views\input_inline_template.html.twig, I've replaced: {% use 'CKEditorBundle:Form:ckeditor_widget.html.twig' %} with: {% use 'IvoryCKEditorBundle:Form:ckeditor_widget.html.twig' %}.
It fixed it.

Passing a macro argument to an if == test in jinja?

I'm using Tarbell to publish a formatted version of an inventory spreadsheet. Every row has a category, so I can do something like this:
<h2>Power Tools</h2>
{% for row in inventory %}
{% if row.Category == "powertools" %}
<b>{{ row.Display_Name|e }}</b> <br />
{% endif %}
{% endfor %}
<h2>A/V Gear</h2>
{% for row in inventory %}
{% if row.Category == "av" %}
<b>{{ row.Display_Name|e }}</b><br />
{% endif %}
{% endfor %}
To get a list of all the power tools followed by a list of A/V gear. I'd like to move that into a macro that I can call with a couple of arguments. I've got this:
{% macro list(cat, title='') -%}
<p>Category: {{ cat }}; Header: {{ title }}</p>
{% for row in inventory %}
{% if row.Category == "{{ cat }}" %}
<b>{{ row.Display_Name|e }}</b><br />
{% endif %}
{% endfor %}
{%- endmacro %}
When I call it with:
{{ list('av', title='Cameras and Audio Recorders')}}
{{ list('powertools', title='Power Tools')}}
I see "Category: powertools; Header: Power Tools" and "Category: av; Header: Cameras and Audio Recorders" as expected, so I know the macro can hear me, but the list itself doesn't show up. Can I use a macro argument in a comparison test? How?
There is no need for variable interpolation syntax inside of a block - you can just refer to the variable by name as you would in Python:
{# Do this #}
{% if row.Category == cat %}
{# Instead of this #}
{% if row.Category == "{{ cat }}" %}