A nicer web-based file browser with the NGNIX Fancy Index module
This post is part of a series of posts where I share my experiences developing, testing, and debugging the new implementation of my website, including this blog and my home page.
When I made the new implementation of my website, I included a file browser for my file repository with files that I would like to share. With NGNIX, this is extremely easy to achieve. Just enable autoindex for the given path at your site. From a previous post, we see how to enable this by setting the attribute autoindex
to on
(only showing an excerpt of the configuration file, where ⋮
represents a few lines not shown here):
server { ⋮ location /dist { alias /var/www/dist; autoindex on; } }
This works, but the resulting file browser does not look good and does not match the style of the rest of the website. To solve the first problem, the NGNIX Fancy Index module came to the rescue: «like the built-in autoindex module does, but adding a touch of style». The Fancy Index module allows a certain degree of customization of the generated content, and even with its default style, it is a nice improvement over the built-in autoindex module. To replace the built-in autoindex module with the NGNIX Fancy Index module, the configuration file was updated to enable fancyindex
instead of autoindex
:
server { ⋮ location /dist { alias /var/www/dist; fancyindex on; } }
The only change is to replace autoindex
with fancyindex
. If you are not happy with the NGNIX Fancy Index module default style, several themes built for the module are available online. One example is the Nginx-Fancyindex-Theme by Lilian Besson (@Naereen), described by the author as «Minimal, modern, and simple». To use this theme on a website, create the directory /var/www/fancyindex_theme
on the web server and copy the following files from the light version of the theme to this directory: header.html
, footer.html
, styles.css
, jquery.min.js
, showdown.min.js
, and addNginxFancyIndexForm.js
. Then, update the configuration file to use this theme:
server { ⋮ location /dist { alias /var/www/dist; fancyindex on; fancyindex_header "/fancyindex_theme/header.html"; fancyindex_footer "/fancyindex_theme/footer.html"; fancyindex_ignore "fancyindex_theme"; } location /fancyindex_theme { alias /var/www/fancyindex_theme; try_files $uri $uri/ =404; } }
The second problem, to match the style of the rest of my website, is solved by modifying an existing theme. I have chosen to start with the theme used in the example above, Nginx-Fancyindex-Theme-light from Nginx-Fancyindex-Theme. To achieve a style that matches my site, I modified the NGINX configuration file for the website and three of the files from the theme: header.html
, footer.html
, and styles.css
. In addition, I have added a JavaScript file for a minor modification of the HTML code. In the configuration file, I configured the behavior of Fancy Index to match my preferences (added three lines, starting with my preferred time format):
server { ⋮ location /dist { alias /var/www/dist; fancyindex on; fancyindex_time_format "%Y-%m-%d %H:%M"; fancyindex_exact_size off; fancyindex_hide_parent_dir on; fancyindex_header "/fancyindex_theme/header.html"; fancyindex_footer "/fancyindex_theme/footer.html"; fancyindex_ignore "fancyindex_theme"; } ⋮ }
In the header.html
file, I modified the title and the heading (the title
and h1
tags), added two lines to include the fonts used on my website, gave the h1
tag an id
attribute, and removed some unused parts:
<!DOCTYPE html> <html> <head> ⋮ <title>PG12 (aa) - a file repository</title> <link rel="stylesheet" href="/fancyindex_theme/styles.css"> <link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:300,400,500' rel='stylesheet' type='text/css'> <link href='https://fonts.googleapis.com/css?family=Roboto+Slab:300,400,500' rel='stylesheet' type='text/css'> <script type="text/javascript" src="/fancyindex_theme/jquery.min.js"></script> </head> <body> <h1 id="path">Path:
The file ends with an open h1
tag. This is correct. The NGNIX Fancy Index module will complete this tag and fill in the rest of the HTML body until the part found in the footer.html
file. When the file browser is at the path dist/texmf/
, the module will complete the h1
tag in the following way (notice the newline inside the tag):
<h1 id="path">Path: /dist/texmf/</h1>
In the footer.html
, I have added one line to include the script mkpath-links.js
and removed some unused parts:
<footer> ⋮ </footer> <script src="https://unpkg.com/xregexp/xregexp-all.js"></script> <script type="text/javascript" src="/fancyindex_theme/addNginxFancyIndexForm.js"></script> <script type="text/javascript" src="/fancyindex_theme/mkpath-links.js"></script> </body> </html>
Since this is specific to the selected style of your specific website, I will not go into the details on how to change the CSS file styles.css
. One example of such changes is how I replaced the fonts used by modifying the font related values in the CSS file:
body { font-family: "Roboto Slab", serif; font-size: 15px; font-weight: 300; ⋮ } .link, .size, .date { font-family: "Source Code Pro", monospace; font-size: .9em; font-weight: 400; }
The final change I made was to include some JavaScript code to modify the h1
tag after the NGINX Fancy Index module has completed it. I created a file mkpath-links.js
with the JavaScript code and copied it to the directory /var/www/fancyindex_theme
on the web server. As seen above, I added an id
attribute with the value "path"
to the h1
tag and included a line in the footer.html
file to include the JavaScript code. This is the JavaScript code (in mkpath-links.js
) that modifies the h1
tag:
let path_content = document.getElementById("path").textContent; const title_and_path = path_content.split(/\r?\n/); const folders = title_and_path[1].split("/"); let content = title_and_path[0] + " "; let path = "/"; for (let i = 1; i < folders.length-1; i++) { path += folders[i] + "/"; content += "<a href=\"" + path + "\">" + folders[i] + "</a>/" } document.getElementById("path").innerHTML = content;
The first line fetches the content of the h1
tag. The second line splits the content into two parts: the title (Path:
in the example above) and the given path (e.g., /dist/texmf/
). The third line splits the path into each directory. The rest of the code rebuilds the content of the h1
tag. In the loop, we insert a link to each directory in the path, and in the final line, we replace the content of the h1
tag with the rebuilt content. For the example above with the path /dist/texmf/
, the resulting h1
tag will be this:
<h1 id="path">Path: <a href="/dist/">dist</a>/<a href="/dist/texmf/">texmf</a>/</h1>
The final version of my file browser includes some more fine-tuning and modifications. Check out the live version at https://www.pg12.org/dist/. This is a screen dump of the live version when I wrote this text:
![Screenshot of a web file browser Screenshot of a web file browser](/images/screenshot-2024-06-21-at-111413.png)