# Directory Listing plugin help

**URL:** <https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513>\
**Category:** Help\
**Created:** [January 15, 2021, 3:02pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513 "2021-01-15T15:02:22Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![leog](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/leog/32/3158_2.png) [@leog](https://talk.jekyllrb.com/u/leog)\
**Post date:** [January 15, 2021, 3:02pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/1 "2021-01-15T15:02:22Z")

</div>

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.

> <https://gist.github.com/leog/0306269e510eeec2f2bbf6bd34e0c78b>

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 🙂 [https://www.buymeacoffee.com/](https://www.buymeacoffee.com/)

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [January 15, 2021, 8:29pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/2 "2021-01-15T20:29:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![leog](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/leog/32/3158_2.png) [@leog](https://talk.jekyllrb.com/u/leog)\
**Post date:** [January 15, 2021, 8:43pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/3 "2021-01-15T20:43:35Z")

</div>

It was written 9 years ago 😮  
It breaks in the “+” here: [Directory Listing Plugin for Jekyll · GitHub](https://gist.github.com/leog/0306269e510eeec2f2bbf6bd34e0c78b#file-directory_listing-rb-L83)  
And it doesn’t generate the expected result even if you remove that part.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [January 15, 2021, 8:45pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/4 "2021-01-15T20:45:00Z")

</div>

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

```auto
{% 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.

> <https://github.com/MichaelCurrin/minima/blob/master/_includes/structure/page-list.html>

Here is an example page [Jekyll | Dev Cheatsheets](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/jekyll/)

---

<div class="post-metadata">

**Author:** ![leog](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/leog/32/3158_2.png) [@leog](https://talk.jekyllrb.com/u/leog)\
**Post date:** [January 15, 2021, 9:35pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/5 "2021-01-15T21:35:43Z")

</div>

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](https://gist.github.com/leog/63518b16235f153d71ee38df0984afd4) 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-html`files 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.html`file using the following code as base:

```auto
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.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [January 16, 2021, 8:22am UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/6 "2021-01-16T08:22:45Z")

</div>

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`

```auto
---
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.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [January 16, 2021, 8:27am UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/7 "2021-01-16T08:27:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [January 16, 2021, 1:53pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/8 "2021-01-16T13:53:09Z")

</div>

I dug into the script.

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

```auto
      @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.

```auto
      @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.

```auto
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

```auto
{% 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](https://jekyllrb.com/docs/plugins/generators/) 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

> <https://github.com/jekyll/jekyll-sitemap/blob/master/lib/sitemap.xml>

---

<div class="post-metadata">

**Author:** ![leog](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/leog/32/3158_2.png) [@leog](https://talk.jekyllrb.com/u/leog)\
**Post date:** [January 16, 2021, 6:42pm UTC](https://talk.jekyllrb.com/t/directory-listing-plugin-help/5513/9 "2021-01-16T18:42:16Z")

</div>

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 🤔

> [@leog](#):
>
> I’m offering a cup of coffee 🙂 [https://www.buymeacoffee.com/](https://www.buymeacoffee.com/)

Let me know your buymeacoffee user to send my appreciation 👍
