Directory Listing plugin help

Hello.

I was wondering if anyone could help me update a plugin I found. It generates html representing the file/folder structure of the current folder.

If anyone could fork it and update it to work on Jekyll 4.1.1, that would make my day. I’m offering a cup of coffee :slight_smile: https://www.buymeacoffee.com/

What part of it breaks on 4.1.1 that needs changing? Was it written for 3.X? Or 4.0?

It was written 9 years ago :open_mouth:
It breaks in the “+” here: Directory Listing Plugin for Jekyll · GitHub
And it doesn’t generate the expected result even if you remove that part.

1 Like

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.

Here is an example page Jekyll | Dev Cheatsheets

Very well thought @MichaelCurrin.

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

Thanks for the help BTW, I really appreciate it.

My system involves making a small index.md page at each directory which also allows me to give it metadata to display on the page.

npm/index.md

---
title: NPM
layout: listing
description: The Node Package Manager
---

There is no body after (except in a few cases where I want it). My layout ensures the listing appears.

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 dug into the script.

The reason why there is an error on + and nil class is because of this line

      @title ||= (context.registers[:site].config['directory_listing_title'] ||
      context.registers[:site].config['directory_listing_prefix']+@dir || @dir)

Which can be fixed by setting directory_listing_prefix in your _config.yml file.

Or ignoring that and just using.

      @title ||= (context.registers[:site].config['directory_listing_title'] ||

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

1 Like

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 :thinking:

Let me know your buymeacoffee user to send my appreciation :+1:

1 Like