This might be exceedingly obvious, but I'm making a Jekyll blog from scratch, and I'm using Shopify's Liquid.
Say I have a collection of posts:
post1, post2, post3, post4, post5, post6, post7, post8, post9, post10
I'm trying to render three posts at a time into a <div>. So it would look something like this:
<div>
post1
post2
post3
</div>
<div>
post4
post5
post6
</div>
<div>
post7
post8
post9
</div>
<div>
post10
</div>
How would I accomplish this in Liquid?
Something like ruby's splice would seem to suffice, but I could not find how to do this in Liquid.
{% for p in site.posts %}
{% assign counter = forloop.index | modulo:3 %}
{% if counter == 1 %}<div>{% endif %}
<h3>{{ p.title }}</h3>
{% if forloop.last or counter == 0 %}</div>{% endif %}
{% endfor %}
Related
I have this code on my blog site but I want the loop to stop in, for example, the second item/article or third
<div class="container mar2ritlft">
<div class="content3col">
{%- for article in collections.article | reverse -%}
{% include 'article-post.njk' %}
{%- endfor -%}
</div>
</div>
Ps: the "collections.article" is blogs that have "article" tag in the metaData
You may want to reconsider your approach on looping through multiple articles by allowing the index of your loop to have a relationship to the actual articles. If so, you should be able to pull off the following...
{%- for articleTitle in collections.article | reverse -%}
{% if loop.index > 2 %}
{{articleTitle}} {# a collection of blog titles???#}
{% include "articles/article-post" + loop.index + ".njk" %}
{% endif %}
{%- endfor -%}
In your articles/ directory, you would have something like...
article-post1.njk
article-post2.njk
article-post3.njk
article-post4.njk
...etc...
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 %}
I'm looking to display information from a csv file on a jekyll-generated site. I need to search for the appropriate category in the csv file, then display four of them on the page. Filtering to the selected category is no problem, but I'm having difficulty limiting the output to four.
Is there a way to apply a limit to an if statement? Or is there any other way to write this? I'm not that savvy in Liquid, so it's extremely likely that I'm missing an obvious solution.
Basic code to make all the applicable data show up on the screen:
{% for study in site.data.studies %}
{% if study.category contains "foo" %}
<div class="col-sm-3">
<h3>{{ study.title }}</h3>
<div class="list-of-attributes">
<h6>Attributes: </h6>
{{ study.attributes }}
</div>
</div>
{% else %}
{% continue %}
{% endif %}
{% endfor %}
I've also tried unless and tablerow, neither of which worked at all. Am I at least on the right track? How can I limit this forloop to stop at four items?
Thank you!
Ideally data should be filtered before rendering however you can also create a variable in liquid to hold the number of stuff rendered
{% assign rendered = 0 %}
{% for study in site.data.studies %}
{% if study.category contains "foo" %}
<div class="col-sm-3">
<h3>{{ study.title }}</h3>
<div class="list-of-attributes">
<h6>attributes: </h6>
{{ study.attributes }}
</div>
</div>
{% assign rendered = rendered | plus: 1 %}
{% if rendered == 4 %}
{% break %}
{% endif %}
{% endif %}
{% endfor %}
The ideal solution as I said would be to create your own filter which does all the work (filter by category and limit the number of results)
{% assign filtered = site.data.studies | my_custom_filter %}
{% for study in filtered %}
<div class="col-sm-3">
<h3>{{ study.title }}</h3>
<div class="list-of-attributes">
<h6>attributes: </h6>
{{ study.attributes }}
</div>
</div>
{% endfor %}
Presuming that your category is a string, not an array, you can do :
{% assign selected = site.data.studies | where: 'category','foo' %}
{% for study in selected limit:4 %}
<div class="col-sm-3">
<h3>{{ study.title }}</h3>
<div class="list-of-attributes">
<h6>Attributes: </h6>
{{ study.attributes }}
</div>
</div>
{% endfor %}
And if your category is a string like "foo, bar, baz" or and array of strings you can use the jekyll 3.2 where_exp filter like this :
{% assign selected = site.data.studies | where_exp:"item", "item.category contains 'foo'" %}
I am working on a Jekyll project. This is a blog with posts which have categories.
I would like to succeed in having a sidebar on the right side listing the categories and the count of posts related to this category AND when clicking on the category itself, having the list of the posts related to this category.
For now, I succeeded in having the list of categories with their counts but not the display of the posts. Here is the code :
<ul class="tag-box inline">
{% assign tags_list = site.categories %}
{% if tags_list.first[0] == null %}
{% for tag in tags_list %}
{{ tag | capitalize }} <span>{{ site.tags[tag].size }}</span>
{% endfor %}
{% else %}
{% for tag in tags_list %}
<div>{{ tag[0] | capitalize }} <span> ({{ tag[1].size }}) </span></div>
{% endfor %}
{% endif %}
{% assign tags_list = nil %}
</ul>
I was looking for some solutions on Internet and some of them were explaining that I should create a folder category and under this folder as many folder as categories I have with an index.html to display the categories. However, this is a lot of duplicated content and I don't know if it is the best way to do.
Thank you for your help!
As you cannot use plugins, you will have to create one page for each category.
In order to avoid repeating content, you can factorize with help of layout chaining. Your category pages will use category_index.html as layout, that will itself use default.html.
Sidebar
<ul class="tag-box inline">
{% for category in site.categories %}
<div>{{ category[0] | capitalize }} <span> ({{ category[1].size }}) </span></div>
{% endfor %}
</ul>
If you want urls like category/toto/ you have to set permalink: pretty in _config.yml.
A category page : category/toto.html
---
layout: category_index
category: toto
---
That's all.
_layouts/category_index.html
---
layout: default
---
<div class="home">
<h1 class="page-heading">Posts in category : {{ page.category }}</h1>
<ul class="post-list">
{% for p in site.categories[page.category] %}
<li>
<h2>{{ p.title }}</h2>
</li>
{% endfor %}
</ul>
</div>
I am attempting to edit blog.liquid so that on a particular blogs listing, there is a customize graphic above it.
Something similar to this:
<div id="page-header">
<h2 id="page-title">{{ blog.title }}</h2>
</div>
{% if blog.new-years-revolution %}
<p class="alignCenter">**[custom code here]**
</p>
{% endif %}
{% for article in blog.articles %}
<h3 class="blog">
{{ article.title | escape }}</h3>
{% if article.excerpt.size > 0 %}
{{ article.excerpt }}
{% else %}
<p>{{ article.content | strip_html | truncate: 800 }}</p>
{% endif %}
{% endfor %}
Essentially I don't want it to show up on any other blogs, just this particular one. So a basic if statement that says "if on this blog, show this". I'm not sure whether to use the blog.id or blog.handle, and depending on which one, how to reference that particular handle so that this image only shows up on that one.
Hopefully I'm explaining clearly enough. Been googling for a while and haven't found anything helpful yet.
That should be:
{% if blog.handle == 'new-years-revolution' %}
<p class="alignCenter">**[custom code here]**</p>
{% endif %}