Paginate highly filtered Jekyll collection - jekyll

I’m building an ICO Website. The website contains a ‘coins’ collection, this collection contains all the ico coin pages. I have then created pages such as https://moonlandingnetwork.netlify.com/upcomingico , https://moonlandingnetwork.netlify.com/activeico etc to display these coins based on whether they are upcoming, active or ended. I used this code to filter these coins based on the date and based on whether the coin is featured.
{% assign featuredcoins = site.coins | where: ‘ico.featured’, ‘true’ %}
{% assign regularcoins = site.coins | where: ‘ico.featured’, ‘false’ %}
{% assign timeframe = 86400 %}
{% assign current_date = “now” | date: “%s” | minus: timeframe %}
{% assign featuredUpcoming = “” | split: ‘,’ %}
{% for coin in featuredcoins %}
{% assign pre_ico_end_date = coin.pre-ico.end-date | date: “%s” | plus: 0 %}
{% assign ico_start_date = coin.ico-detail.start-date | date: “%s” | plus: 0 %}
{% if current_date > pre_ico_end_date and ico_start_date > current_date %}
{% assign featuredUpcoming = featuredUpcoming | push: coin %}
{% endif %}
{% endfor %}
{% assign regularUpcoming = “” | split: ‘,’ %}
{% for coin in regularcoins %}
{% assign pre_ico_end_date = coin.pre-ico.end-date | date: “%s” | plus: 0 %}
{% assign ico_start_date = coin.ico-detail.start-date | date: “%s” | plus: 0 %}
{% if current_date > pre_ico_end_date and ico_start_date > current_date %}
{% assign regularUpcoming = regularUpcoming | push: coin %}
{% endif %}
{% endfor %}
{% for coin in featuredUpcoming limit: 2 %}
<li>Featured Coin</li>
{% endfor %}
{% for coin in regularUpcoming %}
<li>Regular Coin</li>
{% endfor %}
Where I’m stuck is I need to paginate this. I know jekyll doesn’t support pagination of collections. I came across Jekyll paginate V2, Octopress Paginate and this code https://gist.github.com/Phlow/5613fb3f18946f577f071e2a258749a3 in my research. But i couldn’t get any of those to work.
I also require the pagination to work in such a way that the featured coins change on each new page along with the regular coins. Can somebody help me direct on what i should do.

Related

How to count current showing products in Shopify 2.0 dawn theme?

In collection page of dawn(version 5.0.0) theme Shopify, there is and inbuilt functionality to see the total number of products.
I want show that how many current product are showing when more products are getting into pagination.
There is 2 modification in 2 files of dawn theme.
in facets.liquid file add below code under the span id ProductCountDesktop.
{% if next_link %}
{{ offset | plus: 1 }} - {{ offset | plus: page_size }} of
{% else %}
{% capture itemsOnCurrentPage %}
{{ results.all_products_count | minus: offset }}
{% endcapture %}
{% if results.all_products_count > 0 %}{{ offset | plus: 1 }}{% else %}{{ offset }} {% endif %}- {{ offset | plus: itemsOnCurrentPage }} of
{% endif %}
now replace render: facets with below code in main-collection-product-grid.liquid file.
{%- paginate collection.products by section.settings.products_per_page -%}
{% render 'facets', results: collection, enable_filtering: section.settings.enable_filtering,
filter_type: section.settings.filter_type, enable_sorting: section.settings.enable_sorting, collapse_on_larger_devices: section.settings.collapse_on_larger_devices,
offset : paginate.current_offset,next_link:paginate.next.is_link,page_size:paginate.page_size %}
{%- endpaginate -%}

Jekyll liquid syntax for loading _data subfolders for Staticman comments?

I’m trying to set up staticman comments and have gotten all the code implemented to save comments correctly, but the comments are not loading.
My site has multiple types of pages so I have recipe comments save in _data/comments/recipes/recipe-name/entry12233445430320.yml
The problem is in this code:
{% assign urlslug = page.url | remove:'.html' | remove_first:'/' | split: '/' %}
{% assign urlfolder = urlslug[0] %}
{% assign urlfilename = urlslug[1] %}
<p>folder: {{urlfolder}}</p><p>filename: {{urlfilename}}</p>
<h2>{{post_slug}}</h2>
{% if site.data.comments.recipes[urlfilename] %}
<!-- Start static comments -->
<div id="comments" class="js-comments">
<h2 class="page__section-label">
{% if site.data.comments.recipes[urlfilename].size > 1 %}
{{ site.data.comments.recipes[urlfilename] | size }}
{% endif %}
Comments test 1
</h2>
<h2> {{ site.data.comments.recipes[urlfilename] }} </h2>
{% assign comments = site.data.comments.recipes[urlfilename] | sort | where_exp: 'entry', 'comment[1].replying_to_uid == blank' %}
<h3>a: {{ comments }} </h3>
<h3>b: {{ comments[0] }} </h3>
{% for comment in comments %}
<h3>comment test 2</h3>
{% assign index = forloop.index %}
<!-- {% assign replying_to = comment[1].replying_to | to_integer %}
{% assign avatar = comment[1].avatar %} -->
{% assign email = comment[1].email %}
{% assign name = comment[1].name %}
{% assign url = comment[1].url %}
{% assign date = comment[1].date %}
{% assign message = comment[1].message %}
{%- assign uid = comment[1]._id %}
{% include comment.html index=index replying_to=replying_to avatar=avatar email=email name=name url=url date=date message=message %}
{% endfor %}
</div>
<!-- End static comments -->
{% endif %}
I'm successfully accessing the right comment and printing it on the page in raw format, but I can't make it print the comment correctly.
Any help is greatly appreciated.

