Multi-row blog list in Jekyll
These are actually two questions.
Number one: How to display two posts in each row with Jekyll/Liquid?
I answered two similar questions yesterday:
- For loop, wrap every two posts in a div
(one solution for a fixed number of posts - like the last 10 posts in groups of two on the front page - and one solution for an infinite number of posts) - Jekyll automatically processing rows
(another solution with an infinite number of posts, but with four posts per group and with a detailed step-by-step explanation)
Number two: How to achieve a design similar to the one in your screenshot in Bootstrap?
Bootstrap has a page with example designs that you can steal. Especially these two:
- Jumbotron
- Narrow jumbotron
Look at the source code of the example pages - basically, you just have to wrap the posts in a few <div>
s with the right classes.
For example, this is the source code for the three blocks in the Jumbotron example
<div class="row">
<div class="col-md-4">
<h2>Heading</h2>
<p>blah</p>
</div>
<div class="col-md-4">
<h2>Heading</h2>
<p>blah</p>
</div>
<div class="col-md-4">
<h2>Heading</h2>
<p>blah</p>
</div>
</div>
You just need to modify the code examples from my other answers (linked above) so that they generate a similar combination of <div>
s.
Plus, you may want to read about Bootstrap's grid system to get the columns right (e.g. the class col-md-4
in the example code above varies depending on the number of columns you want).
Finally, a real-world example: My blog has a similar listing on the front page.
This is a fixed number of posts (the last nine, three rows of three), so I'm using the first approach from this answer.
The source code of the front page is here.
Note that I'm still on Bootstrap 2 (not 3), so you can't just copy and paste the CSS classes from my source code!
Two Columns - One Ordered List Jekyll
Here's an idea: Use one column and add style="column-count: 2"
to that. Done!
More css column options: https://css-tricks.com/almanac/properties/c/columns/#article-header-id-0
Creating two blogs on same website (Jekyll GitHub) without altering layout/formatting
You've removed the posts
collection from your _config.yml
which was setting the default feature_image
for all posts. Unless you add that back in or include the overrides in each individual post it will not display the header (it may or may not also affect the rest of the styles):
collections:
media:
title: Media # Needed for Siteleaf
output: true
description: "Recent discussions with the media." # The post list page content
feature_text: |
Sharing our motivations and
opinions with the media.
feature_image: "https://picsum.photos/2560/600?image=866"
You're not actually using a media collection in either blog/index.html
nor media/index.html
, you're using the post.categories
for filtering in the end, which will still causes some weird pagination once you start getting things rolling.
You may want to look at using the separate collections and then pre-building your site using paginator v2 (https://github.com/sverrirs/jekyll-paginate-v2/blob/master/README-GENERATOR.md) which will allow for pagination of different collections.
Edit 2020-01-23
Taking a new look at your repository, you still only have one (posts) collection. Therefore the logic for reading feature_*
is being shared. If you look at the include site_feature.html
you can see how the feature_image is being parsed out of the collections.
{% assign collectiondata = site.collections | where: "label", page.collectionpage | first %}
Which in your case is why Blog and Media both have the second image ?image=213
. Your blog.html
and media.html
still have the front matter collectionpage: post
.
I still think you're going down a slippery slope which will result in things not working exactly as you want them once you get more and more posts by doing it this way.
Jekyll every 4th item in loop display differently
I think you can just walk through your items while checking the modulo. Like this:
<div class="row blogitems">
{% for post in site.posts %}
{% assign mod3 = forloop.index | modulo: 3 %}
<div class="col-md-6"><p>{{ post.title }}</p></div>
{% if mod3 == 0 %}<div class="col-md-6"><p>THIS IS NOT A POST</p>{% endif %}
{% if mod3 == 0 or mod3 == 2 %}</div><div class="row blogitems">{% endif %}
{% endfor %}
</div>
How can I have multiple authors for one post in Jekyll?
If you want to specify multiple authors in your YAML Frontmatter, then you are going to want to use YAML's list syntax like you did with categories and tags, like this:
author:
- usman
- someone_else
This will be useful for dynamically injecting author information into each of the posts.
As for allowing multiple people to contribute to the same article, I don't think this has anything to do with Jekyll or what is specified in the Frontmatter. This is an issue of having your Jekyll content hosted in a shared place (such as on GitHub, like many do) where both you and your collaborator can both work on the file. That being said, be aware that you may run into nasty merge conflicts if you work on that same markdown file in parallel.
Update
This is an update based on the OP's edits to the original question.
A simple hacked approach would be to set your author tag like this:
author: Usman and Someone_Else
This doesn't give you much flexibility though. A better solution, which would require you to modify the template you are using, would be to do something like the following:
First, setup your YAML Front Matter so that it can support multiple authors.
authors:
- Usman
- Someone_else
Now, you modify the template to go through the authors specified in the YAML Front Matter.
<p>
{% assign authorCount = page.authors | size %}
{% if authorCount == 0 %}
No author
{% elsif authorCount == 1 %}
{{ page.authors | first }}
{% else %}
{% for author in page.authors %}
{% if forloop.first %}
{{ author }}
{% elsif forloop.last %}
and {{ author }}
{% else %}
, {{ author }}
{% endif %}
{% endfor %}
{% endif %}
</p>
Resulting HTML:
If no authors are specified:
<p>No author</p>
If one author is specified:
<p>Usman</p>
If two authors are specified:
<p>Usman and Someone_Else</p>
If more than two authors are specified:
<p>Usman, Bob, and Someone_Else</p>
For loop, wrap every two posts in a div
I know I'm late to the game but I found what I feel is a fairly elegant solution that doesn't feel hacky.
With for
loop's limit
and offset
params, we can iterate one row at a time, N posts per row.
First, we count the number of rows we'll need to enumerate over:
{% assign rows = site.posts.size | divided_by: 2.0 | ceil %}
The Ruby equivalent would be rows = (posts.size / 2.0).ceil
(odd numbers get their own row).
Next, we'll iterate over the rows:
{% for i in (1..rows) %}
<div>
Now we need to calculate the collection offset with (i - 1) * 2
(using forloop.index0
):
{% assign offset = forloop.index0 | times: 2 %}
Then we can iterate over the slice of posts starting at the row's offset (equivalent to posts[offset, 2]
in Ruby):
{% for post in site.posts limit:2 offset:offset %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
Close the row div
element and for loop:
</div>
{% endfor %}
That's it!
In Ruby, this would be:
rows = (posts.size / 2.0).ceil # the number of rows
(1..rows).each do |i|
offset = (i - 1) * 2
# <div>
posts[offset, 2].each do |post|
# <a href="#{post.url}>#{post.title}</a>
end
# </div>
end
All together now, in Liquid:
{% assign rows = site.posts.size | divided_by: 2.0 | ceil %}
{% for i in (1..rows) %}
{% assign offset = forloop.index0 | times: 2 %}
<div>
{% for post in site.posts limit:2 offset:offset %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
</div>
{% endfor %}
Hope this helps someone!
Jekyll multiple custom repeatable content
I figured out the problem. First one is the folder structure. Simply keep all the postfiles in the _posts/ file in the root directory. The second one is the capitalization of the category name in your liquid tag. Although there are no semantic differences between JOBS and jobs, when used in liquid arguments, they act in a weird way. So try to keep them in lower case. Simply replace the line
{% for post in site.categories.JOBS %}
with this
{% for post in site.categories.jobs %}
This won't solve your problem right away. Jekyll expects you to wrap your posts YAML matter between --- 3 dashes. So you've to use the following format for you post markdown and everything will work:
---
title: test
category: jobs
length: April 2010 – April 2012
position: Junior Developer
---
Content to be displayed
Jekyll automatically processing rows
Note:
I couldn't get the sorted_for
plugin to work in my machine, so I tested my solution with a regular for
instead.
Step 1
As you can't use forloop.index
because you're filtering out some pages, you need to count the loops by yourself, by writing to a variable with assign
.
The following code will just list your pages with a correct loop iterator (by counting just the pages that are actually listed):
{% assign loopindex = 0 %}
{% for page in site.pages %}
{% if page.type == 'project' %}
{% assign loopindex = loopindex | plus: 1 %}
<div class="span3">{{ loopindex }} {{ page.title }}</div>
{% endif %}
{% endfor %}
Step 2
You need to display <div class="row">
with every first row and </div>
with every fourth row.
To find the first and fourth rows, you can use modulo
:
{% assign loopindex = 0 %}
{% for page in site.pages %}
{% if page.type == 'project' %}
{% assign loopindex = loopindex | plus: 1 %}
{% assign rowfinder = loopindex | modulo: 4 %}
<div class="span3">{{ loopindex }} {{ rowfinder }} {{ page.title }}</div>
{% endif %}
{% endfor %}
rowfinder
will always repeat the sequence 1, 2, 3, 0.
Step 3:
So you display <div class="row">
when rowfinder
is 1
, and </div>
when rowfinder
is 0
:
{% assign loopindex = 0 %}
{% for page in site.pages %}
{% if page.type == 'project' %}
{% assign loopindex = loopindex | plus: 1 %}
{% assign rowfinder = loopindex | modulo: 4 %}
{% if rowfinder == 1 %}
<div class="row">
<div class="span3">{{ page.title }}</div>
{% elsif rowfinder == 0 %}
<div class="span3">{{ page.title }}</div>
</div>
{% else %}
<div class="span3">{{ page.title }}</div>
{% endif %}
{% endif %}
{% endfor %}
Step 4:
Now there's only one small thing left: when the number of pages is not a multiple of 4, there's a </div>
missing at the end.
When the number of pages is a multiple of 4, the last value of rowfinder
will be 0
.
So we just need to display the </div>
when the value of rowfinder
is anything else but 0
.
So just put this after the for loop:
{% if rowfinder != 0 %}
</div>
{% endif %}
...and that's it!
Related Topics
Selected Text Background Color
How to Style Form Drop Down Lists
@Media: If Samsung Galaxy S4 Is 1920X1080
Difference Between Ng-Class and Ng-Style
Using Cors Headers with CSS Background-Image
Way to Add Custom Class When Using Ngx-Bootstrap Modalservice
Object Oriented CSS: Should It Matter
Can Visual Studio 2013 Generate CSS Files from .Less Files
Width: 100% with Position: Absolute
How to Make a Bullet List Align with Text in CSS
Fade in Fade Out on Image Hover Using CSS3
Reverse Svg Line Drawing Animation
What Is The Effect of Content: "\0020"; Property
When and Why Should We Use View Encapsulation in Angular
How to Add Vertical Spacing Between Block Elements, But Not Top and Bottom