Class: Jekyll::DirectoryListingGenerator

Inherits:
Generator
  • Object
show all
Defined in:
lib/rawfeed/plugin/pub.rb

Overview

The generator that performs the recursive scan.

Constant Summary collapse

PUB_DIR =

Main directory you want to list

'pub'

Instance Method Summary collapse

Instance Method Details

#generate(site) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/rawfeed/plugin/pub.rb', line 41

def generate(site)
  # Extracts all files and directories within PUB_DIR
  # Deletes the root PUB_DIR itself.
  all_paths = Dir.glob("#{PUB_DIR}/**/{" + '*' + ",.*}")

  # Iterates over each item found and groups by parent directory.
  directory_map = {}

  all_paths.each do |path|
    # It ignores files/directories that Jekyll already processes or ignores.
    basename = File.basename(path)
    next if basename.start_with?('_') || basename.start_with?('.')
    next if basename == 'index.html'

    # Specifies the parent directory (the one where the generated index.html file will be located).
    parent_dir = File.dirname(path)
    parent_dir = PUB_DIR if parent_dir == '.'

    # Initialize the list if it's the first time.
    directory_map[parent_dir] ||= []

    # It determines the type and prepares the data.
    if File.directory?(path)
      # If it's a directory, add the trailing slash for URL.
      type = 'directory'
      url = "/#{path}/"
      size = ''
      date = File.mtime(path)
      # It only adds if the directory is not empty.
      directory_map[parent_dir] << {
        'name' => File.basename(path),
        'type' => type,
        'url'  => url,
        'date' => date
      } unless Dir.empty?(path)
    else
      # If it's a file
      type = 'file'
      url = "/#{path}"
      size = File.size(path)
      date = File.mtime(path)

      # Add the item to its parent directory.
      directory_map[parent_dir] << {
        'name' => File.basename(path),
        'type' => type,
        'url'  => url,
        'size' => size,
        'date' => date
      }
    end
  end

  # Creates listing pages dynamically.
  directory_map.each do |dir_path, contents|
    # Sort by type (directories first), then by name.
    sorted_contents = contents.sort_by do |item|
      [item['type'] == 'file' ? 1 : 0, item['name'].downcase]
    end

    # Logic for the navigation input '..'
    parent_url = nil
    parent_name = '../'

    if dir_path == PUB_DIR
      # Special case: if it's in the root 'pub/', the parent is the root of the site '/'.
      parent_url = '/'
    else
      # For all other subdirectories (e.g. pub/subfolder)
      parent_dir = File.dirname(dir_path)

      # Ensures that 'pub' doesn't become '.' and that the URL doesn't end in a slash.
      if parent_dir == PUB_DIR
        parent_url = "/#{PUB_DIR}/"
      else
        parent_url = "/#{parent_dir}/"
      end
    end

    # Adds the navigation entry for the parent directory.
    sorted_contents.unshift({
      'name' => parent_name,
      'type' => 'parent',
      'url'  => parent_url
    })

    # # Adds the ".." page for back navigation, except for the pub/root directory.
    # unless dir_path == PUB_DIR
    #   parent_url = File.dirname(dir_path)
    #   parent_url = '/' if parent_url == '.'
    #   parent_url = "/#{parent_url}/" unless parent_url == '/'

    #   sorted_contents.unshift({
    #     'name' => '../',
    #     'type' => 'parent',
    #     'url'  => parent_url
    #   })
    # end

    # Create the new page and add it to the website.
    page = DirectoryListingPage.new(site, site.source, dir_path, sorted_contents)
    site.pages << page
  end
end