directoryListing method
Method used to generate a directory listing.
This method is invoked by the handler if the request is for a directory, the directory exists, the directory does not have any of the default files, and allowDirectoryListing is true.
It is passed the Request, Directory. If linkToParent
is true,
if a link to the parent directory is permitted (i.e. this is not the
directory registered with the StaticFiles).
Applications can create a subclass of StaticFiles and implement their own directory listing method, if they want to create a custom directory listings.
Null-safety breaking change: linkToParent is required.
Implementation
Future<Response> directoryListing(Request req, Directory dir,
{required bool linkToParent}) async {
final components = dir.path.split('/');
String title;
if (2 <= components.length &&
components[components.length - 2].isNotEmpty &&
components.last.isEmpty) {
title = components[components.length - 2];
} else {
title = 'Listing';
}
final buf = StringBuffer('''
<!doctype html>
<html>
<head>
<title>${HEsc.text(title)}</title>
<style type="text/css">
body { font-family: sans-serif; }
ul { font-family: monospace; font-size: larger; list-style-type: none; }
a { text-decoration: none; display: inline-block; padding: 0.5ex 0.75em; }
a.parent { border-radius: 0 0 2ex 2ex; }
a.dir { border-radius: 2ex 2ex 0 0; }
a.file { border-radius: 2ex; }
a:hover { text-decoration: underline; }
a.parent:hover { background: #ddd; }
a.dir:hover { background: #ddd; }
a.file:hover { background: #eee; }
</style>
</head>
<body>
<h1>${HEsc.text(title)}</h1>
<ul>
''');
if (linkToParent) {
buf.write(
'<li><a href=".." title="Parent" class="parent">↑</a></li>\n');
}
await for (var entity in dir.list()) {
String n;
String cl;
if (entity is Directory) {
n = '${entity.uri.pathSegments[entity.uri.pathSegments.length - 2]}/';
cl = 'class="dir"';
} else {
n = entity.uri.pathSegments.last;
cl = 'class="file"';
}
buf.write('<li><a href="${HEsc.attr(n)}" $cl>${HEsc.text(n)}</a></li>\n');
}
buf.write('''
</ul>
</body>
</html>
''');
final resp = ResponseBuffered(ContentType.html)
..headerAddDate('Date', DateTime.now())
..write(buf.toString());
return resp;
}