feat(reading): clean and refactor routing for books -> reading to separate paths

This commit is contained in:
Cory Dransfeldt 2025-05-16 13:03:55 -07:00
parent 8d9455940e
commit 262ee84a6d
No known key found for this signature in database
21 changed files with 42 additions and 88 deletions

View file

@ -90,7 +90,7 @@ class BookImportHandler extends ApiHandler
"author" => $author,
"description" => $description,
"read_status" => "want to read",
"slug" => "/books/" . $isbn,
"slug" => "/reading/books/" . $isbn,
];
$this->makeRequest("POST", "books", ["json" => $bookPayload]);

View file

@ -8,7 +8,7 @@ export default {
.sort((a, b) => b.value - a.value)
.map(
(year, index) =>
`<a href="/books/years/${year.value}">${year.value}</a>${
`<a href="/reading/years/${year.value}">${year.value}</a>${
index < years.length - 1 ? " • " : ""
}`
)

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "coryd.dev",
"version": "5.1.6",
"version": "6.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "coryd.dev",
"version": "5.1.6",
"version": "6.0.0",
"license": "MIT",
"dependencies": {
"html-minifier-terser": "7.2.0",

View file

@ -1,6 +1,6 @@
{
"name": "coryd.dev",
"version": "5.1.6",
"version": "6.0.0",
"description": "The source for my personal site. Built using 11ty (and other tools).",
"type": "module",
"engines": {

View file

@ -2,6 +2,7 @@
require_once "icons.php";
require_once "media.php";
require_once "paginator.php";
require_once "routing.php";
require_once "strings.php";
require_once "tags.php";
?>

8
server/utils/routing.php Normal file
View file

@ -0,0 +1,8 @@
<?php
function redirectTo404(): void {
header("Location: /404/", true, 302);
exit();
}
?>

View file

@ -11,11 +11,11 @@
@import url("./base/index.css") layer(base);
/* page styles */
@import url("./pages/books.css") layer(page);
@import url("./pages/contact.css") layer(page);
@import url("./pages/links.css") layer(page);
@import url("./pages/media.css") layer(page);
@import url("./pages/music.css") layer(page);
@import url("./pages/reading.css") layer(page);
@import url("./pages/watching.css") layer(page);
@import url("./pages/webrings.css") layer(page);

View file

@ -9,18 +9,12 @@
$requestUri = $_SERVER["REQUEST_URI"];
$url = trim(parse_url($requestUri, PHP_URL_PATH), "/");
if (strpos($url, "music/artists/") !== 0) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (strpos($url, "music/artists/") !== 0) redirectTo404();
$fetcher = new ArtistFetcher();
$artist = $fetcher->fetch($url);
if (!$artist) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!$artist) redirectTo404();
$artist["description"] = parseMarkdown($artist["description"]);
$pageTitle = htmlspecialchars("Artists • " . $artist["name"], ENT_QUOTES, "UTF-8");

View file

@ -1,7 +1,7 @@
<?php
require __DIR__ . "/../vendor/autoload.php";
require __DIR__ . "/../server/utils/init.php";
require __DIR__ . "/../../vendor/autoload.php";
require __DIR__ . "/../../server/utils/init.php";
use App\Classes\BookFetcher;
use voku\helper\HtmlMin;
@ -9,37 +9,12 @@
$requestUri = $_SERVER["REQUEST_URI"];
$url = trim(parse_url($requestUri, PHP_URL_PATH), "/");
if (preg_match('/^books\/years\/(\d{4})$/', $url, $matches)) {
$year = $matches[1];
$filePath = __DIR__ . "/years/{$year}.html";
if (file_exists($filePath)) {
echo file_get_contents($filePath);
exit();
} else {
echo file_get_contents(__DIR__ . "/../404/index.html");
exit();
}
}
if ($url === "books/years" || $url === "books") {
$indexPath = $url === "books" ? "index.html" : __DIR__ . "/../404/index.html";
readfile($indexPath);
exit();
}
if (!preg_match('/^books\/[\w-]+$/', $url)) {
echo file_get_contents(__DIR__ . "/../404/index.html");
exit();
}
if (!preg_match('/^reading\/books\/([\dXx-]+)$/', $url)) redirectTo404();
$fetcher = new BookFetcher();
$book = $fetcher->fetch($url);
if (!$book) {
echo file_get_contents(__DIR__ . "/../404/index.html");
exit();
}
if (!$book) redirectTo404();
$book["description"] = parseMarkdown($book["description"]);
$pageTitle = htmlspecialchars("Books • {$book["title"]} by {$book["author"]}", ENT_QUOTES, "UTF-8");

View file

@ -9,18 +9,12 @@
$requestUri = $_SERVER["REQUEST_URI"];
$url = trim(parse_url($requestUri, PHP_URL_PATH), "/");
if (!preg_match('/^music\/genres\/[\w-]+$/', $url)) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!preg_match('/^music\/genres\/[\w-]+$/', $url)) redirectTo404();
$fetcher = new GenreFetcher();
$genre = $fetcher->fetch($url);
if (!$genre) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!$genre) redirectTo404();
$pageTitle = htmlspecialchars("Genres • " . $genre["name"], ENT_QUOTES, "UTF-8");
$pageDescription = truncateText(

View file

@ -9,18 +9,12 @@
$requestUri = $_SERVER["REQUEST_URI"];
$url = trim(parse_url($requestUri, PHP_URL_PATH), "/");
if (!preg_match('/^watching\/movies\/[\w-]+$/', $url)) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!preg_match('/^watching\/movies\/[\w-]+$/', $url)) redirectTo404();
$fetcher = new MovieFetcher();
$movie = $fetcher->fetch($url);
if (!$movie) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!$movie) redirectTo404();
$movie["description"] = parseMarkdown($movie["description"]);
$pageTitle = htmlspecialchars("Movies • " . $movie["title"], ENT_QUOTES, "UTF-8");

View file

@ -9,18 +9,12 @@
$requestUri = $_SERVER["REQUEST_URI"];
$url = trim(parse_url($requestUri, PHP_URL_PATH), "/");
if (!preg_match('/^watching\/shows\/[\w-]+$/', $url)) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!preg_match('/^watching\/shows\/[\w-]+$/', $url)) redirectTo404();
$fetcher = new ShowFetcher();
$show = $fetcher->fetch($url);
if (!$show) {
echo file_get_contents(__DIR__ . "/../../404/index.html");
exit();
}
if (!$show) redirectTo404();
$pageTitle = htmlspecialchars("Show • " . $show["title"], ENT_QUOTES, "UTF-8");
$pageDescription = truncateText(

View file

@ -14,10 +14,7 @@
exit();
}
if (!preg_match('/^tags\/(.+?)(?:\/(\d+))?$/', $url, $matches)) {
echo file_get_contents(__DIR__ . "/../404/index.html");
exit();
}
if (!preg_match('/^tags\/(.+?)(?:\/(\d+))?$/', $url, $matches)) redirectTo404();
if (isset($matches[2]) && (int)$matches[2] === 1) {
header("Location: /tags/{$matches[1]}", true, 301);
@ -26,10 +23,7 @@
$tag = strtolower(urldecode($matches[1]));
if (!preg_match('/^[\p{L}\p{N} _\.\-\&]+$/u', $tag)) {
echo file_get_contents(__DIR__ . "/../404/index.html");
exit();
}
if (!preg_match('/^[\p{L}\p{N} _\.\-\&]+$/u', $tag)) redirectTo404();
$page = isset($matches[2]) ? max(1, (int)$matches[2]) : 1;
$pageSize = 20;
@ -37,7 +31,7 @@
$tagged = $fetcher->fetch($tag, $page, $pageSize);
if (!$tagged || count($tagged) === 0) {
echo file_get_contents(__DIR__ . '/../404/index.html');
header("Location: /404/", true, 302);
exit();
}

View file

@ -51,7 +51,7 @@
{%- when 'books' -%}
{%- assign overviewBook = books.all | filterBooksByStatus: 'started' | reverse | first %}
{%- assign ogImage = ogImageBaseUrl | append: overviewBook.image -%}
{%- when 'books-year' -%}
{%- when 'reading-year' -%}
{%- assign pageTitle = 'Books' | append: ' • ' | append: year.value | append: ' • ' | append: globals.site_name -%}
{%- capture pageDescription -%}
Here's what I read in {{ year.value }}.

View file

@ -31,9 +31,9 @@ ErrorDocument 500 /500/index.html
RewriteRule ^music/artists/([^/]+)/?$ music/artists/index.php [L]
## books
RewriteRule ^books/([^/]+)/?$ books/index.php [L]
RewriteRule ^books/years/(\d{4})/?$ books/years/index.html [L]
RewriteRule ^books/?$ books/books.html [L]
RewriteRule ^reading/?$ reading/index.html [L]
RewriteRule ^reading/years/(\d{4})/?$ reading/years/$1.html [L]
RewriteRule ^reading/books/([\dXx-]+)/?$ reading/books/dynamic.php [L]
## movies
RewriteRule ^watching/movies/([^/]+)/?$ watching/movies/index.php [L]

View file

@ -1,9 +1,9 @@
---
permalink: /books/index.php
permalink: /reading/books/index.php
type: dynamic
schema: book
---
<a class="back-link" href="/books" title="Go back to the books index page">{% tablericon "arrow-left" %} Back to books</a>
<a class="back-link" href="/reading" title="Go back to the reading index page">{% tablericon "arrow-left" %} Back to reading</a>
<article class="book-focus">
<div class="book-display">
<img

View file

@ -1,7 +1,7 @@
---
title: Books
description: Here's what I'm reading at the moment.
permalink: "/books/index.html"
permalink: "/reading/index.html"
schema: books
updated: "now"
---

View file

@ -3,8 +3,8 @@ pagination:
data: books.years
size: 1
alias: year
permalink: "/books/years/{{ year.value }}/index.html"
schema: books-year
permalink: "/reading/years/{{ year.value }}/index.html"
schema: reading-year
---
{%- assign bookData = year.data | filterBooksByStatus: 'finished' -%}
{%- assign bookDataFavorites = bookData | findFavoriteBooks -%}
@ -12,7 +12,7 @@ schema: books-year
{%- assign currentYear = 'now' | date: "%Y" -%}
{%- assign yearString = year.value | append: '' -%}
{%- assign currentYearString = currentYear | append: '' -%}
<a href="/books" class="back-link">{% tablericon "arrow-left" %} Back to books</a>
<a href="/reading" class="back-link">{% tablericon "arrow-left" %} Back to reading</a>
<h2 class="page-title">{{ year.value }} • Books</h2>
{% if yearString == currentYearString %}
<p>I've finished <mark>{{ bookData.size }} book{% unless bookData.size == 1 %}s{% endunless %}</mark> this year.{%- if favoriteBooks %} Among my favorites are {{ favoriteBooks }}.{%- endif -%}</p>

View file

@ -5,7 +5,7 @@ description: Search through posts and other content on my site.
---
<h2 class="page-title">Search</h2>
<p>You can find <a href="/posts">posts</a>, <a href="/links">links</a>, <a href="/music/#artists">artists</a>, genres, <a href="/watching#movies">movies</a>, <a href="/watching#tv">shows</a> and <a href="/books">books</a> via the field below (though it only surfaces movies and shows I've watched and books I've written something about). <a href="/tags">You can also browse my tags list</a>.</p>
<p>You can find <a href="/posts">posts</a>, <a href="/links">links</a>, <a href="/music/#artists">artists</a>, genres, <a href="/watching#movies">movies</a>, <a href="/watching#tv">shows</a> and <a href="/reading">books</a> via the field below (though it only surfaces movies and shows I've watched and books I've written something about). <a href="/tags">You can also browse my tags list</a>.</p>
{% render "blocks/top-tags.liquid"
label:"Top tags"
tags:topTags.tags

View file

@ -5,7 +5,7 @@ description: Some basic stats about my activity on this site.
updated: "now"
---
<h2 class="page-title">Stats</h2>
<p>I share the <a href="/music" class="music">music I listen to</a>, <a href="/music/concerts" class="concerts">concerts I attend</a>, <a href="/watching" class="tv">shows and movies I watch</a>, <a href="/books" class="books">books I read</a>, <a href="/posts" class="article">posts I write</a>, and <a href="/links" class="link">links I enjoy</a> on this site. I have some basic counts of each below.</p>
<p>I share the <a href="/music" class="music">music I listen to</a>, <a href="/music/concerts" class="concerts">concerts I attend</a>, <a href="/watching" class="tv">shows and movies I watch</a>, <a href="/reading" class="books">books I read</a>, <a href="/posts" class="article">posts I write</a>, and <a href="/links" class="link">links I enjoy</a> on this site. I have some basic counts of each below.</p>
<hr />
<p class="music">I've listened to <mark>{{ stats.listen_count }} {{ stats.listen_count | pluralize: "track" }}</mark> by <mark>{{ stats.artist_count }} {{ stats.artist_count | pluralize: "artist" }}</mark> across <mark>{{ stats.genre_count }} {{ stats.genre_count | pluralize: "genre" }}</mark>.</p>
<p class="concerts">I've been to <mark>{{ stats.concert_count }} {{ stats.concert_count | pluralize: "concert" }}</mark> at <mark>{{ stats.venue_count }} {{ stats.venue_count | pluralize: "venue" }}</mark>.</p>