Add dynamic XML sitemap for improved SEO

D David Veksler · 1 year ago 3da5ef22e7e6d9c749da219412961b5a76da68da
Parent: 3aa04b26f
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>

2 files changed +78 −0

Diff

diff --git a/index.php b/index.php
index 3d31864..19d87b4 100644
--- a/index.php
+++ b/index.php
@@ -160,6 +160,9 @@ try {
     <meta name="keywords" content="cheatsheets, portfolio, custom cheatsheets, information design, technical writing, data visualization, reference guide, programming, tech, philosophy, ai safety, bitcoin, leadership, david veksler, hire, freelance, consultant, interactive, learning, development, web design">
     <meta name="author" content="David Veksler">
     <link rel="canonical" href="<?php echo htmlspecialchars($baseUrl); ?>">
+    
+    <!-- Sitemap reference for search engines -->
+    <link rel="sitemap" type="application/xml" href="<?php echo htmlspecialchars($baseUrl); ?>sitemap.xml">
 
     <!-- === Open Graph / Facebook / LinkedIn === -->
     <meta property="og:title" content="David Veksler's Cheatsheet Portfolio | Custom Design Services">
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 0000000..a7aa40c
--- /dev/null
+++ b/sitemap.xml
@@ -0,0 +1,75 @@
+<?php
+// Set content type for XML sitemap
+header('Content-Type: text/xml; charset=utf-8');
+
+// Configuration - reuse from index.php
+$excludedItems = [
+    '.',
+    '..',
+    'index.php',
+    'index2.php',
+    'images',
+    'LICENSE',
+    'README.md',
+    'PROMPT.txt',
+    'PROMPT2.txt',
+    'CLAUDE.md',
+    'generate-image-previews.py',
+    'sitemap.xml',
+    // Add any other files you want to exclude from sitemap
+];
+
+$cheatsheetDir = '.';
+
+// Base URL calculation - same as index.php
+$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
+$host = $_SERVER['HTTP_HOST'];
+$scriptName = $_SERVER['SCRIPT_NAME'];
+$scriptDir = dirname($scriptName);
+$scriptDir = ($scriptDir === '.' || $scriptDir === DIRECTORY_SEPARATOR) ? '' : $scriptDir;
+$baseUrl = rtrim($scheme . '://' . $host . $scriptDir, '/') . '/';
+
+// Scan for HTML files
+$htmlFiles = [];
+try {
+    $files = scandir($cheatsheetDir);
+    if ($files !== false) {
+        foreach ($files as $file) {
+            $filePath = rtrim($cheatsheetDir, '/') . '/' . $file;
+            if (in_array($file, $excludedItems, true) || !is_file($filePath) || !is_readable($filePath) || !str_ends_with(strtolower($file), '.html')) {
+                continue;
+            }
+            
+            // Get file modification time for lastmod
+            $lastmod = filemtime($filePath);
+            $htmlFiles[] = [
+                'url' => $baseUrl . $file,
+                'lastmod' => date('c', $lastmod), // ISO 8601 format
+                'priority' => '0.8' // High priority for cheatsheets
+            ];
+        }
+    }
+} catch (Exception $e) {
+    // Continue with empty array if scanning fails
+}
+
+// Add the main index page
+array_unshift($htmlFiles, [
+    'url' => $baseUrl,
+    'lastmod' => date('c', filemtime(__DIR__ . '/index.php')),
+    'priority' => '1.0' // Highest priority for main page
+]);
+
+// Output XML sitemap
+echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
+?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<?php foreach ($htmlFiles as $file): ?>
+    <url>
+        <loc><?php echo htmlspecialchars($file['url']); ?></loc>
+        <lastmod><?php echo htmlspecialchars($file['lastmod']); ?></lastmod>
+        <changefreq>monthly</changefreq>
+        <priority><?php echo htmlspecialchars($file['priority']); ?></priority>
+    </url>
+<?php endforeach; ?>
+</urlset>
\ No newline at end of file