Accessing posts via directory tree in Jekyll - jekyll

Let's say I have a directory like the following:
|things
|---|animals
|---|---|dog
|---|---|cat
|---|---|other
|---|languages
|---|---|Afrikaans
|---|---|Latin
|---|---|Japanese
|---|---|other
and I want to access all of the posts under the "other" category that is under the "languages" category.
I want to be able to do
{% for post in site.categories.things.languages.other do %}
but that apparently doesn't work in Jekyll.
If I can avoid it, I'd like to not do
{% for post in site.categories.cobol do %}
{% if post.categories equals ["things", "languages", "other"] %}
but if I absolutely must, I will.

If you want to simply output a list of posts contained in a given path :
languages_other.html
---
path: "things/languages/other/"
---
{% include post_by_folder.html path=page.path %}
_includes/posts_by_folder.html
<h1>Posts in folder {{ include.path }}</h1>
<ul>
{% for post in site.posts %}
{% if post.path contains include.path %}
<li>
{{ post.title }}
</li>
{%endif %}
{% endfor %}
</ul>
Now any time you want to make a list of posts in a particular folder, you just have to create a page like languages_other.html.

Related

Jekyll blog - How to show a list of posts if list file exists

What I'm trying to do is for each category page, if a file exists with the category name then use that file for the list of popular posts. If not then I want to use the default popular posts.
The category featured post file would exist in this folder, if there is one "_includes/blog/feat-posts."
I want to display in the sidebar of my blog. Here's the code I tried using some documentation I found online. This does not work.
<h3>POPULAR POSTS</h3>
{% comment %}(Not sure if this is the correct code, but looking for static file){% endcomment %}
{% for static_file in site.static_files %}
{% comment %}(if a file exists with the same name as the category name, then..){% endcomment %}
{% if static_file.path == '_includes/blog/feat-posts/{{page.autopages.display_name}}.html' %}
{% comment %}(include that file){% endcomment %}
{% include {{ blog/feat-posts/{{page.autopages.display_name}}.html }} %}
{% else %}
{% comment %}(otherwise use the default files){% endcomment %}
<p>Filename1 Text</p>
<p>Filename2 Text</p>
{% endif %}
{% endfor %}
Please help.
I still don't know what "it does not work" means but I assume the error happens in the line with include or your file is not in your static_sites.
You can check the site.static_files content by adding {{ site.static_files | inspect }} to your code. Static files are kind of special, see https://jekyllrb.com/docs/static-files/.
To construct paths dynamically, you may want to use assign to assign the value to a variable first (see simplified example below).
I could check the path by adding a file to the root folder (path /test.html) and then link to the same file name in the _includes folder:
<h3>POPULAR POSTS</h3>
{% comment %}{{ site.static_files | inspect }}{% endcomment %}
{% for static_file in site.static_files %}
{% if static_file.path == '/test.html' %}
{% assign filename = 'test.html' %}
{% include {{ filename }} %}
{% endif %}
{% endfor %}
I hope this helps.

Jekyll/Liquid Relative URL filter breaks links

I'm trying to use relative_url in most of the links of my Jekyll theme, so if someone wants to have this theme working in a subdirectory he can do it.
I have a problem with the list of categories of the post, each of which should link to the archive.
In _layouts/post.html I have this code:
{% if site.data.settings.categories.active %}
{% include categories.html %}
{% endif %}
categories.html has this code:
<div class="categories">
<span><p>Categories:</p>
{% if post %}
{% assign categories = post.categories %}
{% else %}
{% assign categories = page.categories %}
{% endif %}
{% for category in categories %}
{{category}}
{% unless forloop.last %} {% endunless %}
{% endfor %}
</span>
</div>
Here's the problem:
{{category}}
Somehow, this returns the current post url.
{{category}}
This returns the correct link, but does not work in case the site is in a subdirectory.
Why it returns the post url?
There are multiple problems here.
First off, Liquid doesn't evaluate nested constructs.
Therefore, the following code:
{{ "/categories/#{{category | slugify}}" | relative_url}}
needs to be rewritten into:
{% capture url %}/categories/{{ category | slugify }}{% endcapture %}
{{ url | relative_url }}
Secondly, there is no global post object. Therefore {% if post %} is always going to evaluate to a negative. i.e., it is redundant.

Find post where key has specific value in Jekyll

