-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrss_generator.php
More file actions
154 lines (133 loc) · 5.94 KB
/
Copy pathrss_generator.php
File metadata and controls
154 lines (133 loc) · 5.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php
// Set the content-type to XML
header("Content-Type: application/rss+xml; charset=UTF-8");
function extractValueFromPattern($filename, $pattern) {
$markdownContent = file_get_contents("pages/posts/" . $filename . ".html");
if (preg_match($pattern, $markdownContent, $matches)) {
return trim($matches[1]);
}
return null;
}
// Function to get MIME type from file extension
function getMimeType($url) {
$path = parse_url($url, PHP_URL_PATH); // strips query string and fragment
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$mimeTypes = [
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'webp' => 'image/webp',
// Add more extensions and MIME types as needed
];
return $mimeTypes[$extension] ?? 'application/octet-stream';
}
// Define patterns for the metadata you want to extract
$patterns = [
'pagetitle' => '/<!--\s+pagetitle:(.*?)\s+-->/s',
'pagedate' => '/<!--\s+pagedate:(.*?)\s+-->/s',
'pageexcerpt' => '/<!--\s+pageexcerpt:(.*?)\s+-->/s',
'pageimage' => '/<!--\s+pageimage:(.*?)\s+-->/s', // Image pattern
'pagecategory' => '/<!--\s+pagecategory:(.*?)\s+-->/s' // Optional comma-separated categories. Untagged posts count as "uncategorized".
];
/* CATEGORY FEEDS */
// The ?rss parameter doubles as the category selector:
// ?rss -> all posts (unchanged, backward compatible)
// ?rss=all -> all posts (explicit)
// ?rss=tutorials -> only posts in the "tutorials" category
// ?rss=tutorials,seo -> posts in ANY of the listed categories
// ?rss=uncategorized -> only posts with no pagecategory tag
// This works because index.php handles ?rss before top-cache.php is included,
// so RSS requests never touch the cache and query strings are safe here.
$rssFilterCategories = [];
if (!empty($_GET['rss']) && strtolower(trim($_GET['rss'])) !== 'all') {
foreach (explode(',', $_GET['rss']) as $cat) {
$cat = strtolower(trim($cat));
// Same slug rules as category pages; also drops anything weird from the query string.
if ($cat !== '' && preg_match('/^[a-z0-9\-]+$/', $cat)) {
$rssFilterCategories[] = $cat;
}
}
}
// Site information
$siteTitle = $WebsiteTitle;
$siteLink = $WebsiteURL;
$siteDescription = $WebsiteDescription;
$defaultImage = $WebsiteImage; // Default image URL
// Filtered feeds get the category name(s) in the channel title so subscribers
// can tell their feeds apart (e.g. "My Site – Tutorials").
if (!empty($rssFilterCategories)) {
$prettyNames = array_map(function ($cat) {
return ucwords(str_replace('-', ' ', $cat));
}, $rssFilterCategories);
$siteTitle .= ' – ' . implode(', ', $prettyNames);
}
// Initialize the RSS feed
echo '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
echo '<rss version="2.0">' . "\n";
echo '<channel>' . "\n";
echo '<title>' . htmlspecialchars($siteTitle) . '</title>' . "\n";
echo '<link>' . htmlspecialchars($siteLink) . '</link>' . "\n";
echo '<description>' . htmlspecialchars($siteDescription) . '</description>' . "\n";
echo '<language>en-us</language>' . "\n";
// Channel-wide image
echo '<image>' . "\n";
echo '<url>' . htmlspecialchars($WebsiteImage) . '</url>' . "\n";
echo '<title>' . htmlspecialchars($siteTitle) . '</title>' . "\n";
echo '<link>' . htmlspecialchars($siteLink) . '</link>' . "\n";
echo '</image>' . "\n";
// Collect all items
$items = [];
$postsDir = __DIR__ . '/pages/posts';
foreach (new DirectoryIterator($postsDir) as $fileInfo) {
if ($fileInfo->isDot() || $fileInfo->getExtension() !== 'html') continue;
$filename = $fileInfo->getBasename('.html');
$pageData = [];
// Extract metadata using the patterns
foreach ($patterns as $variableName => $pattern) {
$pageData[$variableName] = extractValueFromPattern($filename, $pattern);
}
if (empty($pageData['pagetitle']) || empty($pageData['pagedate'])) continue;
// Parse the post's categories. Optional — untagged posts are "uncategorized".
// Same parsing rules as the postarchives layouts.
$postCategories = [];
if (!empty($pageData['pagecategory'])) {
foreach (explode(',', $pageData['pagecategory']) as $cat) {
$cat = strtolower(trim($cat));
if ($cat !== '') { $postCategories[] = $cat; }
}
}
if (empty($postCategories)) { $postCategories = ['uncategorized']; }
// Apply the category filter: keep the post if it's in ANY requested category.
if (!empty($rssFilterCategories) && !array_intersect($rssFilterCategories, $postCategories)) continue;
$url = $siteLink . '/posts/' . $filename;
$pubDate = strtotime($pageData['pagedate']); // Use timestamp for sorting
$imageUrl = !empty($pageData['pageimage']) ? $siteLink . '/' . $pageData['pageimage'] : $defaultImage;
$mimeType = getMimeType($imageUrl);
// Add the item to the array
$items[] = [
'title' => htmlspecialchars($pageData['pagetitle']),
'link' => htmlspecialchars($url),
'description' => htmlspecialchars($pageData['pageexcerpt']),
'enclosure' => '<enclosure url="' . htmlspecialchars($imageUrl) . '" type="' . htmlspecialchars($mimeType) . '" length="0" />',
'pubDate' => date(DATE_RSS, $pubDate),
'timestamp' => $pubDate // Store timestamp for sorting
];
}
// Sort items by date, latest first
usort($items, function($a, $b) {
return $b['timestamp'] - $a['timestamp'];
});
// Output sorted items
foreach ($items as $item) {
echo '<item>' . "\n";
echo '<title>' . $item['title'] . '</title>' . "\n";
echo '<link>' . $item['link'] . '</link>' . "\n";
echo '<description>' . $item['description'] . '</description>' . "\n";
echo $item['enclosure'] . "\n";
echo '<pubDate>' . $item['pubDate'] . '</pubDate>' . "\n";
echo '</item>' . "\n";
}
echo '</channel>' . "\n";
echo '</rss>' . "\n";
?>