Downcase a liquid object - jekyll

i want to downcase Liquid-object in Jekyll:
{{ page.tags | downcase }}
{{ page.tags | downcase }} doesn't work. Do you have an idea?
Thanks!

If you want to print a list of downcased page's tags, you can do :
{% comment %}Create an empty array{% endcomment %}
{% assign tagArray = "" | split: "/" %}
{% for tag in page.tags %}
{% assign tagDowncased = tag | downcase %}
{% assign tagArray = tagArray | push: tagDowncased %}
{% endfor %}
<p>{{ tagArray | joint: ", " }}</p>

Related

HTML Script For tags is creating extra space

I've been trying to implement an automatic tag with an app for all of my products on Shopify. It works so that the tag created pulls information from the product desciption. If the description states "Pre-order. Ships in 2-3 weeks." or "Pre-order. Ships January 2021." It will pull whatever appears after the the word "Ships in" or Ships". As a result, the tags appear as such:
preorder**2-3 weeks
preorder**January 2021
The tag is used to insert estimated shipping times throughout the site.
The issue right now is that some of the tags have a space after "preorder** " and we need to make sure there is never a space. Any ideas on how to fix? The Body HTML that it is based off is if it contains "Pre-order. Ships in". Here's our current code:
{% assign body = product.body_html | strip_html | newline_to_br %}
{% assign keywords = "Pre-order. Ships" %}
b{% assign tags = '' %}
{% if body contains keywords %}
{% assign lines = body | split: "<br />" %}
{% for line in lines %}
{% if line contains keywords %}
{% assign tokens = line | split: keywords %}
{% if tokens.size == 2 %}
{% assign inner_tokens = tokens[1] | split: "." %}
{% if inner_tokens.size >= 1 %}
{% assign value = inner_tokens[0] | replace: "in", "" | escape_once | replace: " ", "" %}
{% assign tag = "preorder**" | append:value | replace_first: " ", "" %}
{% assign tags = tags | append: tag | append: ',' %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{{ tags }}
Issue
The issue is happening because "Ships in " has one more space than "Ships ".
Solution
You need to remove the space after the "in".
You can do this easily by modifying your replace operator
Code
replace: "in", "" becomes replace: "in ", "" (note the space).
Your code becomes:
{% assign body = product.body_html | strip_html | newline_to_br %}
{% assign keywords = "Pre-order. Ships" %}
b{% assign tags = '' %}
{% if body contains keywords %}
{% assign lines = body | split: "<br />" %}
{% for line in lines %}
{% if line contains keywords %}
{% assign tokens = line | split: keywords %}
{% if tokens.size == 2 %}
{% assign inner_tokens = tokens[1] | split: "." %}
{% if inner_tokens.size >= 1 %}
{% assign value = inner_tokens[0] | replace: "in ", "" | escape_once | replace: " ", "" %}
{% assign tag = "preorder**" | append:value | replace_first: " ", "" %}
{% assign tags = tags | append: tag | append: ',' %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{{ tags }}

Unable to use concat on `nil`

I am trying to build a related post include file for my Jekyll site. The site is based around the concept of members, attractions and parks (each as collections). Each post has a many to many relationships. I am trying to up a combined array of each of the page attributes (members, attractions and parks) loop through the array and find posts with a common number of tags.
It's quite simple but I am getting stuck with one section, not all the posts have members, attractions and parks fields so they are returning nil but the concat filter requires an array. I am trying to default the variable to an [] but it always gets set to nil. Any ideas?
Here's the code:
<ul class="row">
{% assign pageTags = [] %}{% if page.tags.first %}{% assign pageTags = page.tags %}{% endif %}
{% assign pageAttractions = [] %}{% if page.attractions.first %}{% assign pageAttractions = page.attractions %}{% endif %}
{% assign pageMembers = [] %}{% if page.members.first %}{% assign pageMembers = page.members %}{% endif %}
{% assign pageParks = [] %}{% if page.parks.first %}{% assign pageParks = page.parks %}{% endif %}
{% assign pageTagList = pageTags | concat: pageAttractions | concat: pageMembers | concat: pageParks %}
{% for post in site.documents %}
{% assign sameTagCount = 0 %}
{% assign commonTags = '' %}
{% assign postTags = [] %}{% if post.tags %}{% assign postTags = post.tags %}{% endif %}
{% assign postAttractions = [] %}{% if post.attractions %}{% assign postAttractions = post.attractions %}{% endif %}
{% assign postMembers = [] %}{% if post.members %}{% assign postMembers = post.members %}{% endif %}
{% assign postParks = [] %}{% if post.parks %}{% assign postParks = post.parks %}{% endif %}
{% assign postTageList = postTags | concat: postAttractions | concat: postMembers | concat postParks %}
{% if post.hidden == true %}
{% break %}
{% endif %}
{% for tag in postTageList %}
{% if post.url != page.url %}
{% if pageTagList contains tag %}
{% assign sameTagCount = sameTagCount | plus: 1 %}
{% capture tagmarkup %} <span class="label label-default">{{ tag }}</span> {% endcapture %}
{% assign commonTags = commonTags | append: tagmarkup %}
{% endif %}
{% endif %}
{% endfor %}
{% if sameTagCount >= minCommonTags %}
<li class="col-lg-4 col-md-12">
<div class="main-image">
</div>
<h5>{{ post.categories | first }}</h5>
<h3>{{ post.title | replace: 'Review', '' }}</h3>
<p>
{% if post.description %}
{{ post.description }}
{% else %}
{{ post.content | markdownify | strip_html | truncatewords: 20 }}
{% endif %}
</p>
<p>
Read Article →
</p>
</li>
{% assign maxRelatedCounter = maxRelatedCounter | plus: 1 %}
{% if maxRelatedCounter >= maxRelated %}
{% break %}
{% endif %}
{% endif %}
{% endfor %}
</ul>
You can see the repo here: https://github.com/dtsn/jungleskipper/blob/feature/members/_includes/related-posts.html
From the Liquid documentation:
You cannot initialize arrays using only Liquid.
You can, however, use the split filter to break a string into an array of substrings.
You should look at compact which removes any nil values from an array.
Here is a link to the doc on shopify.
Example from Liquid documentation
Input:
{% assign site_categories = site.pages | map: "category" %}
{% for category in site_categories %}
- {{ category }}
{% endfor %}
Output:
- business
- celebrities
-
- lifestyle
- sports
-
- technology
With Compact
Input:
{% assign site_categories = site.pages | map: "category" | compact %}
{% for category in site_categories %}
- {{ category }}
{% endfor %}
Output:
- business
- celebrities
- lifestyle
- sports
- technology

How to use Jekyll to sort posts by a custom YAML front matter variable?

I'm trying to create a page in my Jekyll site that will display a custom variable and list the posts that contain that custom variable.
I have created a movie review blog using a template Thiago Rossener created:
Thiago's Template: https://github.com/thiagorossener/jekflix-template
My Site: https://www.howdareyoureview.com/
in each post, I have defined custom variables in the YAML front matter that relate to the movie's details (i.e actor, director score, etc.)
for example:
---
layout: post
title: "Baby Driver"
image: 'https://res.cloudinary.com/how-dare-you-review/image/upload/c_fill,h_399,w_760/v1529865791/baby-driver.png'
tags:
- action
score: 72
director: Edgar Wright
written-by: Edgar Wright
staring:
- Ansel Elgort
- Lily James
- Eiza González
- Jon Hamm
- Jamie Foxx
---
I want to create pages exactly like the tags page that already exists in this template:
https://www.howdareyoureview.com/tags/
except I would want to sort by director, starring, etc. instead of by tags.
the tags page is created using the following code in a tags.html file:
---
layout: minimal
title: "#Tags"
permalink: /tags/index.html
description: "Procure por sua #tag favorita."
---
<div class="tags">
{% assign tags_list = site.tags %}
{% if tags_list.first[0] == null %}
{% for tag in tags_list %}
{{ tag }}
{% endfor %}
{% else %}
{% for tag in tags_list %}
{{ tag[0] }}
{% endfor %}
{% endif %}
{% assign tags_list = nil %}
</div>
{% for tag in site.tags %}
<div class="tag-wrapper">
<span class="tag-title" id="{{ tag[0] | slugify }}">{{ tag[0] }}</span>
<ul class="post-list">
{% assign pages_list = tag[1] %}
{% for post in pages_list reversed %}
{% if post.title != null %}
{% if group == null or group == post.group %}
<li>{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">{{ post.date | date: "%m/%d/%Y" }}</time></li>
{% endif %}
{% endif %}
{% endfor %}
{% assign pages_list = nil %}
{% assign group = nil %}
</ul>
</span>
</div>
{% endfor %}
To achieve this for the custom variables I created I tried replacing "tag/tags" with director and saving the file out into to root directory as "directors.html" but the page is blank.
---
layout: minimal
title: "#Directors"
permalink: /directors/index.html
description: "Procure por sua director favorita."
---
<div class="directors">
{% assign directors_list = site.director %}
{% if directors_list.first[0] == null %}
{% for director in directors_list %}
{{ director }}
{% endfor %}
{% else %}
{% for director in directors_list %}
{{ director[0] }}
{% endfor %}
{% endif %}
{% assign directors_list = nil %}
</div>
{% for director in site.director %}
<div class="director-wrapper">
<span class="director-title" id="{{ tag[0] | slugify }}">{{ director[0] }}</span>
<ul class="post-list">
{% assign pages_list = director[1] %}
{% for post in pages_list reversed %}
{% if post.title != null %}
{% if group == null or group == post.group %}
<li>{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">{{ post.date | date: "%m/%d/%Y" }}</time></li>
{% endif %}
{% endif %}
{% endfor %}
{% assign pages_list = nil %}
{% assign group = nil %}
</ul>
</span>
</div>
{% endfor %}
Since the code and the concept is exactly the same as the way tags are populated - I cannot understand why this doesn't work - I'm hoping someone can assist!
Here is my entire directory for reference:
https://github.com/howdareyoureview/howdareyoureview.github.io
Tags page uses site.tags, which is an array of site.posts grouped by tag, created by Jekyll at generation time.
You're trying to replicate by targeting site.directors but this expected array doesn't exist. But, you can use the group_by filter to achieve your goal.
<div class="directors">
{% assign directors = site.posts | group_by: 'director' | sort: "name" %}
{% for director in directors %}
{% if director.name == "" %}
{% assign name = "Anonymous" %}
{% else %}
{% assign name = director.name %}
{% endif %}
{{ name }}
{% endfor %}
</div>
{% for director in directors %}
<div class="director-wrapper">
{% if director.name == "" %}
{% assign name = "Anonymous" %}
{% else %}
{% assign name = director.name %}
{% endif %}
<span class="director-title" id="{{ name | slugify }}">{{ name | debug }}</span>
<ul class="post-list">
{% assign pages_list = director.items %}
{% for post in pages_list reversed %}
<li>{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}" itemprop="datePublished">{{ post.date | date: "%m/%d/%Y" }}</time></li>
{% endfor %}
</ul>
</span>
</div>
{% endfor %}
Tip : You can use the inspect filter to debug your vars. {{ myvar | inspect }}

One variable for different collections in Jekyll to use in forloop

I have several collections on my Jekyll site. I've added post navigation to one of the collections displaying a counter on each post page:
{% assign testimonials = site.testimonials %}
{% assign page_order = 1 %}
{% for node in testimonials reversed %}
{% if node.url == page.url %}
{{ page_order }} from {{ forloop.length }}
{% else %}
{% assign page_order = page_order | plus: 1 %}
{% endif %}
{% endfor %}
I would like to make this code work not only for site.testimonials, but for other collections as well. I tried to pass a variable for collections like this:
{% capture label %}{{ page.collection }}{% endcapture %}
{% assign collection = site.collections | where: "label",label | first %}
{% for node in collection reversed %}
{% if node.url == page.url %}
{{ page_order }} from {{ forloop.length }}
{% else %}
{% assign page_order = page_order | plus: 1 %}
{% endif %}
{% endfor %}
But it doesn't work. Is there any way to pass a variable for all collections in Jekyll to use in forloop in post navigation?
When you access collection with site.testimonials, you get collection's documents array.
{{ site.testimonials | inspect }}
# output >> [#<Jekyll::Document ...>, #<Jekyll::Document ...>, ...]
When you access a collection while looping over site.collection, you receive the collection's object :
{% assign collection = site.collections | where: "label",page.collection | first %}
{{ collection | inspect }}
# output >> { "output": true, "label": "collectionLabel",
"docs": [ doc1, docs2, ... ], "files": [],
"directory": "/path/to/collection",
"relative_directory": "_colectionDirectory" }
In your case, you just have to replace :
{% for node in collection reversed %}
By :
{% for node in collection.docs reversed %}

Listing Jekyll Collection pages by tags

I am trying to make a list of pages within a collection grouped by tags. I know this is easily possible with Jekyll's built-in site.tags feature, which I can (and have) achieve with something like:
<h3>Tags</h3>
{% for tag in site.tags %}
{% assign t = tag | first %}
{% assign posts = tag | last %}
<h4><a name="{{t | downcase | replace:" ","-" }}"></a><a class="internal" href="/tagged/#{{t | downcase | replace:" ","-" }}">{{ t | downcase }}</a></h4>
<ul>
{% for post in posts %}
{% if post.tags contains t %}
<li>
{{ post.title }}
<span class="date">{{ post.date | date: "%B %-d, %Y" }}</span>
</li>
{% endif %}
{% endfor %}
</ul>
<hr>
{% endfor %}
In order to get this:
I want to replicate the site.tags function in a Collection called note. Tags in my collections are grouped like they are for posts, using, e.g., tags: [urban growth, California, industrialization] in the YAML header. But I want to get this working with a Collection instead. I can almost achieve what I want with the following:
{% assign collection = site.note | group_by: "tags" | uniq %}
{% for group in collection %}
{% comment %} This is super hacky and I don't like it {% endcomment%}
<h3>{{ group.name | replace: '"', '' | replace: '[', '' | replace: ']', '' }}</h3>
<ul>
{% for item in group.items %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
{%endfor%}
But as you can probably see, this doesn't break tags out into their unique groups; instead, each set of tags in the YAML is treated as a single, large tag. Any pointers on constructing the array of unique tags and listing the Collection pages under them?
Try this :
{% assign tags = site.note | map: 'tags' | join: ',' | split: ',' | uniq %}
{% for tag in tags %}
<h3>{{ tag }}</h3>
<ul>
{% for note in site.note %}
{% if note.tags contains tag %}
<li>{{ note.title }}</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
The tags assignment method mentioned in David Jacquel's answer can be simplified as:
{% assign tags = site.note | map: 'tags' | uniq %}