Published 2022-03-26.
Time to read: 1 minutes.
jekyll
collection.
I wanted to put up a page that showed articles, ordered by most recently modified.
After working on the problem for a bit, I realized that if every page had a last_modified_at
entry in front matter the problem would be much easier.
So I wrote a Ruby program, not a Jekyll plugin, and processed each post in less than two shakes of a lamb’s tail.
#!/usr/bin/env ruby # Add date: and last_modified_at: fields to front matter for posts that do not have them. # @return number of lines between the --- lines, which demark front matter def front_matter_length(contents) return nil unless contents[0].start_with? "---" contents[1..].find_index { |line| line.start_with? "---" } end # @return date from front matter, or the filename if front matter entry is not present def read_date(front_matter) date_line = front_matter .find { |line| line.start_with? "date:" } return nil unless date_line date_line.delete_prefix("date:") .strip end def process(directory) Dir[directory].each do |file_name| contents = File.readlines(file_name, chomp: true) last_front = front_matter_length contents next unless last_front front_matter = contents[1..last_front] date = read_date front_matter unless date date = File.basename(file_name)[0..9] contents.insert(last_front + 1, "date: #{date}") # insert before 2nd --- last_front += 1 must_save = true end modified_at = front_matter.find { |line| line.start_with? "last_modified_at:" } unless modified_at contents.insert(last_front + 1, "last_modified_at: #{date}") # insert before 2nd --- must_save = true end File.write(file_name, contents.join("\n")) if must_save end end [ "collections/_posts/**/*.html", "collections/_drafts/**/*.html", ].each { |dir| process dir }
If you need to do something similar, you could modify the last bit of the program, and type in the paths to your Jekyll website posts.
[ "collections/_posts/**/*.html", "collections/_drafts/**/*.html", ].each { |dir| process dir }
BTW, I did not convert front matter to YAML because I did not want to change it in any way. Transforming it from text to YAML, and then transforming it back to text again almost certainly would alter the text. I did not want to disturb what was there before, so I just considered front matter as text, and it all went very nicely.