Display array items that have title in jekyll - ruby

I have this code:
<nav>
<ul>
{% for page in site.pages %}
{% if page.title %}
<li>{{ page.title }}</li>
{% endif %}
{% endfor %}
</ul>
</nav>
I don't have any pages with title yet but I may have in the future and tidy-html5, that I'm using to output html with indent, give warning that ul is empty. Without title check it output generated pages tags or global pages like sitemap or rss feed.
Is there a way to first filter array and then don't show nav if the array is empty, something like:
{% pages = [for page in pages if page.title] %}
{% if pages.length %}
<nav>
<ul>
....
</ul>
</nav>
{% endif %}

To get only pages with titles:
pages = site.pages.select{ |p| p.title }
So your code might look something like:
{% assign pages = site.pages.select{ |p| p.title } %}
{% if pages %}
<ul>
{% for page in pages %}
<li>...</li>
{% endfor %}
</ul>
{% endif %}

Related

How to populate a nav with yaml in Jekyll that contains accordions

I am looking for a way to build a navigation that is populated with a .yaml file. I can iterate over the yaml to create the nav items and correct urls that also adds an active class to the nav item when you are on that particular url. I uploaded a screenshot of the existing nav
nav getting populated with active class
my yaml file
nav:
- page: Home
url: /index.html
- page: Getting Started
url: /getting-started.html
- title: Delivery
subfolderitems:
- page: Intro
url: /Delivery/delivery-intro.html
- page: Set Up
url: /Delivery/delivery-deploy.html
- page: Thing 3
url: /thing3.html
- title: Group 2
subfolderitems:
- page: Piece 1
url: /piece1.html
- page: Piece 2
url: /piece2.html
- page: Piece 3
url: /piece3.html
- title: Group 3
subfolderitems:
- page: Widget 1
url: /widget1.html
- page: Widget 2
url: /widget2.html
- page: Widget 3
url: /widget3.html
my html file
<nav>
<ul id="nav-menu" class="nav nav-list">
{% for item in site.data.static-nav.nav %}
<li class="{% if item.url == page.url %} active-item {% endif %}">
{{ item.page }}
</li>
{% if item.subfolderitems[0] %}
{% for subitem in item.subfolderitems %}
{% if subitem.url == page.url %}
{% assign activesubitem = true %}
{% endif %}
{% endfor %}
<li class="parent {% if activesubitem == true %}collapsibleListOpen{% else %}collapsibleListClosed{% endif %}">
<div class="subtree-name">{{ item.title }}</div>
<ul class="nav nav-list">
{% for subitem in item.subfolderitems %}
<li class="{% if subitem.url == page.url %} active-item {% endif %}">
{{ subitem.page }}
</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>
I am running into an issue with the subfolder items being in accordions and having the parent accordion being toggled opened when one of the subitems matches the current url and therefore being active. Is there away to find the parent item with yaml and liquid? I then could somehow check if a parent nav item contains an active sub item ?
If anyone else is stuck on this, I was able to use {% break %}inside the for loop to break out of the loop. You may need a newish version of liquid to use {% break %}. I then assigned a variable that will add the class to have the correct accordion be opened when you open a subpage that is within that accordion.
<nav>
<ul id="nav-menu" class="nav nav-list">
{% for item in site.data.static-nav.nav %}
<li class="{% if item.url == page.url %} active-item {% endif %}">
{{ item.page }}
</li>
{% assign item_isOpen = false %}
{% if item.subfolderitems[0] %}
{% for subitem in item.subfolderitems %}
{% if subitem.url == page.url %}
{% assign item_isOpen = true %}
{% break %}
{% endif %}
{% endfor %}
<li class="{% if item_isOpen == true %} parent collapsibleListOpen {% else %} parent collapsibleListClosed {% endif %}">
<div class="subtree-name">{{ item.title }}</div>
<ul class="nav nav-list">
{% for subitem in item.subfolderitems %}
<li class="{% if subitem.url == page.url %} active-item {% endif %}">
{{ subitem.page }}
</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>

How to Display only products in shopify search results?

I want to display only products from Shopify products but there are showing also pages and posts here is my code for search result:
<div class="product-list">
{% if grid_results == false %}
{% for item in search.results %}
{% include 'search-result' %}
{% endfor %}
{% else %}
<div class="grid-uniform">
{% for item in search.results %}
{% include 'search-result-grid' %}
{% endfor %}
</div>
{% endif %}
{% endif %}
</div>
Now I got the following code:
{% if item.object_type == 'product' %}
But where to put this code so I can get only products for search any text.
Shopify has excellent self help guides for most of the stuff. Here's one such
Show only products in storefront search results

