As you see below, this is a fairly simple collection setup with an unordered lists of events that live in the _events folder at the root level (output is set to false). Instead of using {{ page.title }} in the layout, I want the heading(s) to read as months.
For example, if I add a new item into the _events collection and include month: January in the front-matter, I want that to generate a “January” heading, and place that unordered list underneath the heading. Likewise, if I add a new collection item and include month: February in the front-matter, I want to generate a “February” heading with a new unordered list below that heading.
I know I need a bit of re-arranging of where the heading lives, and I'm thinking I need some type of if statement, but I’m at a roadblock. I can’t figure this one out.
Is this possible with Jekyll Collections?
Layout
{% include root.html %}
<div class="flex-main">
{% include header.html %}
<main class="o-main" role="main">
<div class="o-grid-six">
<h1 class="f1 o-grid-six__child c-headline">{{ page.title }}</h1>
</div>
{{ content }}
</main>
</div>
<div class="flex-footer">
{% include footer.html %}
</div>
View (Events)
---
layout: events
title: Events
order: 2
---
<ul class="c-event-list">
{% for events in site.events %}
<li class="c-event-list__flag">
<div class="c-event-list__flag--left">
<div class="c-event-list__calendar">
<span class="c-event-list__day">{{ events.weekday }}</span>
<span class="f2 c-event-list__date">{{ events.date-number }}</span>
</div>
<img class="c-event-list__image" src="{{ p.url | prepend: site.baseurl }}{{ events.thumb }}" alt="">
</div>
<div class="c-event-list__flag--body">
<div class="c-event-list__content">
<h3 class="f2 c-event-list__title">{{ events.title }}</h3>
<p>{{ events.description }}</p>
<a class="c-button u-mt-2" href="{{ events.link }}">Sign Up</a>
</div>
</div>
</li>
{% endfor %}
</ul>
Collection item (an event)
---
layout: default
thumb: /images/event__screen-printing-basics.jpg
link: https://www.eventbrite.com/e/screen-printing-basics-tickets-41882948025
title: Screen Printing Basics
weekday: Wednesday
month: January
date-number: '10'
description: Join us for an after hours session to learn everything you need to know about screen printing in the Make Lab. We will be coating screens with emulsion, printing artwork onto transparencies, burning the image into the screen, washing out the stencil, mixing ink, prepping our work station, registering the paper, and finally pulling prints. The artwork always varies, so you’ll leave with a one-of-a-kind screen printed poster that you made yourself!
---
Interface
The best way to accomplish this is to use real dateTime and group_by_exp filter.
DateTime
---
layout: default
thumb: /images/event__screen-printing-basics.jpg
link: ...
title: Screen Printing Basics
description: ...
date: 2018-03-21 20:00
---
Note that for some reason date: 2018-03-21 doesn't work.
group_by_exp filter
Simplified print logic can be :
{% assign eventsByYear = site.events | group_by_exp:"event", "event.date | date: '%Y'" %}
{% for year in eventsByYear %}
<h1>{{ year.name }}</h1>
{% assign eventsByMonth = year.items | group_by_exp:"event", "event.date | date: '%B'" %}
{% for month in eventsByMonth %}
<h2>{{ month.name }}</h2>
<ul>
{% for event in month.items %}
<li>{{ event.title }}-{{ event.date | date: "%A, %B %d, %Y"}}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Related
I have been looking at multiple answers to similar questions here on stack overflow and other sources, but simply cannot solve my problem.
I have a page consisting of index.md which has the following frontmatter:
# Feel free to add content and custom Front Matter to this file.
# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
title: title
layout: default
pagination:
enabled: true
---
And this is what I do to list my post:
<!--
Here is the main paginator logic called.
All calls to site.posts should be replaced by paginator.posts
-->
{% for post in paginator.posts %}
<li>
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
<h2>
<a class="post-link" href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
</h2>
</li>
{% endfor %}
</ul>
<!--
Showing buttons to move to the next and to the previous list of posts (pager buttons).
-->
{% if paginator.total_pages > 1 %}
<ul class="pager">
{% if paginator.previous_page %}
<li class="previous">
← Newer Posts
</li>
{% endif %}
{% if paginator.next_page %}
<li class="next">
Older Posts →
</li>
{% endif %}
</ul>
{% endif %}
<div class="pagination">
{% if paginator.previous_page %}
<a href="{{ paginator.previous_page_path }}" class="previous">
Previous
</a>
{% else %}
<span class="previous">Previous</span>
{% endif %}
<span class="page_number ">
Page: {{ paginator.page }} of {{ paginator.total_pages }}
</span>
{% if paginator.next_page %}
Next
{% else %}
<span class="next ">Next</span>
{% endif %}
</div>
I have added the gem to plugin list and to the gem file and run bundle install, and my configuration looks like this:
pagination:
enabled: true
per_page: 3
offset: 2
permalink: '/page/:num/'
title: ':title - page :num of :max'
limit: 0
sort_field: 'date'
sort_reverse: true
However when I run bundle exec jekyll s my test post is not listed.
But if I use:
{% for post in site.posts%}
{{post.title}}
{% endfor %}
My test post is listed as I intent. Anyone who can help me towards, what I am doing wrong, I simply cannot spot it.
Do you have a specific reason for including offset: 2 in the _config.yml? This will exclude the first 2 posts from appearing in the pagination so if you don't have at least 3 posts in your project nothing will be displayed.
Try removing the offset line from your config file, rerun bundle exec jekyll serve, and see if the functionality works.
For offset usage check the jekyll-paginate-v2 README section "Offsetting posts".
So I want to setup a for loop in Jekyll that only displays the latest event/item in the collection. (Organised by date)
Currently, this doesn't do much apart from sort the date by weight and cycle through the collection with a limit of one.
{% assign sorted_events = site.events | sort: "date" %}
{% for event in sorted_events limit:1 %}
<section class="venue-info wow fadeIn" data-wow-duration="1.2s" id="about">
<div class="upcoming-event">
<h1>Our Next Event</h1>
<h2>{{ event.title }}</h2>
<p>{{ event.description }}</p>
<a class="btn scroll" href="{{ event.url }}">Learn More</a>
</div>
{% endfor %}
Taking {{site.post}} as the collection for this example, we sort the collection of posts and then use the last tag to get the last element of the array.
To get the newest post:
{% assign newest = site.posts | sort: "date" | last %}
{{newest.title}}
{{newest.date}}
oldest post:
{% assign oldest = site.posts | sort: "date" | first %}
{{oldest.title}}
{{oldest.date}}
It should work for any other collection like site.events as your code refers.
I am creating a Jekyll theme where all user pages that implement the 'indexable' attribute in the front matter are rendered in the main landing page. So I have the 'frontpage layout:
---
layout: root
---
{% assign custom_pages = site.pages | where: 'indexable', true | sort: 'priority' | reverse %}
{% include header.html %}
{% for c_page in custom_pages %}
<div class="container {{ c_page.class | default: '' }}" >
{{ c_page.content }}
</div>
{% endfor %}
{% include footer.html %}
{% include javascripts.html %}
A sample page that will be processed:
---
layout: page
title: Us
permalink: /us/
indexable: true
priority: 10
class: us-page
---
<div class="row">
{% for member in site.data.members %}
<div class="col-sm-6">
<div class="card card-block">
<img src="{{ member.gravatar }}?s=256" alt="Avatar">
<h4 class="card-title text-xs-center">{{ member.name }}</h4>
<p class="card-text">{{ member.description | markdownify }}</p>
<p class="card-text">
{% for tag in member.expertise_areas %}
<span>{{ tag }}</span>
{% endfor %}
</p>
<a href="{{ member.blog }}" class="btn btn-primary" role="button" >Mi blog</a>
</div>
</div>
{% endfor %}
</div>
However the liquid tags are appearing unprocessed, like the same output {% raw %} would produce. Is there a way through I could do {{ c_page.content | magic_here }} in order to manually get rendered those tags?
EDIT. Screenshot:
EDIT2
Theme repository
Web implementation
Well, despite I still don't know whether the issue is in my code, I am posting how I managed to solve it. Basically I created a filter tag called liquefy which has been put in a .gem and whose main task is taking a text with markdown or/and liquid syntax as an argument which will be parsed and rendered.
Repo: https://github.com/sonirico/liquefy
Gem: https://rubygems.org/gems/liquefy
I have a Jekyll template pulling in text from data objects.
eg.
{% for speaker_hash in site.data.2015.speakers %}
{% assign speaker = speaker_hash[1] %}
<li>
<div class="speaker">
<img class="head" src="/img/2015/speakers/sample.jpg">
<h2> {{ speaker.name}} </h2>
</div>
</li>
{% endfor %}
However I would like to have each page specify what year its for with a page.year property.
Is it possible to create the same for loop but specify the year dynamically?
eg
{% for speaker_hash in site.data.[page.year].speakers %}
Answer yes.
1 - Your page.year must be a string as hash indexes are strings. So in you front matter : year: '2015'
2 - Get speakers depending on page.year :
{% for speaker_hash in site.data[{{page.year}}].speakers %}
I am using jekyll with Github pages for my website.
I am trying to make some posts not visible in the home but they can be linked from another post.
In the frontmatter I tryed to add a field visible like this:
---
layout: post
title:
excerpt:
visible:1
---
And then in the index.html file I did a if check:
<div class="posts">
{% for post in paginator.posts %}
{% if post.visible== 1 %}
<div class="post">
<h1>
<a href="{{ post.url }}">
{{ post.title }}
</a>
</h1>
<span class="post-date">{{ post.date | date_to_string }}</span>
<a class="subtitle" href="{{ post.url }}">
{{ post.excerpt }}
</a>
</a>
</div>
{% endif %}
{% endfor %}
</div>
The idea is that when I set 0 in the visible field, the post won't be visible in the home. Unfortanely this is not working, do you have any hints? Thanks
This works for me:
---
layout: post
title: About Lumen
published: false
---
See [About]({{ site.baseurl }}/about)
If you want to exclude a post/page from pagination you can add hidden: true to the YAML frontmatter. https://github.com/jekyll/jekyll-paginate/issues/6
Try to change your front-matter from visible:1 to visible: 1.
I just tried to reproduce your example on my machine, and I found that Jekyll seems to picky about the blanks in the front-matter.
With visible: 1, your example works for me.
With visible:1, Jekyll outputs the following error message while building the site:
YAML Exception reading C:/foo/bar.md: (): could not find expected ':' while scanning a simple key at line 5 column 1
...but it still finishes building and the generated site works, except that the post is not visible.
You need to modify the _layout/home.html file (In your case, it might be the index.html file).
Try to use an if-endif statement,like this:
{%- for post in site.posts -%}
{% if post.hide == null or post.hide == false %}
<li>
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
<span class="post-meta">{{ post.date | date: date_format }}</span>
<h3>
<a class="post-link" href="{{ post.url | relative_url }}">
{{ post.title | escape }}
</a>
</h3>
</li>
{% endif %}
{%- endfor -%}
Then, hiding a post by hide: true. For example:
published: true
title: Some title
layout: post
hide: true