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

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 %}

Related

Shopify linking product using SEO handle coding

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.

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>

Jekyll -- number of posts by custom yml tags

I am working on a jekyll / gh-pages site. I'd like to build a side bar that lists the number of posts according to a CUSTOM tag. So i can sort posts using different yml elements. It works just fine using the tags yml element and this code
<h3>Activities By Topic</h3>
{% for tag in site.tags %}
{% assign t = tag | first %}
{% for atag in site.data.tags %}
{% if atag.slug == t %}
<h5><a href="{{ site.baseurl }}/{{ atag.slug }}">{{ atag.name }}
{% endif %}
{% endfor %}
({{ tag | last | size }})
</a></h5>
{% endfor %}
But what i'd like is another block that is "Activities by Type" (we are trying to sort posts in different ways. I setup a topic-tag yml element and a `topic-tag.yml file'
_data folder
https://github.com/lwasser/data-lesson-catalog/blob/gh-pages/_data/topic-tags.yml
org folder:
https://github.com/lwasser/data-lesson-catalog/tree/gh-pages/org/topic-tag
sample post:
https://github.com/lwasser/data-lesson-catalog/edit/gh-pages/_posts/lessons/2015-09-10_dc-R.md
relevant YML from sample post
---
layout: post
catalog-entry-type: lesson
title: Data Carpentry R for Ecology
topic-tag: ["Analysis", "Vizualization"]
---
Code that is not working:
<h3>Data Activities By Topic Tag</h3>
{% for tag in site.topic-tag %}
{% assign t = tag | first %}
{% for atag in site.data.topic-tags %}
{% if atag.slug == t %}
<h5><a href="{{ site.baseurl }}/{{ atag.slug }}">{{ atag.name }}</h5>
{% endif %}
{% endfor %}
({{ tag | last | size }})
{% endfor %}
Can i sort posts by other tags (not just the tags yml element)?
The output that i'd like is something like:
Analysis (2)
Visualization (3)
If so, any suggestions as to why the code above doesn't work? I found another post on here asking something similar but the resolution was to use the yaml "tags"element which will not work for my use case.
Many thanks,
Leah
You can use categories. They are working just like tags and can be another way to sort posts.
Hi to anyone who is struggling with this same thing. This is what i've learned.
Tags and categories are built into the jekyll build. You can thus call site.tags or site.categories without adding anything to your config file. Other custom tags that you create like topic-tags, are not inherently understood by jekyl as variables that can be called at the site level. My work-around -- use a counter to count posts by custom variable. the code looks like this
{% for member in site.data.topic-tags %}
{% assign counter = 0 %}
<!-- this code counts the number of posts associated with the member -->
{% for post in site.posts %}
{% if post.topic-tag contains member.slug %}
{% assign counter = counter | plus: 1 %}
{% endif %}
{% endfor %}
<h5><a href="{{ site.baseurl }}/topic-tag/{{ member.slug }}">{{ member.name }} ({{ counter }})</h5>
{% endfor %}
This works like a charm albeit it is looking through all of the posts to see if it contains the member tag in the yaml.
I hope this helps someone!
Here the code I use to display number of post on each categories. You may change site.categories to site.tags to display them by tags.
<h2 class="question">Topics ({{ site.posts | size }} total)</h2>
<ul class="topics">
{% capture tags %}
{% for tag in site.categories %}
{{ tag[0] }}
{% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}
{% for tag in sortedtags %}
<li class="topic-header"><b>{{ tag }} ({{ site.categories[tag] | size }} topics)</b>
<ul class='subnavlist'>
{% for post in site.categories[tag] %}
<li class='recipe'>
{{ post.title }}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
Check it on action here.

Jekyll post counts specific to custom front matter

