ghwikipp: index: Top-level index gives you top-level pages and just subdirectory names.

From eecc70123a07b4302045bd880dd4a4703aeea2a5 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 27 Apr 2026 00:20:56 -0400
Subject: [PATCH] index: Top-level index gives you top-level pages and just
 subdirectory names.

Indexes of those subdirectories give you everything under them (including
further subdirectories.

This lets you use the index page to see all of SDL3 vs SDL2, or a specific
satellite library, etc, without a flood of _everything_ on one page.

One can still click through to get _everything_, but this reduces the pain for
both the server and the user to split it up a little.

Fixes #67.
---
 index.php | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/index.php b/index.php
index 70711d4..80b92c6 100644
--- a/index.php
+++ b/index.php
@@ -1136,7 +1136,15 @@ function build_index($base, $dname, &$output)
         if (substr($dent, 0, 1) == '.') {
             continue;  // skip ".", "..", and metadata.
         } else if (is_dir("$dname/$dent")) {
-            build_index("$base$sep$dent", "$dname/$dent", $output);
+            // if $base is NULL, just list the toplevel directories, so
+            // we don't get a huge flood of possibly-unrelated pages.
+            // we'll allow subdirs under those toplevel dirs to recurse,
+            // though, as these are rare and probably-related.
+            if ($base == NULL) {
+                $output[] = "$dent";
+            } else {
+                build_index("$base$sep$dent", "$dname/$dent", $output);
+            }
             continue;
         } else if (preg_match('/^(.*)\.(.*)$/', $dent, $matches) != 1) {
             continue;
@@ -1241,6 +1249,15 @@ function sort_search_results($a, $b)
     }
 }
 
+// hack for index of subdirs
+if ($reqargcount == 1) {
+    $document = preg_replace('/^(.*?)\/index$/', '$1', $document, -1, $count);
+    if ($count == 1) {
+        $reqargcount++;
+        $reqargs[] = 'index';
+    }
+}
+
 $operation = ($reqargcount >= 2) ? $reqargs[1] : 'view';
 
 if ($operation == 'view') {  // just serve the existing page.
@@ -1443,12 +1460,18 @@ function sort_search_results($a, $b)
     perform_action_on_user('admin', $admin_data, $document, ($operation == 'admin_confirm'));
 
 } else if ($operation == 'index') {
+    // we use "wiki/index" to get the global index instead of a subdir's.
+    $topdir = ($document == 'wiki');
     $pagelist = array();
-    build_index(NULL, $raw_data, $pagelist);
+    build_index($topdir ? NULL : $document, $topdir ? $raw_data : "$raw_data/$document", $pagelist);
     $htmllist = '';
     asort($pagelist, SORT_STRING|SORT_FLAG_CASE);
     foreach ($pagelist as $p) {
-        $htmllist .= "<li><a href='/$p'>$p</a></li>\n";
+        if ($topdir && is_dir("$raw_data/$p")) {
+            $htmllist .= "<li><a href='/$p/index'>$p</a></li>\n";
+        } else {
+            $htmllist .= "<li><a href='/$p'>$p</a></li>\n";
+        }
     }
 
     print_template('index', [ 'title' => "Index of all pages - $wikiname", 'htmllist' => $htmllist ]);