feat(tags): this adds support for post, link, book, show and movie tags with a tag list view and per tag pages

This commit is contained in:
Cory Dransfeldt 2025-04-16 18:59:47 -07:00
parent 3d866262ca
commit 6fdc0b56b9
No known key found for this signature in database
35 changed files with 500 additions and 70 deletions

View file

@ -0,0 +1,109 @@
<?php
require __DIR__ . "/../vendor/autoload.php";
require __DIR__ . "/../server/utils/init.php";
use GuzzleHttp\Client;
use voku\helper\HtmlMin;
$requestUri = $_SERVER["REQUEST_URI"];
$url = trim(parse_url($requestUri, PHP_URL_PATH), "/");
$postgrestUrl = $_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL");
$postgrestApiKey = $_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY");
if ($url === "tags") {
readfile("index.html");
exit();
}
if (!preg_match('/^tags\/(.+?)(?:\/(\d+))?$/', $url, $matches)) {
echo file_get_contents(__DIR__ . "/../404/index.html");
exit();
}
if (isset($matches[2]) && (int)$matches[2] === 1) {
header("Location: /tags/{$matches[1]}", true, 301);
exit();
}
$tag = strtolower(urldecode($matches[1]));
if (!preg_match('/^[\p{L}\p{N} _\-]+$/u', $tag)) {
http_response_code(400);
echo "Invalid tag";
exit();
}
$pageParam = isset($matches[2]) ? (int)$matches[2] : 0;
$page = max($pageParam, 1);
$pageSize = 20;
$offset = ($page - 1) * $pageSize;
$cacheKey = "tag_{$tag}_{$page}";
$useRedis = false;
$tagged = null;
try {
if (extension_loaded('redis')) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$useRedis = true;
}
} catch (Exception $e) {
error_log("Redis not available: " . $e->getMessage());
}
if ($useRedis && $redis->exists($cacheKey)) {
$tagged = json_decode($redis->get($cacheKey), true);
} else {
$client = new Client();
try {
$response = $client->post($postgrestUrl . '/rpc/get_tagged_content', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => "Bearer {$postgrestApiKey}",
],
'json' => [
'tag_query' => $tag,
'page_size' => $pageSize,
'page_offset' => $offset
]
]);
$tagged = json_decode($response->getBody(), true);
if ($useRedis) {
$redis->setex($cacheKey, 3600, json_encode($tagged));
}
} catch (Exception $e) {
error_log($e->getMessage());
echo file_get_contents(__DIR__ . '/../404/index.html');
exit();
}
}
if (!$tagged || count($tagged) === 0) {
echo file_get_contents(__DIR__ . '/../404/index.html');
exit();
}
$totalCount = $tagged[0]['total_count'] ?? 0;
$totalPages = max(ceil($totalCount / $pageSize), 1);
$pagination = [
'pageNumber' => $page,
'pages' => range(1, $totalPages),
'href' => [
'previous' => $page > 1 ? "/tags/{$tag}/" . ($page - 1) : null,
'next' => $page < $totalPages ? "/tags/{$tag}/" . ($page + 1) : null
],
'links' => range(1, $totalPages)
];
$pageTitle = "#" . strtolower(ucfirst($tag)) . "";
$pageDescription = "All content tagged with #" . strtolower(ucfirst($tag)) . ".";
$fullUrl = "https://www.coryd.dev" . $requestUri;
ob_start();
header("Cache-Control: public, max-age=3600");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
?>