Jekyll: an _include which lists posts of a given category

If I have two very similar ways of listing posts of two different categories:
{% if site.categories.News | size > 0 %}
<ul>
{% for post in site.categories.News %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>There are no news posts available</p>
{% endif %}
{% if site.categories.Blog | size > 0 %}
<ul>
{% for post in site.categories.Blog %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>There are no blog posts available</p>
{% endif %}
It makes me feel like this could be an _include, where the category could be passed as a parameter to include e.g. {% include listposts.html category=News %}
However because of the site.categories.(News/Blog) syntax, am unsure how to pass in the category variable, site.categories.(include.category) would not work, as CAT in site.categories.CAT is a literal and not a variable. Does anyone know how I can make these two similar blocks of code a single _include that canbe passed the category as a parameter?
Your include parameter should look like this: {% include listposts.html category=site.categories.News %}
Then your listposts.html file can through them like this:
{% if include.category %}
<ul>
{% for post in include.category %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>There are no blog posts available</p>
{% endif %}

Jekyll retrieve current tag and build an index

Hi i started to built something with Jekyll.
Now i want to built a Top-down list where you can navigate through all the posts with the tag the current page uses.
Here how it looks now.
<div class="list-group">
{% assign custom = page.tag %}
{% for post in site.tags.custom %}
<a href="{{post.url}}" class="list-group-item {% if page.url == post.url %} active {% endif %} ">
{{post.title}}
</a>
{% endif %}
I dont know if the assign is used right.
The working code looks like that:
<div class="list-group">
{% assign custom = page.tag %}
{% for post in site.tags.custom %}
{% if page.url == post.url %} //no liquid inside of attributes
<a href="{{post.url}}" class="list-group-item active">
{% endif %}
<a href="{{post.url}}" class="list-group-item">
{{post.title}}
</a>
{% endfor %} //endif is only for liquids if

Nested liquid loops in a Jekyll archive page not working. Using an outer loop variable inside the inner's condition

I am working with the jekyll static site builder, and I am having
difficulty performing the following:
{% for category in site.categories %}
<h2 id = "{{ category[0] }}"> {{ category[0] }} </h2>
{% for post in site.categories[{{ category }}] %}
<li> {{ post.title }}</li>
{% endfor %}
&#8617
{% endfor %}
I have a post category in my jekyll site called 'test', and I can
display posts from it with the following:
{% for post in site.categories.test %}
<li> {{ post.title }}</li>
{% endfor %}
However, i want to build an archive page automatically, and in order
to do this, I need to embed the category from the outer loop (the loop
that visits all the categories), and use it inside the inner loop to
access posts from that specific category. What do I need to do to get
the first snippet to work how I want it to?
EDIT: Alternatively, is there another way to get the results that I want?
When you do for category in site.categories ,
category[0] will give you the category name,
category[1] will give you the list of posts for that category.
That's the way Liquid handles iteration over hashes, I believe.
So the code you are looking for is this one:
{% for category in site.categories %}
<h2 id="{{ category[0] }}-ref">{{ category[0] }}</h2>
<ul>
{% for post in category[1] %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
<p>↩</p>
{% endfor %}
I've taken the liberty of fixing some markup issues - I've added <ul>...</ul> around the post link list, a <p> around the last link, a semi-colon after the 8617, and also fixed the id at the top (was missing the -ref part).
Regards!
How about...
{% for category in site.categories %}
<h2 id = "{{ category[0] }}"> {{ category[0] }} </h2>
<ul>
{% for post in site.posts %}
{% if post.category == category[0] %}
<li> {{ post.title }}</li>
{% endif %}
{% endfor %}
</ul>
&#8617
{% endfor %}
Sure, it's pretty inefficient and generates a bunch of extra whitespace, but it gets the job done.
[The original was missing the tags. Just added them. Also, to get ride of the whitespace, one can collapse everything from for post in site.posts to endfor onto a single line.]
{% for post in site.categories.category %}
- OR -
{% for post in site.categories.category[0] %}
Also, I'm not sure why kshep's example doesn't work...

Resources