jekyll: combine limit and where and reverse

Using Jekyll i'd like to:
iterate through all the pages
where the page.path is not the current path
where the page.categories contains "featured"
reverse them(most recent first)
limit 3
i'm having problems when getting all those filters together
{% assign posts = site.posts | reverse %}
{% for post in posts limit:3 %}
{% if post.categories contains 'featured' and post.path != page.path %}
{% include card.html post=post %}
{% endif %}
{% endfor %}
right now the limit is not working properly because the inner if will prevent a few items from being rendered.
Assign 0 to a counter variable before entering your loop. Don't set a limit on the loop, but instead set another condition on your counter being below your limit, and increment the counter using Liquid's plus filter every time you meet your criteria and output the card.
{% assign posts = site.posts | reverse %}
{% assign counter = 0 %}
{% for post in posts %}
{% if counter < 3 and post.categories contains 'featured' and post.path != page.path %}
{% include card.html post=post %}
{% assign counter = counter | plus: 1 %}
{% endif %}
{% endfor %}
A more complex example
I'm basing all of this on the looping I use myself. My condition is a little more complex: I check for any shared tag with the current page. I've included this as a further example below.
{% assign counter = 0 %}
{% for post in site.posts %}
{% if counter < 4 %}
{% if post.url != page.url %}
{% assign isValid = false %}
{% for page_tag in page.tags %}
{% for post_tag in post.tags %}
{% if post_tag == page_tag %}
{% assign isValid = true %}
{% endif %}
{% endfor %}
{% endfor %}
{% if isValid %}
{% include article_card.html %}
{% assign counter = counter | plus: 1 %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
Why where fails
Although Liquid has a where filter, it can only do exact comparisons, so you have to reinvent the wheel like this in order to achieve the where-like scenario for more complex conditions. This does make for a lot of looping through site.posts, but Jekyll being a preprocessor means the penalty of using a somewhat inefficient improvised where-type looping is only a compile-time concern, not a runtime one. Even so, to mitigate this cost as much as possible, I opt for having the counter condition be the first that Jekyll calculates.

Jekyll linked documents in collections?

In Jekyll's Front Matter, is there a way to make references to another document?
I have a custom collection, and would like to add meta-data in each document such as "parent-topic" (a link to the parent), and "children" (an array of documents), or "related-topics".
With such a reference I could access the linked documents' meta-data, such as their title, url, or other arbitrary data.
The idea is a hierarchy of documentation, with topics, sub-topics, sub-sub-topics, etc. And a topic page could show a list of child topics, or a breadcrumb for the parent topics, etc.
Real question that deserve a real answer. I also got this documentation problem. Following advise from Ben Balter, I started to use collections. The idea was to make
a table of content reflecting topic/sub-topics arrangement,
a breadcrumb on each page
I gave up because it was simplest to code against pages. So, here's how I do documentation with pages.
Prerequisites :
documentation is in a folder eg : documentation
permalink is set to pretty in _config.yml
folders hierarchy describes documentation organization
example
documentation
|--index.html
|--chapter-1
| |--index.html
|
|--chapter-2
| |--index.html
| |
| |--part-1
| | |--index.html
| | |--subpart-1
| | |--index.html
| |--part-2
| | |--index.html
| |
| |--part-3.html
Note : documentation/chapter-2/part-2/index.html can also be documentation/chapter-2/part-2.html, because permalink is set to pretty, generated page will be at documentation/chapter-2/part-2/index.html.
Pages at a same level are sorted depending on a weight front matter variable. This can be anything you want.
Numbering by tenth allows easy insertion for new doc.
example front matter
---
title: My title
weight: 10
---
documentation get default variables values from _config.yml
example
defaults:
-
scope:
path: "documentation"
type: pages
values:
isDoc: true # allows quick extraction from site.pages
layout: page
Once those prerequisites are in place, it's easy to print a table of content and a breadcrumb.
Table of content
_includes/show-children.html
{% assign parentDir = include.dir %}
{% if parentDir == nil %}<h1>You must specify a root directory</h1>{% endif %}
{% assign allDocs = include.docs %}
{% if allDocs == nil %}{% assign allDocs = site.pages | sort: "weight" %}{% endif %}
{% assign level = include.level %}
{% if level == nil %}{% assign level = parentDir | remove_first: "/" | split:"/" | size %}{% endif %}
{% assign maxLevel = include.maxLevel %}
{% if maxLevel == nil %}{% assign maxLevel = 100 %}{% endif %}
{% assign nextLevel = level | plus : 1 %}
{% comment %}+++++++++++++++++++++++++++++++++++++++++++++++++
Looking for all page in this path with the same level (siblings)
This avoid to deep recursion and error like :
__ Liquid Exception: Nesting too deep __
+++++++++++++++++++++++++++++++++++++++++++++++++{% endcomment %}
{% assign siblings = "" | split: "/" %}
{% for s in allDocs %}
{% assign sPageLevel = s.url | remove_first: "/" | split:"/" | size %}
{% if sPageLevel == level and s.url contains parentDir %}
{% if s.title %}{% assign siblings = siblings | push: s %}{% endif %}
{% endif %}
{% endfor %}
<ul>
{% for p in siblings %}
<li><a href="{{site.baseurl}}{{p.url}}"{%if p.url == page.url%} class="active"{%endif%}>{{ p.title }}</a>
{% if nextLevel <= maxLevel %}
{% include show-children.html dir=p.dir docs=allDocs level=nextLevel maxLevel=maxLevel %}
{% endif %}
</li>
{% endfor %}
</ul>
{% comment %}+++++++++++++++++++++++++++++++++++++++++++++++++
Because all variables are globales (all includes have the same scope)
we restore level and nextLevel variables to parent values
+++++++++++++++++++++++++++++++++++++++++++++++++{% endcomment %}
{% assign level = level | minus : 1 %}
{% assign nextLevel = nextLevel | minus : 1 %}
Use
This include can be called with several arguments :
dir : root dir to explore (ie : /documentation)
docs : an array of pages - default to site.pages
level: level at which we start printing (/documentation is at level 1,
/documentation/chapter-1 is at level 2, and so on)
Default to 'dir' level
maxLevel: where to stop to print - default to 100
Extracting documentation pages
{% assign documents = site.pages | where: "isDoc", true | sort: "weight" %}
{% assign dir = "documentation" %}
This will print all documentation hierachy
{% include show-children.html dir=dir docs=documents %}
This will start printing at level 2
{% include show-children.html dir=dir docs=documents level=2 %}
This stop printing at level 2
{% include show-children.html dir=dir docs=documents maxLevel=2 %}
On page layout if you just want to print page children you can do :
{% assign documents = site.pages | where: "isDoc", true | sort: "weight" %}
{% assign level = page.dir | remove_first: "/" | split:"/" | size %}
{% assign childrenLevel = level | plus : 1 %}
{% include show-children.html docs=documents dir=page.dir level=childrenLevel %}
Breadcrumb
_includes/breadcrumb.html
{% assign minLevel = include.minLevel %}
{% if minLevel == nil %}{% assign minLevel = 1 %}{% endif %}
<div class="breadcrumb">
<p>You are here : </p>
{% assign documents = site.pages | where: "isDoc", true | sort: "weight" %}
{% include get-parents.html page=page minLevel=minLevel docs=documents %}
<p>{{ page.title }}</p>
</div>
<style type="text/css">
.breadcrumb p { display: inline; }
.breadcrumb p+p+p:before { content:"» "; }
</style>
_includes/get-parents.html
{% assign currentPage = include.page %}
{% assign minLevel = include.minLevel %}
{% assign allDocs = include.docs %}
{% assign pageLevel = currentPage.dir | remove_first: "/" | split:"/" | size %}
{% assign parentLevel = pageLevel | minus: 1 %}
{% if parentLevel >= minLevel %}
{% for p in allDocs %}
{% assign pPageLevel = p.dir | remove_first: "/" | split:"/" | size %}
{% if pPageLevel == parentLevel and currentPage.dir contains p.dir %}
{% include get-parents.html page=p minLevel=minLevel docs=allDocs %}
<p>{{ p.title }}</p>
{% endif %}
{% endfor %}
{% endif %}
Use
Print Documentation > chapter 1 > part 1
{% include breadcrumb.html %}
Print Chapter 1 > part 1
{% include breadcrumb.html minLevel=2 %}
Can it be more simple ?
Working code can be found here.

Merge two sources into one feed.xml

My Jekyll side uses the default feed.xml. I would like to change that because I have site.posts and site.screencasts. Both have the needed attributes to be shown in feed.xml. The default runs this loop:
{% for post in site.posts limit:10 %}
...
{% endfor %}
Is there a way to merge site.posts and site.screencasts and than sort them by date and than limit the result to 10?
I assume that your site.screencasts are derived from page or post and all have a date in front matter.
Starting with an empty array helper in _config.yml
emptyArray: []
Then :
{% assign pagesArray = site.emptyArray %}
{% for post in site.posts %}
{% assign pagesArray = pagesArray | push: post %}
{% endfor %}
{% for scr in site.screencasts %}
{% assign pagesArray = pagesArray | push: scr %}
{% endfor %}
{% assign sorted = pagesArray | sort: "date" %}
{% for s in sorted limit: 10 %}
<h1>{{ s.title }}</h1>
{% endfor %}