I've run into an issue when using Jekyll (which uses the Liquid templating language), the plugin jekyll-paginate-v2 and offset.
The problem: I have a featured section on my blog that always shows the most recent post. The other posts appear below, 10 per page using paginate.
I tried to simply show them using {% for post in paginator.posts offset:1 %}, but this is flawed in two ways:
it only shows 9 posts per page instead of 10
it offsets the first post on each page, so that the 1st, 10th, 20th, etc. posts are hidden, which is not what I want
What I'm trying to achieve: a loop that always ignores the post at index 0 and shows everything else as it normally would.
Am I just using offset wrong, or is this a bug in jekyll-paginate-v2?
Right now I've "fixed" it by doing the following, but it's not ideal as the first page only shows 9 posts:
<div class="articles-showcase row post-list">
{% assign featuredpost = site.posts.first %}
{% for post in paginator.posts %}
{% if post == featuredpost %}
{% continue %}
{% else %}
<!-- Article Card -->
<div class="article-detail-box col-lg-6 col-md-6 col-sm-12 card-article-div" data-cat="{{post.category | join: ','}}">
<div class="card card-article box-shadow h-100">
<div class="img-div text-center post-card-header bg-gray">
<img src="{{ site.baseurl }}{{post.image}}" alt="{{post.title}}">
</div>
<div class="card-article-body">
<p class="author-name">{{post.author}} | {{ post.date | date: '%B %d, %Y' }}</p>
<a href="{{site.baseurl}}{{post.url}}">
<h5>{{post.title}}</h5>
</a>
<div class="article-description">{{post.content}}</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
I raised this as an issue to the jekyll-paginate-v2 developers, and it has now been solved: https://github.com/sverrirs/jekyll-paginate-v2/issues/100
As a quick fix you should be able to add a front-matter property to the latest post manually:
---
layout: page
pagination:
enabled: false
---
Otherwise, you either have to exclude the paginator-v2 plugin and write your own logic for pagination or else extend the plugin in your _plugins dir so that the posts data sent to the paginate plugin already excludes the first (actually last because the reverse sorting will be done afterwards.) post.
I've hacked together a flawed solution that I'm using until something better comes along. I'll share it here for now:
<div class="articles-showcase row post-list">
{% if paginator.page == 1 %}
{% for post in site.posts limit:11 %}
{% if post == featuredpost %}
{% continue %}
{% else %}
<!-- Article Card -->
<div class="article-detail-box col-lg-6 col-md-6 col-sm-12 card-article-div" data-cat="{{post.category | join: ','}}">
<div class="card card-article box-shadow h-100">
<div class="img-div text-center post-card-header bg-gray">
<img src="{{ site.baseurl }}{{post.image}}" alt="{{post.title}}">
</div>
<div class="card-article-body">
<p class="author-name">{{post.author}} | {{ post.date | date: '%B %d, %Y' }}</p>
<a href="{{site.baseurl}}{{post.url}}">
<h5>{{post.title}}</h5>
</a>
<div class="article-description">{{post.content}}</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% if paginator.page > 1 %}
{% for post in paginator.posts %}
<!-- Article Card -->
<div class="article-detail-box col-lg-6 col-md-6 col-sm-12 card-article-div" data-cat="{{post.category | join: ','}}">
<div class="card card-article box-shadow h-100">
<div class="img-div text-center post-card-header bg-gray">
<img src="{{ site.baseurl }}{{post.image}}" alt="{{post.title}}">
</div>
<div class="card-article-body">
<p class="author-name">{{post.author}} | {{ post.date | date: '%B %d, %Y' }}</p>
<a href="{{site.baseurl}}{{post.url}}">
<h5>{{post.title}}</h5>
</a>
<div class="article-description">{{post.content}}</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
</div>
The main problem with it is the 2nd paginated page shows the last article on the 1st page again. For me that's better than only showing 9 posts on the first page, however. Any better solution would be greatly appreciated!
Related
I am working with a bootstrap template for a django app
<div class="row">
<div class="col-12">
<div class="card-deck-wrapper">
<div class="card-deck">
{% if posts %}
{% for post in posts %}
<div class="card d-block">
<img class="card-img-top" src="{{ post.image }}" height="200">
<div class="card-body">
<h5 class="card-title">{{ post.title }}</h5>
<p class="card-text">{{ post.description }}</p>
<p class="card-text">
<small class="text-muted">{{ post.creation_date }}</small>
</p>
</div>
</div> <!-- end card-->
{% endfor %}
{% endif %}
</div> <!-- end card-deck-->
</div> <!-- end card-deck-wrapper-->
</div> <!-- end col-->
</div><!-- end row -->
Mi main target is to repeat each "card" just 3 times, otherwise the templates looks awful, but have no idea how to iterate just 3 times, and at the 4th, 7th, 10th, and so on time, create a new "card-deck" to continue with post 4-5-6, then another "card-deck" for post 7-8-9 and so on
Thank you!
I have changed it a little bit at least to know how many "card-deck" should it have in the views
def blogPost(request):
posts = Post.objects.filter(state=True)
numberOfPosts = len(posts)
addOneDeck = 0
if (numberOfPosts%3) > 0:
addOneDeck = 1
numberOfDecks = ((int(numberOfPosts/3))+addOneDeck)
context = {"posts":posts, "decks":numberOfDecks}
return render(request,"blog.html", context)
Are you looking for forloop counter in templates? django has builtin for that
{% for post in posts %}
{{ forloop.counter }} #The current iteration of the loop (1-indexed)
{{ forloop.counter0 }} #The current iteration of the loop (0-indexed)
{% if forloop.counter0|divisibleby:3 %}
<p>print {{ forloop.counter0 }}</p>
{% else %}
<p> do something else</p>
{% endif %}
{% endfor % }}
you can use within if else conditions then.
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#for
I'm trying to create my first blog on Jekyll. I'm stuck on one thing: I have a section for one of my categories, let's say "news":
<section class="news">
<div class="container">
<div class="row no-gutters">
{% for post in site.categories.news limit: 2 offset: 0 %}
{% include news-item-col-6.html %}
{% endfor %}
{% for post in site.categories.news limit: 3 **offset: 2** %}
{% include news-item-col-4.html %}
{% endfor %}
</div>
</div>
</section>
news-item-col-6:
{% if post.thumb != 0 %}
<div class="col-md-6">
<div class="pattern">
<div class="overlay item-title" style="background-image: url({{ post.thumb }});">
<div class="item-title-content">
<h3>{{ post.header }}</h3>
</div>
</div>
</div>
</div>
{% endif %}
news-item-col-4:
{% if post.thumb != 0 %}
<div class="col-md-4">
<div class="pattern">
<div class="overlay item-title" style="background-image: url({{ post.thumb }});">
<div class="item-title-content">
<h3>{{ post.header }}</h3>
</div>
</div>
</div>
</div>
{% endif %}
my posts tp
---
layout: post
title: title | site.com
header: title
description: description
categories: categories url
catname: News
image: "images/URL /to image/1.jpg"
thumb: "images/URL /to thumb/1t.jpg"
permalink: "blog/:categories/:year-:month-:day-:slug.html"
---
The problem is that not all of my posts will have background thumb, and all I want to do is to ignore the posts which has no post.thumb. and the code is works, but unfortunately col-md-4 block's offset is not ignoring post's order with no post.thumb.
The pictures below shows what I want:
This is how should be, if all my posts have post.thumb(bg_image)
This is how should be, if my post Item2 has no post.thumb(bg_image), it just not showing up in section
And this is how my code works
So what should I do to make it work right?
Just use a custom counter, like this:
{% assign counter = 0 %} <!-- create a custom counter and set it to zero -->
{% for post in site.categories.news %} <!-- loop through the posts in news -->
{% if post.thumb %} <!-- check if the post has a thumbnail -->
{% assign counter = counter | plus: 1 %} <!-- increment the counter if it does -->
{% if counter < 3 %} <!-- if this is the first or second counted post -->
{% include news-item-col-6.html %} <!-- include the col-6 element -->
{% elsif counter < 6 %} <!-- else -->
{% include news-item-col-4.html %} <!-- include the col-4 element -->
{% endif %}
{% endif %}
{% endfor %}
I am using jekyll to populate my blog page with blog posts. I want there to be two posts for every div with the "row" class, but I also want every 4th item to be an ad (skip over the post and move to the next row but still include something else that's not a post).
So if there are 6 posts, the output should look like this
<div class="row"> <!-- 1st row -->
<div> {{ post.title }} </div> <!-- 1st post, no skip -->
<div> {{ post.title }} </div> <!-- 2nd post, no skip -->
</div>
<div class="row"> <!-- 2nd row -->
<div> {{ post.title }} </div> <!-- 3rd post, no skip -->
<div> THIS IS NOT A POST </div> <!-- skip post 4, put something else -->
</div>
<div class="row"> <!-- 3rd row -->
<div> {{ post.title }} </div> <!-- 4th post, because last item was skipped to display something else -->
<div> {{ post.title }} </div> <!-- 5th post, no skip -->
</div>
<div class="row"> <!-- 4th row -->
<div> {{ post.title }} </div> <!-- 6th post, no skip -->
</div>
<!-- and so on, so every 4th item is not a post, but the posts continue after the skipped post -->
I have the post loop part but I cant figure out how to add the SKIP
{% assign rows = site.posts.size | divided_by: 2.0 | ceil %}
{% for i in (1..rows) %}
{% assign offset = forloop.index0 | times: 2 %}
<div class="row blogitems">
{% for post in site.posts limit:2 offset:offset %}
<div class="col-md-6">
<p>{{ post.title }}</p>
</div>
{% endfor %}
</div>
{% endfor %}
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>
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 am trying to grasp how blog works in Shopify.
First of all I could not find a solution for having categories or sub categories for blog posts.
All I can do is create multiple blogs and consider them as categories. If I go with this option I have trouble displaying blog titles on home page along with each post so visitors can understand what kind of post it is. I have tried this with tag but in that case I have to sacrifice real usage of tags because a post used to have more than one tag in it. My code looks like:
<section class="trend-sec">
<div class="container">
<h2 class="sec-title">Trending</h2>
<div class="row">
{% for article in blogs.trending.articles limit:4 %}
<div class="col-md-3 col-sm-6">
<div class="img-wraper">
<a href="{{ article.url }}">
<div class="img-cap-lab">
<h4>{{ article.tags }}</h4>
</div>
{% if article.image %}
{% assign image_alt = article.title | escape %}
{{ article | img_url: 'medium' | img_tag: image_alt, 'article__image' | link_to: article.url }}
{% else %}
</div>
{% endif %}
<div class="img-desc">
<h3>{{ article.title }}</h3>
<h5>by {{ article.author }}, {{ article.published_at | date: "%b %d %Y" }}</h5>
</div>
</a>
</div>
</div>
{% endfor %}
</div>
</div>
</section>