Reputation: 1205
I have a plugin which generates a list of popular posts in a collection in Jekyll based on their page views. Inside collection I have two categories and I would like to filter popular posts by the same category as the original post.
Here is my code I've written:
<ul>
{% if page.path contains '_kb/cat1' %}
{% assign popular_posts = site.popular_posts | where:"category","cat1" %}
{% for 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" %}
{% for page in popular_posts | limit:3 %}
<li>
<a href="{{ page.url }}" title="{{ page.title }}">{{ page.title }}</a>
</li>
{% endfor %}
{% endif %}
</ul>
I know I can use something like if post != self
in Ruby, but I don't know, how to do it in Liquid. I've read some tutorials, but didn't find an answer. That's why I'm asking here.
EDIT: I tried to access collection's attributes first, as suggested by @matrixanomaly below. But now it iterates through every document in a collection and gives the number of lists of popular posts equal to the number of documents in a collection. Here is my code. Is there any way to limit this loop only to one, the document itself (or the original post)?
{% for collection in site.collections %}
{% capture label %}{{ collection | first }}{% endcapture %}
{% for doc in site.collections.[label].docs %}
{% assign category = doc.category %}
{% if page.category == category %}
{% assign popular_posts = site.popular_posts | where:"category",category %}
{% for 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 %}
Upvotes: 2
Views: 1604
Reputation: 6947
I'm assuming you're trying to get your code to display other popular posts in the same category as the current post. For example if you're on a post about Java, you'd like to display popular posts about Java, except the current post itself.
page.categories
which returns a list of categories, e.g if you have a post under the category of work
and code
, you get ['work','code']
. Here's a list of page variables.Rather than {% if page.path contains '_kb/cat1' %}
, you could immediately get popular posts based on the category. This should work (I do not have a Jekyll install right now to test this).
<ul>
<!-- uses categories of the current post -->
<!--I used theCategory to avoid confusion, use any variable you want -->
{% for theCategory in page.categories %}
{% assign popular_posts = site.popular_posts | where:"category", theCategory %}
{% for page in popular_posts | limit:3 %}
<li>
<a href="{{ page.url }}" title="{{ page.title }}">{{ page.title }}</a>
</li>
{% endfor %}
{% endfor %}
</ul>
id
, url
, title
, something like {% if popular_page.id != page.id %}
or page.url
as shown in the page variables. The second method would be to use the unless
clause.As shown in Liquid for Designers:
{% if user.name != 'tobi' %}
Hello non-tobi
{% endif %}
# Same as above
{% unless user.name == 'tobi' %}
Hello non-tobi
{% endunless %}
I believe your issue is that you have reused the page
variable, once you do {% for page in popular_posts %}
you make page
a local variable and you lose access to the current posts variable value.
What you would want to swap out in the innermost loop would be:
{% for 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 %} <!-- you can use if and endif also --->
{% endfor %}
EDIT: Since the above code might only show 3, the ugly workaround would be to use limit:4
, but there is the edge case of showing 4 posts when the current post is not popular, you can then do:
{% assign popular_posts = site.popular_posts | where "id" != page.id %} {% for popular_post in popular_posts | limit:3 %} {% unless popular_post.id == page.id %}
I suppose it's a matter of nesting the conditionals as I'm unsure if Liquid allows multiple conditions in their filters, but you want to filter out the current post before doing a limit:3
.
Upvotes: 1