Filter popular posts by category in a collection in Jekyll using Liquid -
i have plugin generates list of popular posts in collection in jekyll based on page views. inside collection have 2 categories , filter popular posts same category original post.
here code i've written:
<ul> {% if page.path contains '_kb/cat1' %} {% assign popular_posts = site.popular_posts | where:"category","cat1" %} {% page in popular_posts | limit:3 %} <li> <a href="{{ page.url }}" title="{{ page.title }}">{{ page.title }}</a> </li> {% endfor %} {% else %} {% assign popular_posts = site.popular_posts | where:"category","cat2" %} {% page in popular_posts | limit:3 %} <li> <a href="{{ page.url }}" title="{{ page.title }}">{{ page.title }}</a> </li> {% endfor %} {% endif %} </ul>
- is there way make code simpler?
- how can exclude original post list? example, if i'm on popular post 1, show links popular posts 2, 3 , 4, , not original posts itself.
i know can use if post != self
in ruby, don't know, how in liquid. i've read tutorials, didn't find answer. that's why i'm asking here.
edit: tried access collection's attributes first, suggested @matrixanomaly below. iterates through every document in collection , gives number of lists of popular posts equal number of documents in collection. here code. there way limit loop one, document (or original post)?
{% collection in site.collections %} {% capture label %}{{ collection | first }}{% endcapture %} {% doc in site.collections.[label].docs %} {% assign category = doc.category %} {% if page.category == category %} {% assign popular_posts = site.popular_posts | where:"category",category %} {% node in popular_posts | limit:3 %} {% unless node.url == page.url %} <li> <a href="{{ node.url }}" title="{{ node.title }}">{{ node.title }}</a> </li> {% endunless %} {% endfor %} {% endif %} {% endfor %} {% endfor %}
i'm assuming you're trying code display other popular posts in same category current post. example if you're on post java, you'd display popular posts java, except current post itself.
- if you've set category in each of post, can use built-in variable provided in jekyll,
page.categories
returns list of categories, e.g if have post under category ofwork
,code
,['work','code']
. here's list of page variables.
rather {% if page.path contains '_kb/cat1' %}
, popular posts based on category. should work (i not have jekyll install right test this).
<ul> <!-- uses categories of current post --> <!--i used thecategory avoid confusion, use variable want --> {% thecategory in page.categories %} {% assign popular_posts = site.popular_posts | where:"category", thecategory %} {% page in popular_posts | limit:3 %} <li> <a href="{{ page.url }}" title="{{ page.title }}">{{ page.title }}</a> </li> {% endfor %} {% endfor %} </ul>
- you can exclude original post using 2 methods. either check if post you're iterating through has same value current post's
id
,url
,title
,{% if popular_page.id != page.id %}
orpage.url
shown in page variables. second method useunless
clause.
as shown in liquid designers:
{% if user.name != 'tobi' %} hello non-tobi {% endif %} # same above {% unless user.name == 'tobi' %} hello non-tobi {% endunless %}
i believe issue is have reused page
variable, once {% page in popular_posts %}
make page
local variable , lose access current posts variable value.
what want swap out in innermost loop be:
{% popular_post in popular_posts | limit:3 %} <!-- renamed variable --> {% unless popular_post.id == page.id %} <li> <a href="{{ page.url }}" title="{{ page.title }}">{{ page.title }}</a> </li> {% endunless %} <!-- can use if , endif ---> {% endfor %}
edit: since above code might show 3, ugly workaround use limit:4
, there edge case of showing 4 posts when current post not popular, can do:
{% assign popular_posts = site.popular_posts | "id" != page.id %} {% popular_post in popular_posts | limit:3 %} {% unless popular_post.id == page.id %}
i suppose it's matter of nesting conditionals i'm unsure if liquid allows multiple conditions in filters, want filter out current post before doing limit:3
.
Comments
Post a Comment