Unable to find current post's category jekyll - jekyll

I want to display keywords and description automatically according to the category of the current post. I've used the following code, but it doesn't worked.
{% if page.categories = "category" %}
{% else %}
{% endif %}
But while using {% page.categories %} it is echoing out the category name correctly. Here are my two doubts:
How can I compare the current post's category?
Are {{ }} and {% %} are same here?

It should look like the following:
{% if page.categories == 'some-name' %}
Hei I am in some-name category
{% else %}
No I am not in some-name category
{% endif %}
2.
No, {{ }} and {% %} are not the same. {{ }} is used for echoing stuff, while {% %} is used for logic expressions and arguments.

Related

Liquid/Jekyll: How to check for no posts when one has two or more conditions?

I am having trouble understanding how I might show a "no posts exist" message for a particular conditional statement with two variables.
In this example, let's say I have a collection of "animals" - on a particular page, I'd like a section that displays "primates that are herbivores":
{% for animal in site.animal %}
{% if animal.species == "primate" and animal.type == "herbivore" %}
{{ animal.content }}
{% endif %}
{% endfor %}
What I'd like to do is something like this (pseudocode):
{% if POSTS_EXIST_FOR_THIS_COMBO: (animal.species == "primate" and animal.type == "herbivore") %}
{% for animal in site.animal %}
{% if animal.species == "primate" and animal.type == "herbivore" %}
{{ animal.content }}
{% endif %}
{% endfor %}
{% else %}
There are no posts for this category.
{% endif %}
Note: This differs from examples like this, because I have two parameters to check. Can someone offer a suggestion about the syntax?
I think you can do the following where you at first filter all by species=primate from site.animal and then filter by type=herbivore from that pool and then check if the result exists.
{% assign animals = site.animal | where:"species","primate" | where:"type","herbivore" %}
{% if animals %}
{% for animal in animals %}
{{ animal.content }}
{% endfor %}
{% endif %}
Hope this helps.

How to check if a value is present in a list?

I would like to get the list of posts having a specific tag in their front matter (*)
I tried the code below, which iterates over all the tags of the current post pages (the current tag is t), then iterates over all the posts (p) to check if they have this tag (and just outputs the title, for debugging reasons):
{% for t in page.tags %}
{% for p in site.posts %}
{% if t in p.tags %}
{{ p.title }}
{% endif %}
{% endfor %}
{% endfor %}
The line {% if t in p.tags %} seems to fail (I come form a Python background so I gave it a try) and I cannot find the in operator in liquid. Does it exits?
(*) I am mentioning what I want to achieve in case there is a more straightforward way to do that but I am still interested in the general question.
Following your example it can be done with the contains tag:
contains can also check for the presence of a string in an array of
strings.
{% if product.tags contains "outdoor" %}
This product is great for
using outdoors!
{% endif %}
So to get the list of posts having a specific tag in their front matter (in this case the posts with the tag mytag):
{% assign posts_with_mytag = site.posts | where_exp:"item",
"item.tags contains 'mytag'" %}
{% for post in posts_with_mytag %}
{{post.title}}
{% endfor %}
Following-up on #maracuny's answer, the corrected code from my question for completeness:
{% for t in page.tags %}
{% for p in site.posts %}
{% if p.tags contains t %}
{{ p.title }}
{% endif %}
{% endfor %}
{% endfor %}

How to loop through categories in a Jekyll collection

