Reputation: 29988
We use a web server that does not allow directory listing.
There is a specific directory I would like to allow listing of.
How can make a simple HTML file that will contain the contents of this directory?
Upvotes: 101
Views: 253897
Reputation: 31676
There are enough valid reasons to explicitly disable automatic directory indexes in apache or other web servers. Or, for example, you might want to only include certain file types in the index. In these cases you might still want a statically generated index.html file in specific folders.
tree
tree is a minimalistic utility that is available on most unix-like systems (ubuntu/debian: sudo apt install tree
, mac: brew install tree
, windows: zip).
tree
can generate plain text, XML (-X
), JSON (-J
) and HTML (-H
) output.
Generate an HTML directory index one level deep, skip, ie -I
gnore the generated index.html
file itself, include sizes (-s
) and timestamps (-D
):
tree -H '.' -L 1 --noreport --dirsfirst -T 'Downloads' -s -D --charset utf-8 -I "index.html" -o index.html
Include only specific file types that match a glob pattern, e.g. *.zip
and *.gz
files, dirs first, include size and timestamps with a custom date format:
tree -H '.' \
-L 1 \
--noreport \
--houtro ""
--dirsfirst \
--charset utf-8 \
--ignore-case \
--timefmt '%d-%b-%Y %H:%M' \
-I "index.html" \
-T 'Downloads' \
-s -D \
-P "*.zip|*.gz" \
-o index.html
-H '.'
enable HTML mode and set base href, can be relative e.g..
or absolute e.g./files
.
-L 1
limit to current directory only
--noreport
do not include the summary at the end
--houtro ""
suppress the credits at the end by setting an empty outro file name
--dirsfirst
put directories first
--charset utf-8
ensure UTF-8 charset
--ignore-case
make the-I
and-P
options case insensitive
--timefmt '%d-%b-%Y %H:%M'
set date format (seeman strftime
in your terminal for details *).
-I "index.html"
Ignore, i.e. do not include the generatedindex.html
file in the listing
-P "*.zip|*.gz"
filter by glob Pattern, e.g. only include zip/gz files
-T
set custom Title (has no effect if--hintro
(set custom intro file) is defined)
-s
include file Sizes
-D
include modified dates
-o index.html
write to file (stdout by default)
If you don't want any title at all you can suppress the header block with
--hintro ""
which will set an empty include file for the intro.
For all supported options see tree --help
or man tree
in a shell.
Combined with gnu find
you can recursively create index files in a subtree e.g. with:
find . -type d -print -exec sh -c 'tree "$0" \
-H "." \
-L 1 \
--noreport \
--houtro ""
--dirsfirst \
--charset utf-8 \
-I "index.html" \
-T "Custom Title" \
--ignore-case \
--timefmt "%d-%b-%Y %H:%M" \
-s \
-D \
-o "$0/index.html"' {} \;
I needed an index generator which I could style the way I want, so ended up writing this script (python 3) which in addition to having customisable styling can also recursively generate an index.html
file in all the nested subdirectories (with the --recursive
or -r
flag). The styling borrows heavily from caddyserver's file-server
module *. It includes last modified time and is responsive in mobile viewports.
Update: A newer version of the script linked above that generates friendly SVG icons for a few dozens of file types (makes slightly bigger index.html files).
Upvotes: 164
Reputation: 7846
My solution was to use a local apache web server to generate HTML index files.
This works very well, and means I can test and check any changes on the local apcahe webserver, before I generate listings and uploading the files. In fact my indexes were designed to use apache fancy indexing LONG before I was force to switch to a static web server, so I did not have to re-designed them for a different index generator.
The script to do it was actually VERY simple and written in plain shell.
If you like to see the uploaded result... Visit my "Tower of Computational Sorcery"... https://antofthy.gitlab.io/info/
Upvotes: -1
Reputation: 6390
You can either: Write a server-side script page like PHP, JSP, ASP.net etc to generate this HTML dynamically
or
Setup the web-server that you are using (e.g. Apache) to do exactly that automatically for directories that doesn't contain welcome-page (e.g. index.html)
Specifically in apache read more here: Edit the httpd.conf: http://justlinux.com/forum/showthread.php?s=&postid=502789#post502789 (updated link: https://forums.justlinux.com/showthread.php?94230-Make-apache-list-directory-contents&highlight=502789)
or add the autoindex mod: http://httpd.apache.org/docs/current/mod/mod_autoindex.html
Upvotes: 13
Reputation: 5631
If you have node
then you can use fs
like in this answer to get all the files:
const { resolve } = require('path'),
{ readdir } = require('fs').promises;
async function getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(dirents.map((dirent) => {
const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}));
return Array.prototype.concat(...files);
}
And you might use that like this:
const directory = "./Documents/";
getFiles(directory).then(results => {
const html = `<ul>` +
results.map(fileOrDirectory => `<li>${fileOrDirectory}</li>`).join('\n') +
`</ul>`;
process.stdout.write(html);
// or you could use something like fs.writeFile to write the file directly
});
You could call it at the command-line with something like this:
$ node thatScript.js > index.html
Upvotes: 0
Reputation: 4896
There's a free php script made by Celeron Dude that can do this called Celeron Dude Indexer 2. It doesn't require .htaccess
The source code is easy to understand and provides a good starting point.
Here's a download link: https://gitlab.com/desbest/celeron-dude-indexer/
Upvotes: 12
Reputation: 37817
If you have a staging server that has directory listing enabled, then you can copy the index.html
to the production server.
For example:
wget https://staging/dir/index.html
# do any additional processing on index.html
scp index.html prod/dir
Upvotes: 2
Reputation: 3928
For me PHP is the easiest way to do it:
<?php
echo "Here are our files";
$path = ".";
$dh = opendir($path);
$i=1;
while (($file = readdir($dh)) !== false) {
if($file != "." && $file != ".." && $file != "index.php" && $file != ".htaccess" && $file != "error_log" && $file != "cgi-bin") {
echo "<a href='$path/$file'>$file</a><br /><br />";
$i++;
}
}
closedir($dh);
?>
Place this in your directory and set where you want it to search on the $path. The first if statement will hide your php file and .htaccess and the error log. It will then display the output with a link. This is very simple code and easy to edit.
Upvotes: 42
Reputation: 89
Did you try to allow it for this directory via .htaccess?
Options +Indexes
I use this for some of my directories where directory listing is disabled by my provider
Upvotes: 8
Reputation: 4967
This can't be done with pure HTML.
However if you have access to PHP on the Apache server (you tagged the post "apache") it can be done easilly - se the PHP glob function. If not - you might try Server Side Include - it's an Apache thing, and I don't know much about it.
Upvotes: 1