I spent the last several hours scouring the depths of stackoverflow along with other amazing Jekyll tutorial sites, and have yet to find a solution to this particular issue. =[
Instead of using site.tags or site.categories, I created my own custom label named "subcategories" under the category 'blog'. The goal is to try to get a post-count for each. The tutorials I've found have worked for both categories AND tags perfectly, just not custom front matter.
Some of my subcategories are written like this:
[design]
[gaming]
[design, gaming]
I'm looking for a code that will increment the post count by 1 as it realizes there's a post that contains the subcategory. Since I am not using a plugin, the complete list of subcategories are actually listed separately in a data .yml file (in addition to start of my posts).
Here is one of my many pitiful attempts at writing this:
<ul class="blog__sidebar__subcategories m-t-s">
{% for subcategory in site.data.subcategories %}
<a class="blog__sidebar__subcategories__item" href="{{ site.baseurl }}/blog/{{ subcategory.class }}">
<li>{{ subcategory.class }}
{% assign counter = '0' %}
{% assign subcat_data == site.data.subcategories %}
{% for post in site.categories.blog %}
{% if subcat_data == post.subcategories %}
{% capture counter %}{{ counter | plus: '1' }}{% endcapture %}
{% endif %}
{% endfor %}
({{ counter }})
</li>
</a>
{% endfor %}
</ul>
Problems I've found include the output having constant duplicates, or spitting out "design,gaming" as one entity. This results in things like:
design | 6
gamingdesign | 6
gaming | 6
gaming | 6
Here's how my .yml file looks (simple):
- class: design
- class: gaming
And my code prior to attempting to add a post count (which worked!):
<ul class="blog__sidebar__subcategories m-t-s">
{% for subcategory in site.data.subcategories %}
<a class="blog__sidebar__subcategories__item" href="{{ site.baseurl }}/blog/{{ subcategory.class }}">
<li>{{ subcategory.class }}</li>
</a>
{% endfor %}
</ul>
Also please let me know if I accidentally violated any social etiquette of stackoverflow. First time posting! Thank you a million.
Jekyll is not playing well with user arrays. I think you'd better stick to Jekyll's existing mechanisms.
So, you can use tags for subcategories.
---
layout: post
date: 2014-08-14 07:51:24 +02:00
title: Your title
categories: [ blog ]
tags:
- design
- gaming
---
And your loop can be
{% for tag in site.tags %}
{% comment %}+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tag = Array [
"design",
Array [
#Jekyll:Post #id="/blog/1993/02/08/index",
#Jekyll:Post #id="/blog/1991/08/14/index"
]
]
Values in this tag array are :
- tag[0] -> "design"
- tag[1] -> an Array of posts that have the design tag
Here, we can already do a "{{ tag [0] }} : {{ tag[1] | size }}"
that will give us the count for each tag's posts array.
But if one post insn't in "blog" category but has a tag used
in the "blog" category, it will be counted here.
Where must count only posts that are in the "blog" category.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++{% endcomment %}
{% assign counter = 0 %}
{% for post in tag[1] %}
{% if post.categories contains "blog" %}
{% assign counter = counter | plus: 1 %}
{% endif %}
{% endfor %}
{% comment %}+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Only print counter if the current tag has "blog" posts
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++{% endcomment %}
{% if counter > 0 %}
<p>{{ tag[0] }} : {{ counter }}</p>
{% endif %}
{% endfor %}

How do you support per-page sidebar content in Zotonic?

I would like to have per-page sidebar content in Zotonic:
Links
White papers
Webinars
What is a good way to do this and what kind of template snippets would I need to make it work?
Log into the Zotonic admin interface.
Create Predicates:
Links (text->text)
White papers (text->document)
Webinars (text->text)
These predicates then show up in Page Connections in the Page editor. Add Links to other pages, links to White papers and links to Webinar pages in this way.
Add the following to _article_sidebar.tpl:
{% with m.rsc[id].links as texts %}
{% if texts %}
<h2>See also:</h2>
<ul>
{% for text in texts %}
<li><a href="{{ m.rsc[text].page_url }}" {% ifequal text id %}class="current"{% endifequal %}>{{ m.rsc[text].title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% with m.rsc[id].white_papers as texts %}
{% if texts %}
<h2>White papers:</h2>
<ul>
{% for text in texts %}
<li><a href="{{ m.rsc[text].page_url }}" {% ifequal text id %}class="current"{% endifequal %}>{{ m.rsc[text].title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% with m.rsc[id].webinars as texts %}
{% if texts %}
<h2>Related webinars:</h2>
<ul>
{% for text in texts %}
<li><a href="{{ m.rsc[text].page_url }}" {% ifequal text id %}class="current"{% endifequal %}>{{ m.rsc[text].title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
When you add a Predicate it lets you add metadata to your RSCs (Pages, Media, etc.) in Zotonic. Each Predicate allows you to connect a collection of RSCs to a RSC in the Zotonic interface. This collection is stored and accessed as IDs of RSCs.
Predicate metadata are then accessible within templates. The expression m.rsc[id].links selects the collection of IDs of RSCs connected to the current page as Links.
The expression m.rsc[id] selects the RSC for the page being rendered. The expression m.rsc[text] selects the RSC for a onnected RSC.
The expression {% ifequal text id %}class="current"{% endifequal %} conditionally renders a CSS class attribute that alters the link style to indicate that it is the current page.