Would you consider using a Jekyll solution using Liquid templating instead of Ruby code? This is also a lot less code.
My solution lists pages at the exact same directory as the current page. Where the page that uses this includes bit is index.md
{% assign pages = site.pages | sort: 'title' %}
<ul>
{% for item in pages %}
{% if item.dir == page.dir and item.path != page.path %}
<li> {{ item.name }} </li>
{% endif %}
{% endfor %}
</ul>
Then in a folder one level down, there is another index.md file which lists the page in it’s own directory.
I do a listing of pages as above as a bullet list and then I also have a menu of buttons for directories at the current directory. Which really means that for index.md, if there is foo/index.md and bar/index.md then there are links to /foo/ and /bar/
If you prefer you could update my snippet to list pages at the current level and all nested levels below. By changing item.dir == page.dir (which uses the current pages directory) you can use a starts with condition or contains condition. Or you split the path string by / so you can array of breadcrumbs and then you check the first few are equal.
Here is my snippet in context of a fork of minima. I used it for nested menus on a few sites.
But I better explain my use case that led me to consider using that piece of old code.
I need to create an index.html for each folder, including root, that lists the files/folders in it. I have something in place here directory_index.rb · GitHub that works but not completely as expected as the generated index.html files trigger the watch when a file is changed. I tried generating the files in the _site folder directly but I can’t get the index-htmlfiles to be kept after the build even using keep_files configuration (does not work well with wildcards).
I started working on a Generator plugin to achieve the same thing but I’m not familiar with Ruby and the Jekyll Page class so I can’t get to put any content to the generated index.htmlfile using the following code as base:
module CreateIndexPlugin
class IndexPageGenerator < Jekyll::Generator
safe true
def generate(site)
site.pages.each do |page|
site.static_files << IndexPage.new(site, page)
end
end
end
# Subclass of `Jekyll::Page` with custom method definitions.
class IndexPage < Jekyll::Page
def initialize(site, page)
@site = site # the current site instance.
@base = site.source # path to the source directory.
@dir = page.dir # the directory the page will reside in.
# All pages have the same filename, so define attributes straight away.
@basename = 'index' # filename without the extension.
@ext = '.html' # the extension.
@name = 'index.html' # basically @basename + @ext.
end
end
end
I’ll have a look at your Ruby script and update it.
Since the one script has issues with the watch cycle and the other doesn’t, maybe you can learn something from the attributes set on one and apply to the other
I got errors on page.parent not a valid attribute. I’m stuck on that so abandoned the plugin.
I also had to change the class usage to avoid errors and had to add generate as a method on a generator.
require "pathname"
module MyModule
class Generator < Jekyll::Generator
def source_path
end
def generate(site)
end
def parent
end
end
class IncludeListingTag < Liquid::Tag
# ...
end
end
Liquid::Template.register_tag("directory_listing", MyModule::IncludeListingTag)
Regardless of whether you want to use a single listing page for your whole site, or have one at each level, I refer back to my initial comment that Jekyll Liquid templating is more appropriate and much easier. With the small downside that you have to make index.md files yourself instead of automagically with a plugin.
In fact most people on this site can help with Jekyll templating like the templates I shared, while only a few will be able to help with the plugin Ruby code - plus you won’t able to maintain the Ruby code alone if you need to change it.
Plus - the plugin code you shared gives a comment to use it like this
{% directory_listing Title of Listing %}
Which looks like the plugin just adds a tag for you to use on a page that already exists like index.md. If you want to create an index.md / index.html page from nothing, you have to use Generator code from your example above or the Jekyll docs to output the file. That means mixing two existing plugin scripts into one file, which is going to cause you issues I think.
Even the jekyll-sitemap plugin uses Jekyll Liquid code inside a template file to achieve its listing of content in sitemap.xml, rather than making a Ruby generator
Thank you very much for your thorough explanations @MichaelCurrin on the different alternatives.
I guess I will go for the index.md alternative as I already have the Python script read information from a README.md file to be the header of the automagically created index.html. My preference was the Generator Plugin that generates that HTML file but not sure how to print content to it
Let me know your buymeacoffee user to send my appreciation