Search code examples
liquidjekyll-theme

How can I sort a dimensional array output by key value from jekyll data yaml files?


I need the name from several yml files sorted, alphabetically on the output.

I've tried to add | sort: 'name' in my for loop. I get:

 Liquid Exception: no implicit conversion of String into Integer in pages/index.html

Sample _data/cat/example1.yml

name: "test1"

permalink: "/test"

twitter: "WIP"

facebook: "WIP"

web: "WIP"

I have at least 3 yml files in my test in the /cat folder.

Sample Include File

<div class="row">
{% for cat_hash in site.data.cat %}
{% assign cat = cat_hash[1] | sort: 'name' %}
<div class="col-6 col-12-narrower">
    <section>
      <header>
        <a class="image featured" href="{{ cat.permalink }}" title="{{ cat.name }}"><h3>{{ cat.name }}</h3></a>
      </header>
        <p>{{ cat.web }}</p>
     </section>
</div>
{% endfor %}
</div>

I've read several examples with this sort issue. Just not sure if any of the hash results in the loop answered my situation?


Solution

  • Your not applying the sort on a valid array of hashes.

    If you do a {{ site.data.cat | inspect }} you get something like {"t1"=>{"name"=>"test1"}, "t2"=>{"name"=>"allo"}, "t3"=>{"name"=>"jekyll"}} (I've simplified data files for brevity but it works the same with more complicated data files like yours).

    You currently are applying sort filter on {"name"=>"test1"} object which cannot sort itself.

    What you need to do is to get all your data hashes in a single array. then you can sort it.

    {% assign datas = "" | split: "" %}
    {% for cat in site.data.cat %}
      {% assign datas = datas | push: cat[1] %}
    {% endfor %}
    
    DEBUG : {{ datas | inspect }}
    

    You now have an array that can be sorted.

    {% assign datas = datas | sort: "name" %}
    DEBUG : {{ datas | inspect }}
    

    You can now print your datas sorted by name.

    Full code :

    {% assign datas = "" | split: "" %}
    {% for cat in site.data.cat %}
      {% assign datas = datas | push: cat[1] %}
    {% endfor %}
    
    {% assign datas = datas | sort: "name" %}
    
    <div class="row">
    {% for cat in datas %}
      <div class="col-6 col-12-narrower">
        <section>
          <header>
            <a class="image featured" href="{{ cat.permalink }}" title="{{ cat.name }}">
              <h3>{{ cat.name }}</h3>
            </a>
          </header>
          <p>{{ cat.web }}</p>
        </section>
      </div>
    {% endfor %} 
    </div>
    

    Note that inspect filter is used for debugging only.