Jekyll/Liquid Templating Capture Category Name of a Post - jekyll

I am creating an archive by date and using this solution.
I want to add the category of the post next to the post and am having trouble capturing the category name of a post since categories are indexed through the site
{% else %}
<li>{{ post.title }}
{% capture category_names %}{{ ## need to capture category }}{% endcapture %}
{% if category_name %} - {% for category in category_names %}
{{category}}
{% unless forloop.last %} {% endunless %}
{% endfor %}
{% endif %}
{% if post.date %} - {{ post.date | date: "%m/%d/%Y" }}{% endif %}</li>
{% endif %}
Currently the code above creates {post name } - - mm/dd/YYYY as I want without the category name in between the 2 '-'.
Any idea how to capture the category name of a post? Thank you.

Related

Combining Jekyll post data with data from YAML to make a new blog feed

I think I'm not even sure what I should be searching for. On my Jekyll Blog I currently have just blog posts that have been written and listed with their full content on the main page and using pagination. I want to follow more Indie Web standards and follow a PESOS (Publish Elsewhere, Syndicate (to your) Own Site) method. I've figured out a way to get data from my Twitter (e.g. post_date, embed code, etc) into a YAML data file automatically. What I want to do is take the data from my posts and combine the data from Twitter and include those posts as if they were also blog posts (the plan is to do the same with Instagram as well).
I've tried a lot of things, but I'm not even sure what is the best way to go about doing this. I'm assuming that it will use something similar to Using Jekyll, how do you alter an array's contents using a for loop?, but I can't seem to make it work. My code for the blog posts is as follows currently:
{% for post in paginator.posts %}
{% if post.header.teaser %}
{% capture teaser %}{{ post.header.teaser }}{% endcapture %}
{% else %}
{% assign teaser = site.teaser %}
{% endif %}
{% if post.id %}
{% assign title = post.title | markdownify | remove: "<p>" | remove: "</p>" %}
{% else %}
{% assign title = post.title %}
{% endif %}
<div class="list__item">
<article class="archive__item" itemscope itemtype="https://schema.org/CreativeWork">
<h1 class="archive__item-title" itemprop="headline">
{% if post.link %}
{{ title }} <i class="fas fa-link" aria-hidden="true" title="permalink"></i><span class="sr-only">Permalink</span>
{% else %}
{{ title }}
{% endif %}
</h1>
<p>Posted on {{ post.date | date: "%A %B %-d, %Y" }} by Jacob Campbell.</p>
{{ post.content }}
</article>
</div>
{% endfor %}
{% include paginator.html %}
Maybe, if your posts and tweets do have the same structure in terms of fields you could concat the two:
{% comment %} Given that you make the tweets accessible from site, as a collection, for example {% endcomment %}
{% assign posts = paginator.posts | concat: site.tweets | sort: "date" %}
{% for post in posts %}
<h2>{{ post.title }}</h2>
<div>{{ post.content }}</div>
{% endfor %}
Mind that, here I am also resorting the list after the concat, via the sort filter, so the tweets do appear in the normal time series of the posts.
And if your structures are not the same, you can always resort to the collection in which your post is:
{% assign posts = paginator.posts | concat: site.tweets | concat: site.instagram | sort: "date" %}
{% for post in posts %}
{% if post.collection == 'posts' %}
<h2>{{ post.title }}</h2>
<div>{{ post.content }}</div>
{% elsif post.collection == 'tweets' %}
{% comment %} If I am not mistaken, twitter have no title concept {% endcomment %}
<h2>There was a bird singing about:</h2>
<div>{{ post.content }}</div>
{% elsif post.collection == 'instagram' %}
{% comment %} So, now, it can fit any social media of your choice {% endcomment %}
{% endif %}
{% endfor %}

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

Liquid markup sorting the output

I am trying to display a list of all articles using liquid markup. I've got this code which displays them properly, however I want to be able to sort by the modified date descending (most recent article on top). How can this be accomplished?
I was thinking that perhaps I need to create a new array with all articles in it and then sort that, but I am not sure how to do that. Also note that I want to sort ALL of my articles by date, not just within each folder.
{% for category in portal.solution_categories %}
{% if category.folders_count > 0 %}
{% for folder in category.folders %}
{% for article in folder.articles %}
{{ article.title }} - {{ article.modified_on | short_day_with_time }} <br>
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
Thanks!
You can use a variable to sort the list of articles and then iterate that variable.
{% for category in portal.solution_categories %}
{% if category.folders_count > 0 %}
{% for folder in category.folders %}
{% assign sorted = (folder.articles | sort:date) %}
{% for article in sorted %}
{{ article.title }} - {{ article.modified_on | short_day_with_time }} <br>
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}

Jekyll: Listing all categories but one with a limit breaks the limit

I am trying to output a list of post titles with the 5 latest posts in ALL categories BUT one. It works fine with the filtering, unfortunately it takes the posts that are being excluded in consideration for the limit. Is there any easy way to not count the excluded posts?
{% for post in site.posts limit: 5 %}
{% if post.category == "news" %}
//Do nothing
{% else if %}
{{ post.title }}
{% endif %}
{% endfor %}
To limit filtered posts you need to filter them first.
We create an array of posts that do not include the news category:
{% assign no_news = "" | split: "" %}
{% for post in site.posts %}
{% unless post.categories contains 'news' %}
{% assign no_news = no_news | push: post %}
{% endunless %}
{% endfor %}
Now we traverse this new array limiting iterations by 5:
{% for post in no_news limit: 5 %}
{{ post.title }} - {{post.categories}}
{% endfor %}
It will output 5 posts not containing the news category.
You should be able to assign the posts first, then call them:
{% assign relevant = site.posts | except:"category","news" %}
{% for posts in relevant limit:5 %}
{{ post.title }}
{% endfor %}
For more: https://github.com/jekyll/jekyll/issues/2018

Looping through all list of posts not in some category in liquid

I want to loop through posts on a site except ones with the category unlisted. I'm able to do this by nesting an if statement inside the for loop, but this breaks down when I want to also specify a limit – the loop will run for 5 times only regardless of whether the post passes the check.
{% for post in site.posts limit: 5 %}
{% unless post.categories contains 'unlisted' %}
<!-- display post -->
{% endunless %}
{% endfor %}
I need to pass an already filtered list to the for loop, but I'm unable to do this mainly because I can't find a way to combine the where filter with contains and negation:
{% for post in site.posts | WHERE CATEGORIES NOT CONTAINS 'UNLISTED' | limit: 5 %}
<!-- display post -->
{% endfor %}
You can use a counter :
<ul>
{% assign postCounter = 0 %}
{% assign maxPost = 5 %}
{% for post in site.posts %}
{% unless post.categories contains 'unlisted' %}
<li>{{ post.title }}</li>
{% assign postCounter = postCounter | plus: 1 %}
{% if postCounter >= maxPost %}
{% break %}
{% endif %}
{% endunless %}
{% endfor %}
</ul>