I need to be able to compare a value in each of the markdown files in a folder called in_media to the user_id of the current page stored in a _users folder and only display the post title that have that value from the in_media folder.
User markdown file in _users folder
---
user_id: 123
title: bob
---
Post markdown from in_media folder
---
users: 123
---
I tried the following:
{% for this_user in site.in_media %}
{% for user in page.user %}
{% if this_user == user.user_id %}
<li><a href="{{ post.external_link }}">{{ post.title }}</a </li>
{% endif %}
{% endfor %}
{% endfor %}
However, this is not returning anything
Try this way:
{% for post in site.in_media %}
{% if post.value == page.title %}
<li>{{ post.title }}</li>
{% endfor %}
{% endfor %}
I'm not sure that you can use external_link, never heard of it. Maybe you'll need to build permalink manually - depending on your _config.xml.
Also note the collection should be properly set up to work with permalinks.

List non-posts pages in relevant category pages

I have a Jekyll blog up and running, but I'd like to do something that seems a bit unorthodox.
Essentially, I've got blog posts in /_posts, and a set of static pages in another folder at /projects.
The top of these projects page looks like this:
---
layout: project
title: My cool project
categories:
- Data Journalism
status: active
---
Now, the biggie: Each category (such as Data Journalism in the example above) has a page with a unique URL, where posts belonging to this category are aggregated.
I would like projects belonging to these categories to be aggregated on these same pages, eg the Data Journalism category page would have a list of projects and a list of posts, all of which are part of this category.
I managed to list all the projects on each category page with
<ul class="posts">
{% for page in site.pages %}
{% if page.layout == 'project' %}
{% if page.status == 'active' %}
<h2>{{ page.title }}</h2>
<div> {{ page.description }}</div>
{% endif %}
{% endif %}
{% endfor %}
</ul>
added in _layouts/category_index.html. But it shows all projects, not only the one belonging to the page category. In the example, My cool project should only be listed in the Data Journalism category page.
Can you help? I'd be most grateful!
EDIT: Thanks to Davic Jacquel for the solution. His answer's below, marked as solved, and here is the tweak I had to make:
<ul class="posts">
{% for p in site.pages %}
{% if p.layout == 'project' and p.status == 'active' %}
{% assign cat = p.categories | downcase %}
{% if cat contains page.category %}
<h2>{{ p.title }}</h2>
<div> {{ p.description }}</div>
{% endif %}
{% endif %}
{% endfor %}
</ul>
Edit : reading your plugin code makes me realize that you have a page.category variable in all your categories pages.
Note : current page's data are stored in the page variable. So, when you loop, try not use page as a storage variable to avoid collision.
In _layouts/category_index.html :
---
layout: default
---
<ul class="posts">
{% for p in site.pages %}
{% if p.layout == 'project' and p.status == 'active' %}
{% if p.categories contains page.category %}
<h2>{{ p.title }}</h2>
<div> {{ p.description }}</div>
{% endif %}
{% endif %}
{% endfor %}
</ul>

Jekyll 2.0 listing all post from category breaks

I moved from Jekyll pre-1.0 to 2.0 recently.
In my original code, on each blog post it will list all the title of posts that belongs to the same category as the current post being viewed. Previously this code worked:
{% for post in site.categories.[page.category] %}
<li {% if page.title == post.title %} class="active" {% endif %}>
{{ post.title }}</li>
{% endfor %}
However in the new version this does not work and I have to specify the category individually like so:
{% for post in site.categories.['NAME_OF_CATEGORY'] %}
Why can't I dynamically check for the category as before? And is there a work around for this instead of using if statements?
I figured it out. I had, in each post, my YAML front-matter category variables in uppercase or Camel case. Example: category: ABC or category: Zyx.
Doing page.category will always return the the actual category as it was written in the front-matter, which is ABC or Zyx. However site.categories.[CAT] only accepts CAT in lower cases (down case in liquid language).
Hence this will work site.categories.['abc'] or site.categories.['xyz'].
But this will fail site.categories.['ABC'] or site.categories.['Xyz']. It is the same as doing site.categories.[page.category].
Solution. Assign the current page category in lower case like so:
{% assign cat = page.category | downcase %}
{% for post in site.categories.[cat] %}
<li {% if page.title == post.title %} class="active" {% endif %}>
{{ post.title }}</li>
{% endfor %}