Can I supply group_by, where, or sort with an Array from front matter?


#1

Can I supply a front matter array to any of these filters: group_by, where, sort? I cannot get the below to work with supplying nav.actual and filtering on the value of that (1.0 in this case)

---
layout: articleStyle-0012
headline: hello
nav:
  parent: 0
  actual: 1.0
  sub: 1.1
---
{% assign pages = site.linux | where: "nav.actual", "1.0" %}
        {% for p in pages %}
        {{p.url}}
{% endfor %}

#2

not sure, but it is possible you are comparing a string to an int - not sure how the front matter is treating actual: 1.0

try testing where: "nav.actual", 1.0 or change 1.0 to a word just to see if it works.


#3

For this:

    {% assign myItem = site.linux | where: "nav.actual", 1.0 %}  
    {% for p in myItem %}  
    {{p.url}}  
    {% endfor %}  

I get this error:
Error: undefined method `[]’ for nil:NilClass

This also produces the same error:

    {% assign myItem = site.linux | where: "nav.actual", "one" %}
    {% for p in myItem %}
    {{p.url}}
    {% endfor %}  

Same error:
Error: undefined method `[]’ for nil:NilClass


#4

was that the same error as before?

I’d also try doing the nested front matter outside of the assign as a simpler example to see if it works - adding the assign step is an extra bit of complexity. So just see if you can get the value of nav.actual.


#5

yes, that was the same error as earlier. Thanks for the quick response. Would you mind showing me the nested front matter as you proposed? My entire partial template is below. Does sorting only work with non-collections (posts and data)?

<nav id="nav_mobile" class="globalNav">
	<ul>
        <li><a tabindex="1" href="{{ site.url }}">home</a></li>
        {% for item in site.collections %}
            {% if item.label != 'posts' %}
            <li><a tabindex="{{ forloop.index | plus:1}}" href="{{ site.url }}/{{ item.label }}">{{item.label}}</a></li>
            {% endif %}
        {% endfor %}
	</ul>  
  

<ul>
{% assign myItem = site.linux | where: "nav.actual", 1.0 %}
{% for p in myItem %}  
  <li><a href="{{p.url}}">{{p.label}}</a></li>
{% endfor %}
</ul>
</nav>  

#6

you have a lot of parts. Just saying to start from a simple example and work your way up - for example if you just do {{ nav.actual }} to see the value of it you will find it is not there as it should be page.nav.actual.

where: "nav.actual" I think should be where: page.nav.actual or maybe you need to actually assign that value to something? I think that “nav.actual” is probably being taken literally as a string when you are trying to get it from the front matter right?

What is in site.linux?

edit - I guess I am lost lol. Is nav.actual from the front matter or site.linux? I don’t see where you are using the front matter nav.actual.


#7

ah, ok, maybe I get what you are doing, you have hard coded nav.actual to test, then when it works it would really be getting it from the front matter?

need to see site.linux.


#8

Let me give you some more details.

site.linux is a custom collection

site.linux has many ‘pages’ in the collection. All pages are represented by a markdown file (e.g. myPage.md, index.md, …). Some of these markdown files have the nav array in their frontmatter.
For example (_linux/articles/index.md):

---
headline: Explore Linux OS
permalink: /linux/articles/
meta:
    title: &title Linux Fun
    description: &description Linux 
    keywords: &keywords keywords, here, lots, of, them
    og:
        title: *title
        description: *description
        published_time: 2017-03-14
        modified_time: &moded 2018-01-04
        updated_time: *moded
        tag: *keywords
sitemap:
  lastmod: *moded
  priority: 0.7
  changefreq: monthly
  exclude: no
nav:
  parent: 0
  actual: 1.0
  sub: 1.1
---

Then, in a template or template partial, I’d like to filter all of the pages in the linux custom collection by the nav.actual #. Say, find all pages in a collection that have nav.actual == 1.0

Does that help paint a better picture than before about how/why I’m trying to sort pages?

Happy to give more insight if I’m explaining this poorly. Thanks for the help thus far.:smiley:


#9

ok, now I understand and get the same error. It seems like it should work, not sure what the problem is.

You can do an if inside the for loop to do the comparison though - probably not good for performance.

{% for p in site.linux %}  
{% if p.nav.actual ==  1.0 %}
  <li><a href="{{p.url}}">{{p.label}}</a></li>
{% endif %}
{% endfor %}

I think I got that right, my example was a little different. 1.0 was not in quotes for it to work…


#10

Great. I got it working with the conditional/s.

It seems like it should work, but I guess they have not implementing sorting custom collections with any of those filters ( group_by, where, and sort). :thinking:

Maybe there is a ticket opened for it.


#11

it isn’t the collection part that doesn’t work it was because it was a nested (?) data item - if it had been just nav: 1 or something that was one level it works properly.

Glad it worked! just keep in mind that if statements can slow things down if you use them a lot.


#12

The following works. Is this faster than having a bunch of loops with conditionals?

{% assign myItem = site.linux | where: "nav_actual", 0 %}
{% for pg in myItem %}
    <a href="{{ pg.url | append:' ' | replace:'/ ','' }}">{{pg.title}}</a>
{% endfor %}

With the following front matter snippet:

---
nav_parent: na
nav_actual: 0
nav_sub: 1.0
---  

#13

my guess is yes that would be faster but I really don’t know. If you don’t have hundreds of pages it probably doesn’t matter much.


#14

That makes sense. Many thanks and I hope I can return the favor.