I'm trying to loop through categories that have been added to collection posts. For the default 'posts' section it's as easy as:
{% for category in site.categories %}
{{ category }}
{% endfor %}
But I can't seem to get this working for my collection. I thought it would be something along the lines of:
{% for category in my_collection.categories %}
{{ category }}
{% endfor %}
But that doesn't seem to work. Any help would be appreciated.
for anyone needing the answer to this...I've managed to solve this by adding all unique 'my_collection' categories to an array then looping through that. Here's the code:
<!-- create categories array-->
{% assign categories_array = "" | split:"|" %}
<!--Add each unique 'my_collection' category to the array-->
{% for post in site.my_collection %}
{% for category in post.categories %}
{% assign categories_array = categories_array | push: category | uniq %}
{% endfor %}
{% endfor %}
<!--Output the categories-->
{% for category in categories_array %}
{{ category }}
{% endfor %}
you can grab the name of each category like so:
{% for category in site.categories %}
{{ category | first | strip_html }}
{% endfor %}
You first have to declare the collection
{%a assign col = site.COLLECTIONNAME %}
Then you can loop inside the collection
{% for cat in col %}
{{ col.name }}
{% endfor %}

Getting the related posts from specific category (category/_posts)

I am doing the following
{% for post in site.related_posts limit:3 %}
// My stuff
{% endfor %}
and it keeps returning the posts from each of my categories i.e. blog/_posts/ as well as projects/_posts/ what I want is only blog posts. So I tried to do the following
{% for post in site.categories.blog.related_posts limit:3 %}
// My stuff
{% endfor %}
But it doesn't seem to return anything at all. Can any one please tell me what am I doing wrong here?
I never use related_posts, but this fairly ugly bit might work for you:
capture the category
{% capture related_posts %}{{ page.categories }}{% endcapture %}
Use that category to create your related posts
{% assign collection = site.categories[related_posts] %}
Return the related posts in a loop, pulling out the current page's post
{% for article in collection %}
{% unless page.url == article.url %}
{{ article.title }} - {{ category | capitalize }}<br />
{% endunless %}
{% endfor %}
Both this and related posts are processor intensive if you have a lot of posts.

Jekyll - Get all posts that are in multiple categories

I want to loop over all posts that are assigned category "foo" and category "bar" ..
{% for post in site.categories.foo and in site.categories.bar %}
Is this possible?
In my case "foo" as a "parent" category to "bar" ... /foo/bar/_posts
Thanks
Instead of looking through every post and matching with an or, you can filter by the first tag and then look for the second (and third, fourth, fifth...) tags:
{% for post in site.categories.fizz%}
{% if post.categories contains "buzz" and post.categories contains "bang" %}
<!--post has categories fizz AND buzz AND bang-->
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
This is a little more efficient than iterating over every single post, and it sets up an and relationship instead of an or relationship.
It is fully possible: loop over all posts, and then select the wanted posts:
{% for post in site.posts %}
{% if post.categories contains "foo" or post.categories contains "bar" %}
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
Using the Where Expression filter in Jekyll.
Jekyll Liquid Filter Docs
Where Expression,
Select all the objects in an array where the expression is true.
3.2.0
{{ site.members | where_exp:"item", "item.projects contains 'foo'" }}
So on my site I did:
_includes/clippings.html
...
{% capture _filter %}item.tags contains '{{ include.tag }}'{% endcapture %}
{% for clip in site.clippings | where_exp: 'item', _filter %}
{{ clip.do_stuff }}
# more html and stuff
{ endfor }
{% include clippings.html tag='foo' %}
In this case I need to specify the filter tag dynamically. And clippings is just a collection like posts.
If you want to filter by multiple static tags you could do something like:
{% for post in site.posts | where_exp: 'item', "item.tags contains 'foo'" | where_exp: 'item', "item.tags contains 'bar'" %}
{{ post.do_stuff }}
{ endfor }
If you want to do multiple dynamic filter tags then you will need to do something similar to the capture stuff I did above.
I have not tested this, but it should filter posts by an arbitrary amount of filter tags.
{% assign posts = site.posts %}
{% filter_tags = 'foo, bar, buzz' | slipt: ', ' %}
{% for tag in filter_tags %}
{% capture _filter %}item.tags contains '{{ tag }}'{% endcapture %}
{% assign posts = posts | where_exp: 'items', _filter %}
{% endfor %}
{% for post in posts %}
{{ post.do_stuff }}
{% endfor %}
However looping over the whole thing once and checking each post might be more efficient at that point.