Example folder listing:
https://centerkey.com/files
Last active
March 12, 2025 07:25
-
-
Save dpilafian/930e1677d0c08eed3c39f04d32d7bf19 to your computer and use it in GitHub Desktop.
A good looking replacement for Apache DirectoryIndex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> | |
<!-- Folder Listing --> | |
<!-- v1.3.6 (March 12, 2025) --> | |
<!-- A good looking replacement for Directory Listings: --> | |
<!-- Rename this file to "index.php" and copy it into a web --> | |
<!-- server directory to enable browsing on that directory. --> | |
<!-- Requirement: --> | |
<!-- Apache HTTP Server Project with php_module enabled --> | |
<!-- (see: [PKG-INSTALL-HOME]/etc/httpd/httpd.conf) --> | |
<!-- Example page: --> | |
<!-- https://centerkey.com/files --> | |
<!-- WTFPL --> | |
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> | |
<html lang=en> | |
<head> | |
<meta charset=utf-8> | |
<meta name=viewport content="width=device-width, initial-scale=1"> | |
<meta name=robots content="index, follow"> | |
<meta name=description content="Folder listing for <?=basename(__DIR__)?>"> | |
<meta name=apple-mobile-web-app-title content="<?=basename(__DIR__)?>"> | |
<title>Folder: <?=basename(__DIR__)?></title> | |
<link rel=icon href=https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7/svgs/solid/folder.svg> | |
<link rel=apple-touch-icon href=https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7/svgs/solid/folder.svg> | |
<link rel=mask-icon href=https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7/svgs/solid/folder.svg color=darkgoldenrod> | |
<link rel=preconnect href=https://fonts.googleapis.com> | |
<link rel=preconnect href=https://fonts.gstatic.com crossorigin> | |
<link rel=stylesheet href=https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7/css/all.min.css> | |
<link rel=stylesheet href=https://cdn.jsdelivr.net/npm/dna-engine@3.2/dist/dna-engine.css> | |
<link rel=stylesheet href=https://cdn.jsdelivr.net/npm/web-ignition@2.3/dist/reset.min.css> | |
<style> | |
body { color: dimgary; background-color: white; margin: 0px 20px; } | |
body >main { min-height: auto; } | |
body >main h1 { color: cadetblue; } | |
body >main h1+h2 { text-shadow: none; } | |
body >main a { color: darkgray; border-color: cadetblue; } | |
body >main a:hover { background-color: cadetblue; outline-color: cadetblue; } | |
body >main ul.simple-text { margin: 0px 0px 30px 15px; } | |
body >main ul.simple-text li { display: flex; align-items: center; margin-bottom: 10px; } | |
body >main ul.simple-text li i.font-icon { width: 1.8em; text-align: center; color: darkslateblue; } | |
body >main ul.simple-text li i.font-icon[data-icon=circle-up] { color: dimgray; } | |
body >main ul.simple-text li i.font-icon[data-icon=folder] { color: darkgoldenrod; } | |
body >main ul.simple-text li i.font-icon[data-icon=square-up-right] { color: brown; } | |
body >main p a { margin-right: 8px; } | |
@media (max-width: 667px) { /* selects iPhone 6/6s/7/8/SE2/SE3 landscape and anything narrower */ | |
body { margin: 0px; } | |
body >main h1 { font-size: 1.7em; } | |
body >main ul.simple-text { margin-left: 0px; } | |
} | |
@media (prefers-color-scheme: dark) { /* dark mode */ | |
body { color: silver; background-color: var(--colorCharcoal); } | |
body >main h1 { color: lightseagreen; } | |
body >main a { color: gainsboro; } | |
body >main ul.simple-text li i.font-icon { color: mediumslateblue; } | |
body >main ul.simple-text li i.font-icon[data-icon=circle-up] { color: silver; } | |
body >main ul.simple-text li i.font-icon[data-icon=folder] { color: goldenrod; } | |
body >main ul.simple-text li i.font-icon[data-icon=square-up-right] { color: crimson; } | |
} | |
</style> | |
<script defer src=https://cdn.jsdelivr.net/npm/dna-engine@3.2/dist/dna-engine.min.js></script> | |
<script defer src=https://cdn.jsdelivr.net/npm/web-ignition@2.3/dist/lib-x.min.js></script> | |
<script data-on-load=displayPath> | |
const displayPath = () => { | |
// Show the URL of the current folder. | |
const subheader = globalThis.document.querySelector('main >h2'); | |
const homeIcon = globalThis.document.querySelector('.home-link'); | |
subheader.textContent = globalThis.location.origin + globalThis.location.pathname; | |
homeIcon.href = globalThis.location.origin; | |
}; | |
</script> | |
<?php | |
$gitHubHome = "https://gist.github.com/dpilafian/930e1677d0c08eed3c39f04d32d7bf19"; | |
if (!function_exists("str_ends_with")) { //polyfill for PHP 8.0.0 str_ends_with() | |
function str_ends_with($haystack, $needle) { | |
return substr($haystack, -strlen($needle)) === $needle; | |
} | |
} | |
function showFile($file) { | |
// Don't display hidden files, php files, link files, or folders. | |
$extension = pathinfo($file, PATHINFO_EXTENSION); | |
$extOk = !in_array($extension, array("php")); | |
$isLink = str_ends_with($file, ".link.md"); | |
return !is_dir($file) && $file[0] !== "." && $file !== "error_log" && $extOk && !$isLink; | |
} | |
function fileIcon($fileExtension) { | |
$fileTypes = array( | |
"gif" => "file-image", | |
"html" => "file-code", | |
"jpeg" => "file-image", | |
"jpg" => "file-image", | |
"md" => "file-pen", | |
"mp3" => "file-audio", | |
"pdf" => "file-pdf", | |
"png" => "file-image", | |
"svg" => "file-image", | |
"txt" => "file-lines", | |
"xml" => "file-code", | |
"zip" => "file-zipper", | |
); | |
return array_key_exists($fileExtension, $fileTypes) ? $fileTypes[$fileExtension] : "file"; | |
}; | |
function toHtml($file) { | |
// Create the <li> string to render a line representing a file or folder. | |
$isFolder = is_dir($file); | |
$icon = $isFolder ? "folder" : fileIcon(pathinfo($file, PATHINFO_EXTENSION)); | |
$title = $file; | |
if (!$isFolder && str_ends_with($file, ".link.md")) { | |
// Looks for the ".link.md" extension and reads the markdown syntax for a | |
// hyperlink. For example, the file "example-website.link.md" could have | |
// one line of text like "[Click me](https://example.org)". | |
$icon = "square-up-right"; | |
$md = preg_split("/[\[\]()]/", htmlspecialchars(file_get_contents($file))); | |
$file = $md[3]; | |
$url = parse_url($file); | |
$relLinkHost = $_SERVER["HTTP_HOST"] ?: $_SERVER["SERVER_NAME"]; | |
$host = isset($url["host"]) ? $url["host"] : $relLinkHost; | |
$title = $md[1] . " [" . $host . "]"; | |
} | |
return "<li><a href='$file'><i data-icon=$icon></i></a> <a href='$file'>$title</a></li>"; | |
} | |
?> | |
</head> | |
<body> | |
<main> | |
<h1>Folder Listing</h1> | |
<h2>[URL]</h2> | |
<ul class=simple-text> | |
<li><a href=..><i data-icon=circle-up></i></a> <a href=..>Parent folder</a></li> | |
<?=implode(PHP_EOL, array_map("toHtml", glob("*", GLOB_ONLYDIR)))?> | |
<?=implode(PHP_EOL, array_map("toHtml", glob("*.link.md")))?> | |
<?=implode(PHP_EOL, array_map("toHtml", array_filter(glob("*"), "showFile")))?> | |
</ul> | |
<p> | |
<a href=# class=home-link><i data-icon=home></i></a> | |
<a href=<?= $gitHubHome ?>><i data-brand=github-alt></i></a> | |
</p> | |
</main> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
################## | |
# Folder Listing # | |
# WTFPL # | |
################## | |
# To make this file runnable: | |
# $ chmod +x *.sh.command | |
banner="Folder Listing" | |
projectHome=$(cd $(dirname $0); pwd) | |
pkgInstallHome=$(dirname $(dirname $(which httpd))) | |
apacheCfg=$pkgInstallHome/etc/httpd | |
apacheLog=$pkgInstallHome/var/log/httpd/error_log | |
webDocRoot=$(grep ^DocumentRoot $apacheCfg/httpd.conf | awk -F'"' '{ print $2 }') | |
displayIntro() { | |
cd $projectHome | |
echo | |
echo $banner | |
echo $(echo $banner | sed s/./=/g) | |
pwd | |
version=$(grep "<\!\-\- v" *.php | awk '{ print $2 }') | |
echo $version | |
echo | |
} | |
lintPhp() { | |
cd $projectHome | |
echo "Linting:" | |
php --syntax-check *.php | |
echo | |
} | |
publishWebFiles() { | |
cd $projectHome | |
publishSite=$webDocRoot/centerkey.com | |
publishFolder=$publishSite/files | |
publish() { | |
echo "Publishing:" | |
mkdir -p $publishFolder | |
cp -v *.php $publishFolder/index.php | |
echo | |
} | |
test -w $publishSite && publish | |
} | |
launchBrowser() { | |
cd $projectHome | |
url=https://centerkey.com/files | |
test -w $publishSite && url=http://localhost/centerkey.com/files | |
echo "Opening:" | |
echo $url | |
sleep 2 | |
open $url | |
echo | |
} | |
displayIntro | |
lintPhp | |
publishWebFiles | |
launchBrowser |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment