Jekyll site.categories incorrect values - jekyll

When I access site.categories.first I get what looks to be all the content of all my blog posts wrapped into a single string.
When I access site.categories[1] I get an empty string. The length of site.categories appears roughly equal to the number of categories I have.
I checked for any manual editing of site.categories, but I don't see anything that would be doing this.

You can use inspect filter to understand how categories works.
{{ site.categories | inspect }} returns a hash like:
{
"jekyll"=>[#<Jekyll::Document _posts/2017-10-31-welcome-to-jekyll.markdown collection=posts>],
"update"=>[#<Jekyll::Document _posts/2017-10-31-welcome-to-jekyll.markdown collection=posts>]
}
And {{ site.categories.first | inspect }} returns an array like :
["jekyll", [#<Jekyll::Document _posts/2017-10-31-welcome-to-jekyll.markdown collection=posts>]]
Where {{ site.categories.first[0] }} is the category name, and {{ site.categories.first[1] }} is an array containing first category's document.
You can call a category from his name {{ site.categories.jekyll | inspect }} but not by is index {{ site.categories[0] | inspect }} => []
You cannot modify site.categories because it is freezed by jekyll.

Related

Jekyll Liquid Syntax, how to dereference a property

I am grouping the posts on my site using this liquid tag.
{% assign postsForYear = site.posts | group_by_exp:"post", "post.date | date: '%Y'" | where: "name", "2020" %}
When I echo the postForYear out to screen, I see this:
{"name"=>"2020", "items"=>[#, #, #, #, #, #], "size"=>6} 0
Which makes sense, as I have six posts for that year. However, I am trying to dereference that object and get the .size property, which I can see in the output...I can't figure out the syntax!
How to get the .Size property?
None of these work.
{{ postsForYear.size }}
{{ postsForYear.items | size }}
After that, I would love to learn how to foreach my way through the posts...this also seems simple but doesn't work!
Ah, I figured it out. Strangely, the postsForYear array was actually treated like an array itself, so I had to index into the first position to get to the properties.
{% assign postsForYear = site.posts |
group_by_exp:"post", "post.date | date: '%Y'" | where: "name", "2020" %}
###doesn't work
{{ postsForYear.items | size }}
### does work
{{ postsForYear[0].items | size }}
### example
Posts for year {{ postsForYear[0].name }}, total posts {{ postsForYear[0].size }}
>Posts for year 2020, total posts 6
And to answer my other question, how to foreach your way through:
{% for post in postsForYear[0].items %}
<h1>{{post.title}}</h1><br>
{% endfor %}

Jekyll - Evaluate a string before assignment

I need to capture a string into a variable tag, then use this variable in site.tags.tag. The code is:
{% capture tag %}programming{% endcapture %}
{{ tag }}
{%- assign titles = site.tags.tag | map: "title" -%}
{{ titles }}
This code only prints prints:
programming
But if I replace site.tags.tag with either site.tags.programming or site.tags.'programming' I get the desired output:
programming
title1 title2
Is there a way to evaluate the variable tag before the assignment? After reading a similar question I tried site.tags.{{tag}} but it didn't work.
site.tags[tag] might be what you're looking for.

How to group Jekyll pages by the first letter of the title?

I'm building a Jekyll site that has a page for each topic. I want to create an alphabetically grouped list of links to each page.
For example, if my topic titles are:
Aardvark
Beatle
Catfish
Cattle
I want to end up with a list of links organised as:
A
Aardvark
B
Beatle
C
Catfish
Cattle
So far, I have gotten code that looks like this:
{% assign topics_by_letter =
site.topics | group_by_expr: "topic", "topic.title | slice: 0, 1" %}
{% for letter in topics_by_letter %}
<div>
{{ letter.name }}
</div>
{% endfor %}
site.topics is the correct name of the page collection and evaluates as expected.
All topics have a valid title label.
Where I am stuck is that letter.name evaluates to empty and I just have a list of empty divs. The snippet {{ page.title | slice: 0, 1 }} works and gives you back the first letter of the topic title.
What am I missing?
Was a typo, group_by_expr should be group_by_exp.

Sort by a modified variable in Liquid and Jekyll

I have a collection in Jekyll which I want to sort. Sorting by title is easy of course.
<ul>
{% for note in site.note | sort: "title" %}
<li>{{note.path | git_mod }}: {{ note. title }}</li>
{% endfor %}
</ul>
I want to sort by date. But since collections don't have a date, I have a custom Liquid filter which takes the path of the item, and gets its last modified time in Git. You can see that in the code above, where I pass the path to git_mod. I can verify that this works, because when I print out the list, I get the correct last modified times, and it is a full date. (In practice, I also pass it to date_as_string.)
But I can't sort by that value because Liquid doesn't know about it, since it is a value already in each item in the site.note collection. How can I sort by that value? I was thinking something like this, but it doesn't work:
<ul>
{% for note in site.note | sort: path | date_mod %}
<li>{{note.path | git_mod }}: {{ note. title }}</li>
{% endfor %}
</ul>
I've also tried variants like: {% for note in site.note | sort: (note.path | git_mod) %}
None of these throw an error, but none of them work either.
This is a case where you can use Jekyll hooks.
You can create a _plugins/git_mod.rb
Jekyll::Hooks.register :documents, :pre_render do |document, payload|
# as posts are also a collection only search Note collection
isNote = document.collection.label == 'note'
# compute anything here
git_mod = ...
# inject your value in dacument's data
document.data['git_mod'] = git_mod
end
You then will be able to sort by git_mod key
{% assign sortedNotes = site.note | sort: 'git_mod' %}
{% for note in sortedNotes %}
....
Note that you cannot sort in a for loop. You first need to sort in an assign, then loop.

Liquid Template: Append variable to data object

I have the following structure in my Jekyll app:
_data/
test.json
items/
test/
index.html
I am using the following to grab just the name of the ending folder name of my item:
{% assign listing = {{ page.url | remove: 'items/' | replace:'/',' ' | truncatewords: 1 | remove:'...' | escape }} %}
What I'm then trying to do is access the data file which the matching folder name from the _data directory.
I've gotten it to:
{{ site.data.{{ listing }} }}
which allows me to see the data, but I can't actually go inside the JSON object to grab a specific item, like {{ site.data.{{ listing }}.test }} does not work. Any help would be greatly appreciated. Thanks!
Use some brackets like this :
{% assign datas = site.data[{{listing}}] %}
You can now access datas.test.