Reputation: 2058
When iterating through an array of files in the _data
folder, what is the default criteria for sorting the files?
At first I was expecting it to be sorted alphabetically, but after some testing I realized it was not. Still, I couldn't figure out what was the criteria being used to sort the files.
{%- for file in site.data.folder -%}
{{ file | inspect }}
<br />
<br />
{%- endfor -%}
From what I understood file
is an array containing the filename as the first element and the data as the second element, so I'm not sure using sort
with any property name would work. When I tried I had the error message:
Liquid Exception: no implicit conversion of String into Integer
When using sort
with no arguments, I could return the files sorted by filename alphabetic order:
{%- assign files = site.data.folder | sort -%}
{%- for file in files -%}
{{ file | inspect }}
<br />
<br />
{%- endfor -%}
So my questions are:
_data
files?site.data.folder
)After creating the default Jekyll page, I created the _data/folder
directory, where I'd include 5 random .json
files:
_data/folder/a.json
_data/folder/b.json
_data/folder/c.json
_data/folder/d.json
_data/folder/e.json
Each of them have the following content:
_data/folder/a.json:
{"name":"Mike"}
_data/folder/b.json:
{"id":"4343"}
_data/folder/c.json:
[{"age":"29"},{"job":"journalist"}]
_data/folder/d.json:
{"name":"John"}
_data/folder/e.json
{"haircolor":"green"}
With those files in place, I created a page named page.html
on the root directory with:
---
---
<pre>{{ site.data.folder | inspect }}</pre>
<br />
<br />
{%- for file in site.data.folder -%}
<pre>{{ file | inspect }}</pre>
<br />
{%- endfor -%}
And the output of that page was:
{"e"=>{"haircolor"=>"green"}, "c"=>[{"age"=>"29"}, {"job"=>"journalist"}], "d"=>{"name"=>"John"}, "a"=>{"name"=>"Mike"}, "b"=>{"id"=>"4343"}}
["e", {"haircolor"=>"green"}]
["c", [{"age"=>"29"}, {"job"=>"journalist"}]]
["d", {"name"=>"John"}]
["a", {"name"=>"Mike"}]
["b", {"id"=>"4343"}]
The files were not ordered alphabetically, but instead in some apparently random order. I can get them in alphabetical order by using:
---
---
<pre>{{ site.data.folder | sort | inspect }}</pre>
<br />
<br />
{%- assign folder = site.data.folder | sort -%}
{%- for file in folder -%}
<pre>{{ file | inspect }}</pre>
<br />
{%- endfor -%}
Output:
[["a", {"name"=>"Mike"}], ["b", {"id"=>"4343"}], ["c", [{"age"=>"29"}, {"job"=>"journalist"}]], ["d", {"name"=>"John"}], ["e", {"haircolor"=>"green"}]]
["a", {"name"=>"Mike"}]
["b", {"id"=>"4343"}]
["c", [{"age"=>"29"}, {"job"=>"journalist"}]]
["d", {"name"=>"John"}]
["e", {"haircolor"=>"green"}]
But it's still unclear what is the ordering criteria on the call without sort
.
Upvotes: 5
Views: 941
Reputation: 2058
Going from @ashmaroli's assumption that this was not a Jekyll's issue, I started making a little bit of research about file ordering and ran into the following resources:
Indeterministic File order using Dir
The link describes a counter intuitive behavior when loading multiple dependencies. If the order the files are loaded matter the shortcut below could result in they being loaded in a different order than the expected.
Dir[File.join(File.dirname(__FILE__), 'example/*.rb')].each{ |f| require f }
This is apparently due to the underlying glob
system call according to the answer in the link.
How is Pythons glob.glob ordered?
In the SO question above, the user is asking why the returned glob
file order in Python is different than the order on the output of ls -l
. Even though the question is about Python and not Ruby, the underlying call to the OS is likely the same. The OS is not required to deliver the files in any order, so they should be sorted after the call.
The first answer states that if you run ls -U
you get the unordered list of files, which matches the order I have here when I make a list of _data
objects on Jekyll without sorting. So this is most likely the cause of the weird ordering: it's OS dependent.
Since Jekyll orders the _post
files, I think it wouldn't be a major issue to order _data
files by default as well, to avoid any confusion. But as it was stated before in the question itself, it can be easily done with the sort
filter.
Upvotes: 1