feat: initial commit

This commit is contained in:
Cory Dransfeldt 2025-03-27 16:46:02 -07:00
commit e214116e40
No known key found for this signature in database
253 changed files with 17406 additions and 0 deletions

View file

@ -0,0 +1,135 @@
---
permalink: /music/artists/index.php
type: dynamic
schema: artist
---
<a class="back-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
<article class="artist-focus">
<div class="artist-display">
<img
class="image-media"
srcset="
{{ globals.cdn_url }}<?= htmlspecialchars($artist["image"]) ?>?class=w200&type=webp 200w,
{{ globals.cdn_url }}<?= htmlspecialchars($artist["image"]) ?>?class=w600&type=webp 400w,
{{ globals.cdn_url }}<?= htmlspecialchars($artist["image"]) ?>?class=w800&type=webp 800w
"
sizes="(max-width: 450px) 200px,
(max-width: 850px) 400px,
800px"
src="{{ globals.cdn_url }}<?= htmlspecialchars($artist["image"]) ?>?class=w200&type=webp"
alt="<?= htmlspecialchars($artist["name"]) ?> • <?= htmlspecialchars(parseCountryField($artist["country"])) ?>"
decoding="async"
width="200"
height="200"
/>
<div class="media-meta">
<h2><?= htmlspecialchars($artist["name"]) ?></h2>
<span class="sub-meta country">{% tablericon "map-pin" %} <?= htmlspecialchars(
parseCountryField($artist["country"])
) ?></span>
<?php if ($artist["favorite"]): ?>
<span class="sub-meta favorite">{% tablericon "heart" %} This is one of my favorite artists!</span>
<?php endif; ?>
<?php if ($artist["tattoo"]): ?>
<span class="sub-meta tattoo">{% tablericon "needle" %} I have a tattoo inspired by this artist!</span>
<?php endif; ?>
<?php if ($artist["total_plays"] > 0): ?>
<span class="sub-meta">
<mark>
<?= $artist["total_plays"] . ' ' . pluralize($artist["total_plays"], "play") ?>
</mark>
</span>
<?php endif; ?>
<span class="sub-meta">
<?= htmlspecialchars($artist["emoji"] ?? $artist["genre"]["emoji"]) ?>
<a href="<?= htmlspecialchars($artist["genre"]["url"]) ?>">
<?= htmlspecialchars($artist["genre"]["name"]) ?>
</a>
</span>
</div>
</div>
<?php
renderAssociatedMedia(
$artist["related_artists"] ?? [],
$artist["books"] ?? [],
$artist["genres"] ?? [],
$artist["movies"] ?? [],
$artist["posts"] ?? [],
$artist["shows"] ?? []
);
?>
<?php if (!empty($artist["description"])): ?>
<h2>Overview</h2>
<div data-toggle-content class="text-toggle-hidden">
<?= parseMarkdown($artist["description"]) ?>
</div>
<button data-toggle-button>Show more</button>
<?php endif; ?>
<?php if (!empty($artist["concerts"])): ?>
<p id="concerts" class="concerts">
{% tablericon "device-speaker" %}
I've seen this artist live!
</p>
<ul>
<?php foreach ($artist["concerts"] as $concert): ?>
<?php
$venue = "";
if (!empty($concert["venue_name"])) {
if (!empty($concert["venue_latitude"]) && !empty($concert["venue_longitude"])) {
$venue = '<a href="https://www.openstreetmap.org/?mlat=' . htmlspecialchars($concert["venue_latitude"]) . '&mlon=' . htmlspecialchars($concert["venue_longitude"]) . '#map=18/' . htmlspecialchars($concert["venue_latitude"]) . '/' . htmlspecialchars($concert["venue_longitude"]) . '">' . htmlspecialchars($concert["venue_name_short"]) . '</a>';
} else {
$venue = htmlspecialchars($concert["venue_name_short"]);
}
}
$modalId = "modal-" . htmlspecialchars($concert["id"]);
?>
<li class="concerts">
On <mark><?php echo date("F j, Y", strtotime($concert["date"])); ?></mark>
<?php if (!empty($venue)): ?>
at <?php echo $venue; ?>
<?php endif; ?>
<?php if (!empty($concert["notes"])): ?>
<?php $notes = "### Notes\n" . htmlspecialchars($concert["notes"]); ?>
<noscript>
<input class="modal-input" id="<?php echo $modalId; ?>" type="checkbox" tabindex="0" />
<label class="modal-open" for="<?php echo $modalId; ?>">
{% tablericon "info-circle" %}
</label>
<div class="modal-wrapper">
<div class="modal-body">
<label class="modal-close" for="<?php echo $modalId; ?>">
{% tablericon "circle-x" %}
</label>
<?php echo parseMarkdown($notes); ?>
</div>
</div>
</noscript>
<button class="modal-open client-side" data-modal-trigger="<?php echo $modalId; ?>" data-modal-button>
{% tablericon "info-circle" %}
</button>
<dialog id="dialog-<?php echo $modalId; ?>" class="client-side">
<button class="modal-close" data-modal-button>
{% tablericon "circle-x" %}
</button>
<?php echo parseMarkdown($notes); ?>
</dialog>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<table>
<tr>
<th>Album</th>
<th>Plays</th>
<th>Year</th>
</tr>
<?php foreach ($artist["albums"] as $album): ?>
<tr>
<td><?= htmlspecialchars($album["name"]) ?></td>
<td><?= $album["total_plays"] > 0 ? $album["total_plays"] : "-" ?></td>
<td><?= $album["release_year"] ?></td>
</tr>
<?php endforeach; ?>
</table>
</article>

View file

@ -0,0 +1,66 @@
---
permalink: /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>
<article class="book-focus">
<div class="book-display">
<img
class="image-media"
srcset="
{{ globals.cdn_url }}<?= htmlspecialchars($book["image"]) ?>?class=verticalsm&type=webp 200w,
{{ globals.cdn_url }}<?= htmlspecialchars($book["image"]) ?>?class=verticalmd&type=webp 400w,
{{ globals.cdn_url }}<?= htmlspecialchars($book["image"]) ?>?class=verticalbase&type=webp 800w
"
sizes="(max-width: 450px) 203px,
(max-width: 850px) 406px,
(max-width: 1000px) 812px,
812px"
src="{{ globals.cdn_url }}<?= htmlspecialchars($book["image"]) ?>?class=verticalsm&type=webp"
alt="<?= htmlspecialchars($book["title"]) ?> by <?= htmlspecialchars($book["author"]) ?>"
decoding="async"
width="200"
height="307"
/>
<div class="media-meta">
<h2><?= htmlspecialchars($book["title"]) ?></h2>
<?php if (!empty($book["rating"])): ?>
<span><?= htmlspecialchars($book["rating"]) ?></span>
<?php endif; ?>
<?php if (!empty($book["author"])): ?>
<span class="sub-meta">By <?= htmlspecialchars($book["author"]) ?></span>
<?php endif; ?>
<?php if ($book["favorite"]): ?>
<span class="sub-meta favorite">{% tablericon "heart" %} This is one of my favorite books!</span>
<?php endif; ?>
<?php if ($book["tattoo"]): ?>
<span class="sub-meta tattoo">{% tablericon "needle" %} I have a tattoo inspired by this book!</span>
<?php endif; ?>
<?php if ($book["status"] == 'finished'): ?>
<span class="sub-meta">Finished on: <mark><?= date('F j, Y', strtotime($book["date_finished"])) ?></mark></span>
<?php elseif ($book["status"] == 'started'): ?>
<progress value="<?= htmlspecialchars($book["progress"]) ?>" max="100"><?php $book["progress"] . '%'; ?></progress>
<?php endif; ?>
</div>
</div>
<?php if (!empty($book["review"])): ?>
{% render "blocks/banners/warning.liquid", text: "There are probably spoilers after this banner — this is a warning about them." %}
<h2>My thoughts</h2>
<?= parseMarkdown($book["review"]) ?>
<?php endif; ?>
<?php
renderAssociatedMedia(
$book["artists"] ?? [],
$book["related_books"] ?? [],
$book["genres"] ?? [],
$book["movies"] ?? [],
$book["posts"] ?? [],
$book["shows"] ?? []
);
?>
<?php if (!empty($book["description"])): ?>
<h2>Overview</h2>
<?= parseMarkdown($book["description"]) ?>
<?php endif; ?>
</article>

View file

@ -0,0 +1,42 @@
---
permalink: /music/genres/index.php
type: dynamic
schema: genre
---
<a class="back-link" href="/music" title="Go back to the music index page">{% tablericon "arrow-left" %} Back to music</a>
<h2><?= htmlspecialchars($genre["emoji"]) ?> <?= htmlspecialchars($genre["name"]) ?></h2>
<article class="genre-focus">
<?php $artistCount = count($genre["artists"]); ?>
<?php if ($artistCount > 0): ?>
<p>My top <mark><?= htmlspecialchars($genre["name"]) ?></mark> artists are
<?php
$artists = array_slice($genre["artists"], 0, 5);
$artistLinks = [];
foreach ($artists as $artist) {
$artistLinks[] = '<a href="' . htmlspecialchars($artist["url"]) . '">' . htmlspecialchars($artist["name"]) . '</a>';
}
echo implode(', ', $artistLinks);
?>. I've listened to <mark><?= $genre["total_plays"] . ' ' . pluralize($genre["total_plays"], "play") ?></mark> tracks from this genre.</p>
<hr />
<?php endif; ?>
<?php
renderAssociatedMedia(
[],
$genre["books"] ?? [],
[],
$genre["movies"] ?? [],
$genre["posts"] ?? [],
[]
);
?>
<?php if (!empty($genre["description"])): ?>
<h3>Overview</h3>
<div data-toggle-content class="text-toggle-hidden">
<?= parseMarkdown($genre["description"]) ?>
<p><a href="<?= htmlspecialchars($genre["wiki_link"]) ?>">Continue reading at Wikipedia.</a></p>
<p><em>Wikipedia content provided under the terms of the
<a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons BY-SA license</a></em></p>
</div>
<button data-toggle-button>Show more</button>
<?php endif; ?>
</article>

View file

@ -0,0 +1,58 @@
---
permalink: /watching/movies/index.php
type: dynamic
schema: movie
---
<a class="back-link" href="/watching" title="Go back to the watching index page">{% tablericon "arrow-left" %} Back to watching</a>
<article class="movie-focus">
<img
srcset="
{{ globals.cdn_url }}<?= htmlspecialchars($movie["backdrop"]) ?>?class=bannersm&type=webp 256w,
{{ globals.cdn_url }}<?= htmlspecialchars($movie["backdrop"]) ?>?class=bannermd&type=webp 512w,
{{ globals.cdn_url }}<?= htmlspecialchars($movie["backdrop"]) ?>?class=bannerbase&type=webp 1024w
"
sizes="(max-width: 450px) 256px,
(max-width: 850px) 512px,
1024px"
src="{{ globals.cdn_url }}<?= htmlspecialchars($movie["backdrop"]) ?>?class=bannersm&type=webp"
alt="<?= htmlspecialchars($movie["title"]) ?> (<?= htmlspecialchars($movie["year"]) ?>)"
class="image-banner"
decoding="async"
width="256"
height="180"
/>
<div class="media-meta">
<h2><?= htmlspecialchars($movie["title"]) ?> (<?= htmlspecialchars($movie["year"]) ?>)</h2>
<?php if (!empty($movie["rating"])): ?>
<span><?= htmlspecialchars($movie["rating"]) ?></span>
<?php endif; ?>
<?php if ($movie["favorite"]): ?>
<span class="sub-meta favorite">{% tablericon "heart" %} This is one of my favorite movies!</span>
<?php endif; ?>
<?php if ($movie["tattoo"]): ?>
<span class="sub-meta tattoo">{% tablericon "needle" %} I have a tattoo inspired by this movie!</span>
<?php endif; ?>
<?php if (!empty($movie["last_watched"])): ?>
<span class="sub-meta">Last watched on <?= date('F j, Y', strtotime($movie["last_watched"])) ?>.</span>
<?php endif; ?>
</div>
<?php if (!empty($movie["review"])): ?>
{% render "blocks/banners/warning.liquid", text: "There are probably spoilers after this banner — this is a warning about them." %}
<h2>My thoughts</h2>
<?= parseMarkdown($movie["review"]) ?>
<?php endif; ?>
<?php
renderAssociatedMedia(
$movie["artists"] ?? [],
$movie["books"] ?? [],
$movie["genres"] ?? [],
$movie["related_movies"] ?? [],
$movie["posts"] ?? [],
$movie["shows"] ?? []
);
?>
<?php if (!empty($movie["description"])): ?>
<h2>Overview</h2>
<?= $movie["description"] ?>
<?php endif; ?>
</article>

View file

@ -0,0 +1,58 @@
---
permalink: /watching/shows/index.php
type: dynamic
schema: show
---
<a class="back-link" href="/watching" title="Go back to the watching index page">{% tablericon "arrow-left" %} Back to watching</a>
<article class="watching focus">
<img
srcset="
{{ globals.cdn_url }}<?= htmlspecialchars($show["backdrop"]) ?>?class=bannersm&type=webp 256w,
{{ globals.cdn_url }}<?= htmlspecialchars($show["backdrop"]) ?>?class=bannermd&type=webp 512w,
{{ globals.cdn_url }}<?= htmlspecialchars($show["backdrop"]) ?>?class=bannerbase&type=webp 1024w
"
sizes="(max-width: 450px) 256px,
(max-width: 850px) 512px,
1024px"
src="{{ globals.cdn_url }}<?= htmlspecialchars($show["backdrop"]) ?>?class=bannersm&type=webp"
alt="<?= htmlspecialchars($show["title"]) ?> (<?= htmlspecialchars($show["year"]) ?>)"
class="image-banner"
decoding="async"
width="256"
height="180"
/>
<div class="media-meta">
<h2><?= htmlspecialchars($show["title"]) ?> (<?= htmlspecialchars($show["year"]) ?>)</h2>
<?php if (!empty($show["favorite"])): ?>
<span class="sub-meta favorite">{% tablericon "heart" %} This is one of my favorite shows!</span>
<?php endif; ?>
<?php if (!empty($show["tattoo"])): ?>
<span class="sub-meta tattoo">{% tablericon "needle" %} I have a tattoo inspired by this show!</span>
<?php endif; ?>
<?php if (!empty($show["episode"]["formatted_episode"])): ?>
<span class="sub-meta">I last watched
<mark><?= htmlspecialchars($show["episode"]["formatted_episode"]) ?></mark>
on <?= date('F j, Y', strtotime($show["episode"]["last_watched_at"])) ?>.
</span>
<?php endif; ?>
</div>
<?php if (!empty($show["review"])): ?>
{% render "blocks/banners/warning.liquid", text: "There are probably spoilers after this banner — this is a warning about them." %}
<h2>My thoughts</h2>
<?= parseMarkdown($show["review"]) ?>
<?php endif; ?>
<?php
renderAssociatedMedia(
$show["artists"] ?? [],
$show["books"] ?? [],
$show["genres"] ?? [],
$show["movies"] ?? [],
$show["posts"] ?? [],
$show["related_shows"] ?? []
);
?>
<?php if (!empty($show["description"])): ?>
<h2>Overview</h2>
<?= parseMarkdown($show["description"]) ?>
<?php endif; ?>
</article>

14
src/pages/index.html Normal file
View file

@ -0,0 +1,14 @@
---
permalink: /
---
{% render "home/intro.liquid"
intro:globals.intro,
nowPlaying:nowPlaying.content
%}
{% render "home/recent-media.liquid"
media:recentMedia,
globals:globals
%}
{% render "home/recent-activity.liquid"
items:recentActivity
%}

View file

@ -0,0 +1,55 @@
---
title: Books
description: Here's what I'm reading at the moment.
permalink: "/books/index.html"
schema: books
updated: "now"
---
{%- assign currentYear = 'now' | date: "%Y" -%}
{%- assign bookData = books.all | filterBooksByStatus: 'started' | reverse -%}
{%- assign currentBookCount = books.currentYear | size -%}
<h2 class="page-title">Currently reading</h2>
<p>Here's what I'm reading at the moment. I've finished <mark>{{ currentBookCount }} books</mark> this year. I've read <mark>{{ books.daysRead }}</mark> days in a row and counting.</p>
<p class="book-years">{{ books.years | bookYearLinks }}</p>
{% render "blocks/banners/rss.liquid",
url: "/feeds/books.xml",
text: "Subscribe to my books feed or follow along on this page"
%}
<hr />
{% for book in bookData %}
{% capture alt %}{{ book.title }} by {{ book.authors }}{% endcapture %}
<article class="book-entry">
<a href="{{ book.url }}">
<img
srcset="
{{ globals.cdn_url }}{{ book.image }}?class=verticalsm&type=webp 200w,
{{ globals.cdn_url }}{{ book.image }}?class=verticalmd&type=webp 400w
"
sizes="(max-width: 450px) 200px,
400px"
src="{{ globals.cdn_url }}{{ book.image }}?class=verticalsm&type=webp"
alt="{{ alt | replaceQuotes }}"
loading="lazy"
decoding="async"
width="200"
height="307"
/>
</a>
<div class="media-meta">
<a href="{{ book.url }}">
<h2>{{ book.title }}</h2>
</a>
{% if book.author %}
<span class="sub-meta">By {{ book.author }}</span>
{% endif %}
{% if book.progress %}
{% render "media/progress-bar.liquid",
percentage:book.progress
%}
{% endif %}
{% if book.description %}
<div class="description">{{ book.description | normalize_whitespace | markdown | htmlTruncate }}</div>
{% endif %}
</div>
</article>
{% endfor %}

View file

@ -0,0 +1,29 @@
---
pagination:
data: books.years
size: 1
alias: year
permalink: "/books/years/{{ year.value }}/index.html"
schema: books-year
---
{%- assign bookData = year.data | filterBooksByStatus: 'finished' -%}
{%- assign bookDataFavorites = bookData | findFavoriteBooks -%}
{%- capture favoriteBooks -%}{{ bookDataFavorites | shuffleArray | mediaLinks: "book", 5 }}{%- endcapture -%}
{%- 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>
<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>
{% else %}
<p>I finished <mark>{{ bookData.size }} book{% unless bookData.size == 1 %}s{% endunless %}</mark> in <mark>{{ year.value }}</mark>.{%- if favoriteBooks %} Among my favorites were {{ favoriteBooks }}.{%- endif -%}</p>
{% endif %}
<hr />
{% render "media/grid.liquid",
globals:globals,
data:bookData,
shape:"vertical",
count:200,
loading:"eager"
%}

View file

@ -0,0 +1,48 @@
---
title: Concerts
description: These are concerts I've attended (not all of them — just the ones I could remember or glean from emails, photo metadata et al).
pagination:
data: concerts
size: 30
permalink: "/music/concerts/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
---
{%- if pagination.pageNumber == 0 -%}
<h2 class="page-title">Concerts</h2>
<p>These are concerts I've attended (not all of them — just the ones I could remember or glean from emails, photo metadata et al). I've been to at least <mark>{{ concerts | size }}</mark> shows. <a href="/music" class="music">You can also take a look at the music I've been listening to lately</a>.</p>
<hr />
{%- endif -%}
<ul class="standalone">
{%- for concert in pagination.items -%}
{%- capture artistName -%}
{% if concert.artist.url %}
<a href="{{ concert.artist.url }}" class="music">{{ concert.artist.name }}</a>
{% else %}
{{ concert.artist.name }}
{% endif %}
{%- endcapture -%}
{%- capture venue -%}
{% if concert.venue.name %}
{% if concert.venue.latitude and concert.venue.longitude %}
<a href="https://www.openstreetmap.org/?mlat={{ concert.venue.latitude }}&mlon={{ concert.venue.longitude }}#map=18/{{ concert.venue.latitude }}/{{ concert.venue.longitude }}">{{ concert.venue.name_short }}</a>
{% else %}
{{ concert.venue.name_short }}
{% endif %}
{% endif %}
{%- endcapture -%}
<li>
<strong>{{ artistName }}</strong> on {{ concert.date | date: "%B %e, %Y" }}
{% if venue %} at {{ venue }}{% endif %}
{%- if concert.notes -%}
{% assign notes = concert.notes | prepend: "### Notes\n" | markdown %}
{% render "blocks/modal.liquid",
icon:"info-circle",
content:notes,
id:concert.id
%}
{%- endif -%}
</li>
{%- endfor -%}
</ul>
{% render "nav/paginator.liquid",
pagination:pagination
%}

View file

@ -0,0 +1,80 @@
---
title: Music
description: This is everything I've been listening to recently — it's collected in a database as I listen to it and displayed here.
permalink: "/music/index.html"
schema: music-index
updated: "now"
---
<h2 class="page-title">{{ title }}</h2>
<p>I've listened to <mark>{{ music.week.artists.size }} artists</mark>, <mark>{{ music.week.albums.size }} albums</mark> and <mark>{{ music.week.totalTracks }} tracks</mark> this week. Most of that has been {{ music.week.genres | mediaLinks: "genre", 5 }}.</p>
<p><mark>Take a look at what I've listened to</mark> <a href="/music/this-month">this month</a> or <a href="/music/concerts" class="concerts">check out the concerts I've been to</a>.</p>
{% render "blocks/now-playing.liquid",
nowPlaying:nowPlaying.content
%}
<hr />
<h3 id="artists">
<a href="/music/this-week/artists">
{% tablericon "microphone-2" %} Artists
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:music.week.artists,
count:8,
loading:"eager"
%}
{% render "media/music/tables/all-time/artists.liquid",
globals:globals,
topArtists:topArtists
%}
<h3 id="albums">
<a href="/music/this-week/albums">
{% tablericon "vinyl" %} Albums
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:music.week.albums,
count:8
%}
{% render "media/music/tables/all-time/albums.liquid",
globals:globals,
topAlbums:topAlbums
%}
<h3 id="tracks">
<a href="/music/this-week/tracks/">
{% tablericon "playlist" %}
Tracks
</a>
</h3>
<div>
<input id="tracks-recent" name="track-options" type="radio" aria-hidden="true" checked />
<input id="tracks-chart" name="track-options" type="radio" aria-hidden="true" />
<label for="tracks-recent" class="button" data-toggle="tracks-recent">Recent</label>
<label for="tracks-chart" class="button" data-toggle="tracks-chart">This week</label>
<div class="tracks-recent">
{% render "media/music/charts/recent.liquid",
globals:globals,
data:music.recent
%}
</div>
<div class="tracks-chart">
{% render "media/music/charts/rank.liquid",
data:music.week.tracks,
count:10
%}
</div>
</div>
{%- if albumReleases.upcoming.size > 0 -%}
<h3 id="album-releases">
<a href="/music/album-releases/">
{% tablericon "calendar-time" %}
Anticipated albums
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:albumReleases.upcoming,
count:8
%}
{%- endif -%}

View file

@ -0,0 +1,23 @@
---
title: Anticipated albums
description: These are the album releases I'm currently looking forward to.
permalink: "/music/album-releases/index.html"
schema: music-releases
updated: "now"
---
<h2 class="page-title">{{ title }}</h2>
<p>These are all albums I'm looking forward to (this year — next year?).</p>
<p><mark>Take a look at what I'm listening to</mark> <a href="/music/">now</a> or <a href="/music/concerts" class="concerts">check out the concerts I've been to</a>.</p>
{% render "blocks/banners/calendar.liquid",
url:"/music/releases.ics",
text:"Subscribe to my album releases calendar"
%}
<hr />
{%- if albumReleases.upcoming.size > 0 -%}
{% render "media/grid.liquid",
globals:globals,
data:albumReleases.upcoming,
%}
{%- else -%}
<p style="text-align:center"><mark>OH NO THERE'S NO MUSIC TO LOOK FORWARD TO.</mark></p>
{%- endif -%}

View file

@ -0,0 +1,22 @@
---
title: Albums this month
description: These are the albums I've been listening to this month. All of them are awesome.
pagination:
data: music.month.albums
size: 24
permalink: "/music/this-month/albums/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: music-month-albums
updated: "now"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Albums this month</h2>
<p>These are the albums I've been listening to this month. All of them are awesome. Listed in descending order from most plays to least.</p>
<p><mark>You can also take a look at</mark> the <a href="/music/this-month/artists">artists I've listened to this month</a>, <a href="/music/this-week/artists">the artists I've listened to this week</a> or <a href="/music/this-week/albums">the albums I've listened to this week</a>.</p>
<p><a href="/music/concerts" class="concerts">I also keep track of the concerts I've been to</a>.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination
%}

View file

@ -0,0 +1,22 @@
---
title: Artists this month
description: These are the artists I've been listening to this month. All of them are awesome.
pagination:
data: music.month.artists
size: 24
permalink: "/music/this-month/artists/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: music-month-artists
updated: "now"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Artists this month</h2>
<p>These are the artists I've been listening to this month. All of them are awesome. Listed in descending order from most plays to least.</p>
<p><mark>You can also take a look at</mark> the <a href="/music/this-week/albums">the albums I've listened to this week</a>, <a href="/music/this-month/albums">albums I've listened to this month</a> or <a href="/music/this-week/artists">the artists I've listened to this week</a>.</p>
<p><a href="/music/concerts" class="concerts">I also keep track of the concerts I've been to</a>.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination
%}

View file

@ -0,0 +1,36 @@
---
title: Music this month
description: This is everything I've been listening to this month — it's collected in a database as I listen to it and displayed here.
permalink: "/music/this-month/index.html"
updated: "now"
---
<h2 class="page-title">{{ title }}</h2>
<p>I've listened to <mark>{{ music.month.artists.size }} artists</mark>, <mark>{{ music.month.albums.size }} albums</mark> and <mark>{{ music.month.totalTracks }} tracks</mark> this month. Most of that has been {{ music.month.genres | mediaLinks: "genre", 5 }}.</p>
<p><mark>Take a look at what I've listened to</mark> <a href="/music">this week</a> or <a href="/music/concerts" class="concerts">check out the concerts I've been to</a>.</p>
<hr />
<h3 id="artists">
<a href="/music/this-month/artists">
{% tablericon "microphone-2" %} Artists
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:music.month.artists,
count:8,
loading: "eager"
%}
<h3 id="albums">
<a href="/music/this-month/albums">
{% tablericon "vinyl" %} Albums
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:music.month.albums,
count:8
%}
<h3 id="tracks">{% tablericon "playlist" %} Tracks</h3>
{% render "media/music/charts/rank.liquid",
data:music.month.tracks,
count:10
%}

View file

@ -0,0 +1,22 @@
---
title: Albums this week
description: These are the albums I've been listening to this week. All of them are awesome.
pagination:
data: music.week.albums
size: 24
permalink: "/music/this-week/albums/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: music-week-albums
updated: "now"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Albums this week</h2>
<p>These are the albums I've been listening to this week. All of them are awesome. Listed in descending order from most plays to least.</p>
<p><mark>You can also take a look at</mark> the <a href="/music/this-month/artists">artists I've listened to this month</a>, <a href="/music/this-week/artists">the artists I've listened to this week</a> or <a href="/music/this-month/albums">the albums I've listened to this month</a>.</p>
<p><a href="/music/concerts" class="concerts">I also keep track of the concerts I've been to</a>.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination
%}

View file

@ -0,0 +1,22 @@
---
title: Artists this week
description: These are the artists I've been listening to this week. All of them are awesome.
pagination:
data: music.week.artists
size: 24
permalink: "/music/this-week/artists/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: music-week-artists
updated: "now"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Artists this week</h2>
<p>These are the artists I've been listening to this week. All of them are awesome. Listed in descending order from most plays to least.</p>
<p><mark>You can also take a look at</mark> the <a href="/music/this-week/albums">albums I've listened to this week</a>, <a href="/music/this-month/albums">the albums I've listened to this month</a> or <a href="/music/this-month/artists">the artists I've listened to this month</a>.</p>
<p><a href="/music/concerts" class="concerts">I also keep track of the concerts I've been to</a>.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination
%}

View file

@ -0,0 +1,21 @@
---
title: Tracks this week
description: These are tracks artists I've been listening to this week. Some of them are awesome.
pagination:
data: music.week.tracks
size: 30
permalink: "/music/this-week/tracks/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: music-week-tracks
updated: "now"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Artists this week</h2>
<p>These are the tracks I've been listening to this week. Some of them are awesome. Listed in descending order from most plays to least.</p>
<p><mark>You can also take a look at</mark> the <a href="/music/this-week/albums">albums I've listened to this week</a>, <a href="/music/this-month/albums">the albums I've listened to this month</a>, <a href="/music/this-week/artists">the artists I've listened to this week</a> or the <a href="/music/this-month/artists">the artists I've listened to this month</a>.</p>
<p><a href="/music/concerts" class="concerts">I also keep track of the concerts I've been to</a>.</p>
<hr />
{% endif %}
{% render "media/music/charts/rank.liquid",
data:pagination.items,
pagination:pagination
%}

View file

@ -0,0 +1,22 @@
---
title: Favorite movies
description: These are my favorite movies. There are many like them, but these are mine.
pagination:
data: movies.favorites
size: 24
permalink: "/watching/favorites/movies/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: favorite-movies
---
<a href="/watching" class="back-link">{% tablericon "arrow-left" %} Back to watching</a>
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">{{ title }}</h2>
<p>These are my favorite movies. There are many like them, but these are mine.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination,
shape:"vertical"
count:24
%}

View file

@ -0,0 +1,22 @@
---
title: Favorite shows
description: These are my favorite shows. There are many like them, but these are mine.
pagination:
data: tv.favorites
size: 24
permalink: "/watching/favorites/shows/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: favorite-shows
---
<a href="/watching" class="back-link">{% tablericon "arrow-left" %} Back to watching</a>
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">{{ title }}</h2>
<p>These are my favorite shows. There are many like them, but these are mine.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination,
shape:"vertical"
count:24
%}

View file

@ -0,0 +1,66 @@
---
title: Watching
description: Here's all of the TV and movies I've been watching presented in what is (hopefully) an organized fashion.
permalink: "/watching/index.html"
schema: watching
updated: "now"
---
{%- assign featuredMovie = movies.recentlyWatched | shuffleArray | first -%}
<h2 class="page-title">{{ title }}</h2>
{% render "media/watching/hero.liquid",
globals:globals,
movie:featuredMovie
%}
<p>Here's all of the TV and movies I've been watching presented in what is (hopefully) an organized fashion.</p>
<p><a href="/watching/shows/upcoming">You can see all of the shows I've got queued up here.</a></p>
{% render "blocks/banners/rss.liquid",
url: "/feeds/movies.xml",
text: "Subscribe to my movies feed or follow along on this page"
%}
<hr />
<h3 id="movies">
<a href="/watching/recent/movies">
{% tablericon "movie" %} Recent movies
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:movies.recentlyWatched,
shape:"vertical",
count:6
%}
<h3 id="tv">
<a href="/watching/recent/shows">
{% tablericon "device-tv-old" %} Recent shows
</a>
</h3>
{% render "media/grid.liquid",
globals:globals,
data:tv.recentlyWatched,
shape:"vertical",
count:6
%}
<h3 id="favorite-movies">
<a href="/watching/favorites/movies">
{% tablericon "star" %} Favorite movies
</a>
</h3>
{% assign favoriteMovies = movies.favorites | shuffleArray %}
{% render "media/grid.liquid",
globals:globals,
data:favoriteMovies,
shape:"vertical",
count:6
%}
<h3 id="favorite-shows">
<a href="/watching/favorites/shows">
{% tablericon "star" %} Favorite shows
</a>
</h3>
{% assign favoriteShows = tv.favorites | shuffleArray %}
{% render "media/grid.liquid",
globals:globals,
data:favoriteShows,
shape:"vertical",
count:6
%}

View file

@ -0,0 +1,22 @@
---
title: Recent movies
description: These are my favorite movies. There are many like them, but these are mine.
pagination:
data: movies.recentlyWatched
size: 24
permalink: "/watching/recent/movies/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: favorite-movies
---
<a href="/watching" class="back-link">{% tablericon "arrow-left" %} Back to watching</a>
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">{{ title }}</h2>
<p>These are my favorite movies. There are many like them, but these are mine.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination,
shape:"vertical"
count:24
%}

View file

@ -0,0 +1,22 @@
---
title: Recent shows
description: These are my favorite shows. There are many like them, but these are mine.
pagination:
data: tv.recentlyWatched
size: 24
permalink: "/watching/recent/shows/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
schema: favorite-shows
---
<a href="/watching" class="back-link">{% tablericon "arrow-left" %} Back to watching</a>
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">{{ title }}</h2>
<p>These are my favorite shows. There are many like them, but these are mine.</p>
<hr />
{% endif %}
{% render "media/grid.liquid",
globals:globals,
data:pagination.items,
pagination:pagination,
shape:"vertical"
count:24
%}

View file

@ -0,0 +1,28 @@
---
title: Upcoming shows
description: Here are all of the episodes I've got queued up from the shows I'm watching.
permalink: "/watching/shows/upcoming/index.html"
schema: upcoming-shows
updated: "now"
---
{%- assign featuredMovie = upcomingShows.watching | shuffleArray | first -%}
<a href="/watching" class="back-link">{% tablericon "arrow-left" %} Back to watching</a>
<h2 class="page-title">{{ title }}</h2>
{% render "media/watching/hero.liquid",
globals:globals,
movie:featuredMovie
%}
<p>Here's all of the TV shows I'm keeping up with. Shows I <em>want</em> to watch but haven't started are at the bottom of the page — the rest are sorted by air and watch date. Shows I follow with new episodes appear first, followed by shows I'm catching up on and those with new episodes on the way.</p>
<hr />
<h3>Watching</h3>
{% render "media/grid.liquid",
globals:globals,
data:upcomingShows.watching,
shape:"vertical"
%}
<h3>Not started</h3>
{% render "media/grid.liquid",
globals:globals,
data:upcomingShows.unstarted,
shape:"vertical"
%}

16
src/pages/page.html Normal file
View file

@ -0,0 +1,16 @@
---
pagination:
data: pages
size: 1
alias: page
permalink: "{{ page.permalink }}/index.html"
image: "{{ page.open_graph_image | prepend: globals.cdn_url | default: globals.avatar }}"
updated: "{{ page.updated | default: null }}"
schema: page
---
{% render "blocks/index.liquid",
blocks:page.blocks,
globals:globals,
collections:collections,
links:links
%}

3
src/pages/pages.json Normal file
View file

@ -0,0 +1,3 @@
{
"layout": "base.liquid"
}

View file

@ -0,0 +1,31 @@
---
title: Links
description: These are links I've liked or otherwise found interesting. They're all added manually, after having been read and, I suppose, properly considered.
pagination:
data: links.all
size: 30
permalink: "/links/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Links</h2>
<p>These are links I've liked or otherwise found interesting. They're all added manually, after having been read and, I suppose, properly considered.</p>
{% render "blocks/banners/rss.liquid",
url: "/feeds/links.xml",
text: "Subscribe to my links feed or follow along on this page"
%}
<hr />
{% endif %}
<div class="link-grid">
{% for link in pagination.items %}
<div class="link-box">
<time datetime="{{ link.date }}">{{ link.date | date: "%B %e, %Y" }}</time>
<article>
<a href="{{ link.link }}" title="{{ link.title | escape }}"><strong>{{ link.title }}</strong></a>
{% if link.author %} via <a href="{{ link.author.url }}">{{ link.author.name }}</a>{% endif %}
</article>
</div>
{% endfor %}
</div>
{% render "nav/paginator.liquid",
pagination:pagination
%}

View file

@ -0,0 +1,34 @@
---
title: All posts
pagination:
data: posts.all
size: 15
permalink: "/posts/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber }}/{% endif %}index.html"
---
{% if pagination.pageNumber == 0 %}
<h2 class="page-title">Posts</h2>
<p>These are all of my blog posts on this site (I like some more than others).</p>
<p>I tend to write about whatever strikes me, with a focus on development, technology, automation or issues I run into with these things. This is all typically light on editing with and heavy on spur of the moment thoughts.</p>
{% render "blocks/banners/rss.liquid",
url: "/feeds/posts.xml",
text: "Subscribe to my posts feed or follow along on this page"
%}
<hr />
{% endif %}
{% for post in pagination.items %}
<article>
<aside>
{%- if post.featured -%}{% tablericon "star" %}{%- endif -%}
<time datetime="{{ post.date }}">
{{ post.date | date: "%B %e, %Y" }}
</time>
</aside>
<h3>
<a href="{{ post.url }}">{{ post.title }}</a>
</h3>
<p>{{ post.description | markdown }}</p>
</article>
{% endfor %}
{% render "nav/paginator.liquid",
pagination:pagination
%}

View file

@ -0,0 +1,61 @@
---
pagination:
data: posts.all
size: 1
alias: post
permalink: "{{ post.url }}/index.html"
schema: blog
---
<article class="standalone">
<aside>
{%- if post.featured -%}{% tablericon "star" %}{%- endif -%}
<time datetime="{{ post.date }}">
{{ post.date | date: "%B %e, %Y" }}
</time>
</aside>
<h3>
{{ post.title }}
</h3>
<div>
{% render "blocks/banners/old-post.liquid",
isOldPost:post.old_post
%}
{%- if post.image -%}
<img
srcset="
{{ globals.cdn_url }}{{ post.image }}?class=w200&type=webp 200w,
{{ globals.cdn_url }}{{ post.image }}?class=w400&type=webp 400w,
{{ globals.cdn_url }}{{ post.image }}?class=w800&type=webp 800w,
{{ globals.cdn_url }}{{ post.image }}?class=w1600&type=webp 1600w
"
sizes="(max-width: 450px) 200px,
(max-width: 850px) 400px,
(max-width: 1000px) 800px,
1200px"
src="{{ globals.cdn_url }}{{ post.image }}?class=w200"
alt="{{ post.image_alt | replaceQuotes }}"
class="image-banner"
loading="eager"
decoding="async"
width="200"
height="auto"
/>
{%- endif -%}
{{ post.content | markdown }}
{% render "blocks/index.liquid",
blocks:post.blocks
%}
{% render "blocks/associated-media.liquid",
artists: post.artists,
books: post.books,
genres: post.genres,
movies: post.movies,
posts: post.posts,
shows: post.shows
%}
{% render "blocks/banners/mastodon.liquid"
url:post.mastodon_url
%}
{% render "blocks/banners/coffee.liquid" %}
</div>
</article>

View file

@ -0,0 +1,35 @@
---
title: Blogroll
permalink: /blogroll/index.html
description: These are awesome blogs that I enjoy and you may enjoy too.
---
<h2 class="page-title">{{ title }}</h2>
<p>You can <a href="/blogroll.opml">download an OPML file</a> containing all of these feeds and import them into your RSS reader.</p>
<table>
<tr>
<th>Name</th>
<th>Link</th>
<th>Subscribe</th>
</tr>
{% for blog in blogroll %}
<tr>
<td>{{ blog.name }}</td>
<td><a href="{{ blog.url }}">{{ blog.url | replace: "https://", "" }}</a></td>
<td class="blog-roll-icons">
{%- if blog.rss_feed -%}
<a class="rss" href="{{ blog.rss_feed }}" aria-label="RSS feed for {{ blog.name }}">{% tablericon "rss" %}</a>&nbsp;
{%- endif -%}
{%- if blog.json_feed -%}
<a class="json" href="{{ blog.json_feed }}" aria-label="JSON feed for {{ blog.name }}">{% tablericon "json" %}</a>&nbsp;
{%- endif -%}
{%- if blog.newsletter -%}
<a class="mail-plus" href="{{ blog.newsletter }}" aria-label="Subscribe to {{ blog.name }}'s newsletter">{% tablericon "mail-plus" %}</a>&nbsp;
{%- endif -%}
{%- if blog.mastodon -%}
<a class="brand-mastodon" href="{{ blog.mastodon }}" aria-label="Follow {{ blog.name }} on Mastodon">{% tablericon "brand-mastodon" %}</a>&nbsp;
{%- endif -%}
</td>
</tr>
{% endfor %}
</table>
<p>Head on over to <a href="https://blogroll.org">blogroll.org</a> to find more blogs to follow or search for feeds using <a href="https://feedle.world">feedle</a>.</p>

View file

@ -0,0 +1,42 @@
---
title: 403
description: Sorry, you're not allowed to see that!
permalink: /403/index.html
eleventyExcludeFromCollections: true
excludeFromSitemap: true
---
<div class="hero">
<img
srcset="
{{ globals.cdn_url }}/7fafebe2-1779-49e0-a61a-24ef8ef8f7a0.jpg?class=bannersm&type=webp 256w,
{{ globals.cdn_url }}/7fafebe2-1779-49e0-a61a-24ef8ef8f7a0.jpg?class=bannermd&type=webp 512w,
{{ globals.cdn_url }}/7fafebe2-1779-49e0-a61a-24ef8ef8f7a0.jpg?class=bannerbase&type=webp 1024w
"
sizes="(max-width: 450px) 256px,
(max-width: 850px) 512px,
1024px"
src="{{ globals.cdn_url }}/7fafebe2-1779-49e0-a61a-24ef8ef8f7a0.jpg?class=bannersm&type=webp"
alt="An image of Daria Morgendorffer sitting at a table reading As I Lay Dying."
class="image-banner"
loading="lazy"
decoding="async"
width="720"
height="480"
/>
</div>
<div>
<h2 style="text-align:center">403</h2>
<p>Hi! So, this is a 403 page. In internet parlance that translates to forbidden which, unfortunately, means you're not allowed to see what you asked this server for.</p>
</div>
<script>
const track403 = () => {
const referrer = document.referrer || "Unknown referrer";
const userAgent = navigator.userAgent;
if (window.umami)
umami.track("Blocked Access", { referrer, user_agent: userAgent });
};
document.addEventListener("DOMContentLoaded", track403);
</script>

View file

@ -0,0 +1,44 @@
---
title: 404
description: What kind of idiots do you have working here?
permalink: /404/index.html
eleventyExcludeFromCollections: true
excludeFromSitemap: true
---
<div class="hero">
<img
srcset="
{{ globals.cdn_url }}/daac2a48-455f-4b7b-a727-b33868cbb2fc.jpg?class=bannersm&type=webp 256w,
{{ globals.cdn_url }}/daac2a48-455f-4b7b-a727-b33868cbb2fc.jpg?class=bannermd&type=webp 512w,
{{ globals.cdn_url }}/daac2a48-455f-4b7b-a727-b33868cbb2fc.jpg?class=bannerbase&type=webp 1024w
"
sizes="(max-width: 450px) 256px,
(max-width: 850px) 512px,
1024px"
src="{{ globals.cdn_url }}/daac2a48-455f-4b7b-a727-b33868cbb2fc.jpg?class=bannersm&type=webp"
alt="An image Kevin McCallister screaming taken from the movie Home Alone 2."
class="image-banner"
loading="lazy"
decoding="async"
width="720"
height="480"
/>
</div>
<div style="text-align:center">
<h2>404</h2>
<p>What kind of idiots do you have working here?</p>
<p><a href="/">Hurry up and skip out on the room service bill!</a></p>
</div>
<script>
const track404 = () => {
const referrer = document.referrer || "Unknown referrer";
const userAgent = navigator.userAgent;
const requestedURL = window.location.pathname;
if (window.umami)
umami.track("404 Error", { referrer, user_agent: userAgent, requested_url: requestedURL });
};
document.addEventListener("DOMContentLoaded", track404);
</script>

View file

@ -0,0 +1,42 @@
---
title: 429
description: Hey! Knock that off.
permalink: /429/index.html
eleventyExcludeFromCollections: true
excludeFromSitemap: true
---
<div class="hero">
<img
srcset="
{{ globals.cdn_url }}/45f831f8-1283-45b4-9778-fb1827553ff2.jpg?class=bannersm&type=webp 256w,
{{ globals.cdn_url }}/45f831f8-1283-45b4-9778-fb1827553ff2.jpg?class=bannermd&type=webp 512w,
{{ globals.cdn_url }}/45f831f8-1283-45b4-9778-fb1827553ff2.jpg?class=bannerbase&type=webp 1024w
"
sizes="(max-width: 450px) 256px,
(max-width: 850px) 512px,
1024px"
src="{{ globals.cdn_url }}/45f831f8-1283-45b4-9778-fb1827553ff2.jpg?class=bannersm&type=webp"
alt="An image Elmo standing next to Jack Black who is smiling and holding a stop sign."
class="image-banner"
loading="lazy"
decoding="async"
width="720"
height="480"
/>
</div>
<div style="text-align:center">
<h2>429</h2>
<p>Hey! Knock that off. Take a break and try again.</p>
</div>
<script>
const track429 = () => {
const referrer = document.referrer || "Unknown referrer";
const userAgent = navigator.userAgent;
if (window.umami)
umami.track("Rate limited", { referrer, user_agent: userAgent });
};
document.addEventListener("DOMContentLoaded", track429);
</script>

View file

@ -0,0 +1,43 @@
---
title: 500
description: Oh wow, that's really broken.
permalink: /500/index.html
eleventyExcludeFromCollections: true
excludeFromSitemap: true
---
<div class="hero">
<img
srcset="
{{ globals.cdn_url }}/39f8b486-4321-4ce1-8fd7-08e09f2cec09.jpg?class=bannersm&type=webp 256w,
{{ globals.cdn_url }}/39f8b486-4321-4ce1-8fd7-08e09f2cec09.jpg?class=bannermd&type=webp 512w,
{{ globals.cdn_url }}/39f8b486-4321-4ce1-8fd7-08e09f2cec09.jpg?class=bannerbase&type=webp 1024w
"
sizes="(max-width: 450px) 256px,
(max-width: 850px) 512px,
1024px"
src="{{ globals.cdn_url }}/39f8b486-4321-4ce1-8fd7-08e09f2cec09.jpg?class=bannersm&type=webp"
alt="An image of from IT Crowd where Maurice types at a computer with a fire in t he foreground."
class="image-banner"
loading="lazy"
decoding="async"
width="720"
height="480"
/>
</div>
<div style="text-align:center">
<h2>500</h2>
<p>Well, something's on fire. <a href="/">I'd head for the exit.</a></p>
</div>
<script>
const track500 = () => {
const referrer = document.referrer || "Unknown referrer";
const userAgent = navigator.userAgent;
const requestedURL = window.location.pathname;
if (window.umami)
umami.track("500 Error", { referrer, user_agent: userAgent, requested_url: requestedURL });
};
document.addEventListener("DOMContentLoaded", track500);
</script>

View file

@ -0,0 +1,260 @@
---
title: Search
permalink: /search/index.html
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).
</p>
<noscript>
<p>
<mark
>If you're seeing this it means that you've (quite likely) disabled
JavaScript (that's a totally valid choice!).</mark>
You can search for anything on my site using the form below, but your query
will be routed through
<a href="https://duckduckgo.com">DuckDuckGo</a>.
</p>
<p>
<mark>Type something in and hit enter.</mark>
</p>
</noscript>
<form class="search__form" action="https://duckduckgo.com" method="get">
<input
class="search__form--input"
placeholder="Search"
type="search"
name="q"
autocomplete="off"
autofocus
onkeydown="return event.key !== 'Enter'"
/>
<details>
<summary>Filter by type</summary>
<fieldset class="search__form--type">
<label>
<input type="checkbox" name="type" value="post" checked />
post
</label>
<label>
<input type="checkbox" name="type" value="artist" checked />
artist
</label>
<label>
<input type="checkbox" name="type" value="genre" checked />
genre
</label>
<label>
<input type="checkbox" name="type" value="book" checked />
book
</label>
<label>
<input type="checkbox" name="type" value="movie" checked />
movie
</label>
<label>
<input type="checkbox" name="type" value="show" checked />
show
</label>
</fieldset>
</details>
<input
class="search__form--fallback"
type="hidden"
name="sites"
value="coryd.dev"
/>
</form>
<ul class="search__results client-side"></ul>
<button class="search__load-more client-side" style="display: none">
Load More
</button>
<script src="/assets/scripts/components/minisearch.js"></script>
<script>
window.addEventListener("load", () => {
(() => {
if (typeof MiniSearch === "undefined") return;
const miniSearch = new MiniSearch({
fields: ["title", "description", "tags", "type"],
idField: "id",
storeFields: [
"id",
"title",
"url",
"description",
"type",
"tags",
"total_plays",
],
searchOptions: {
fields: ["title", "tags"],
prefix: true,
fuzzy: 0.1,
boost: { title: 5, tags: 2, description: 1 },
},
});
const $form = document.querySelector(".search__form");
const $fallback = document.querySelector(".search__form--fallback");
const $input = document.querySelector(".search__form--input");
const $results = document.querySelector(".search__results");
const $loadMoreButton = document.querySelector(".search__load-more");
const $typeCheckboxes = document.querySelectorAll(
'.search__form--type input[type="checkbox"]',
);
$form.removeAttribute("action");
$form.removeAttribute("method");
if ($fallback) $fallback.remove();
const PAGE_SIZE = 10;
let currentPage = 1;
let currentResults = [];
let total = 0;
let debounceTimeout;
const parseMarkdown = (markdown) =>
markdown
? markdown
.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.*?)\*/g, "<em>$1</em>")
.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2">$1</a>')
.replace(/\n/g, "<br>")
.replace(/[#*_~`]/g, "")
: "";
const truncateDescription = (markdown, maxLength = 225) => {
const plainText =
new DOMParser().parseFromString(parseMarkdown(markdown), "text/html")
.body.textContent || "";
return plainText.length > maxLength
? `${plainText.substring(0, maxLength)}...`
: plainText;
};
const renderSearchResults = (results) => {
const resultHTML = results
.map(
({ title, url, description, type, total_plays }) => `
<li class="search__results--result">
<h3>
<a href="${url}">${title}</a>
${
type === "artist" && total_plays > 0
? ` <mark>${total_plays} plays</mark>`
: ""
}
</h3>
<p>${truncateDescription(description)}</p>
</li>
`,
)
.join("");
$results.innerHTML =
resultHTML ||
'<li class="search__results--no-results">No results found.</li>';
$results.style.display = "block";
};
const loadSearchIndex = async (query, types, page) => {
try {
const typeQuery = types.join(",");
const response = await fetch(
`https://www.coryd.dev/api/search.php?q=${query}&type=${typeQuery}&page=${page}&pageSize=${PAGE_SIZE}`,
);
const data = await response.json();
total = data.total || 0;
const formattedResults = (data.results || []).map((item) => ({
...item,
id: item.result_id,
}));
miniSearch.removeAll();
miniSearch.addAll(formattedResults);
return formattedResults;
} catch (error) {
console.error("Error fetching search data:", error);
return [];
}
};
const getSelectedTypes = () =>
Array.from($typeCheckboxes)
.filter((cb) => cb.checked)
.map((cb) => cb.value);
const updateSearchResults = (results) => {
if (currentPage === 1) {
renderSearchResults(results);
} else {
appendSearchResults(results);
}
$loadMoreButton.style.display =
currentPage * PAGE_SIZE < total ? "block" : "none";
};
const appendSearchResults = (results) => {
const newResultsHTML = results
.map(
({ title, url, description, type, total_plays }) => `
<li class="search__results--result">
<h3>
<a href="${url}">${title}</a>
${
type === "artist" && total_plays > 0
? ` <mark>${total_plays} plays</mark>`
: ""
}
</h3>
<p>${truncateDescription(description)}</p>
</li>
`,
)
.join("");
$results.insertAdjacentHTML("beforeend", newResultsHTML);
};
const handleSearch = async () => {
const query = $input.value.trim();
if (!query) {
renderSearchResults([]);
$loadMoreButton.style.display = "none";
return;
}
const results = await loadSearchIndex(query, getSelectedTypes(), 1);
currentResults = results;
currentPage = 1;
updateSearchResults(results);
};
$input.addEventListener("input", () => {
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(handleSearch, 150);
});
$typeCheckboxes.forEach((cb) =>
cb.addEventListener("change", handleSearch),
);
$loadMoreButton.addEventListener("click", async () => {
currentPage++;
const nextResults = await loadSearchIndex(
$input.value.trim(),
getSelectedTypes(),
currentPage,
);
currentResults = [...currentResults, ...nextResults];
updateSearchResults(nextResults);
});
})();
});
</script>

View file

@ -0,0 +1,42 @@
---
title: Stats
permalink: /stats/index.html
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>
<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>
<p class="tv">I've watched <mark>{{ stats.episode_count }} {{ stats.episode_count | pluralize: "episode" }}</mark> of <mark>{{ stats.show_count }} {{ stats.show_count | pluralize: "show" }}</mark>{% if stats.episode_count != "1" %} (some more than once){% endif %}.</p>
<p class="movies">I've watched <mark>{{ stats.movie_count }} {{ stats.movie_count | pluralize: "movie" }}</mark>{% if stats.movie_count != "1" %} (some more than once){% endif %}.</p>
<p class="books">I've read <mark>{{ stats.book_count }} {{ stats.book_count | pluralize: "book" }}</mark>. I've read <mark>{{ books.daysRead }} {{ books.daysRead | pluralize: "day" }}</mark> in a row and counting.</p>
<p class="article">I've written <mark>{{ stats.post_count }} {{ stats.post_count | pluralize: "post" }}</mark>.</p>
<p class="link">I've shared <mark>{{ stats.link_count }} {{ stats.link_count | pluralize: "link" }}</mark>.</p>
<hr />
{% for year_stats in stats.yearly_breakdown %}
<h3>{{ year_stats.year }}</h3>
<ul>
{% if year_stats.listen_count %}
<li class="music">Listened to <mark>{{ year_stats.listen_count }} {{ year_stats.listen_count | pluralize: "track" }}</mark> by <mark>{{ year_stats.artist_count }} {{ year_stats.artist_count | pluralize: "artist" }}</mark> across <mark>{{ year_stats.genre_count }} {{ year_stats.genre_count | pluralize: "genre" }}</mark>.</li>
{% endif %}
{% if year_stats.concert_count %}
<li class="concerts">Attended <mark>{{ year_stats.concert_count }} {{ year_stats.concert_count | pluralize: "concert" }}</mark> at <mark>{{ year_stats.venue_count }} {{ year_stats.venue_count | pluralize: "venue" }}</mark>.</li>
{% endif %}
{% if year_stats.episode_count %}
<li class="tv">Watched <mark>{{ year_stats.episode_count }} {{ year_stats.episode_count | pluralize: "episode" }}</mark> of <mark>{{ year_stats.show_count }} {{ year_stats.show_count | pluralize: "show" }}</mark>{% if year_stats.episode_count != "1" %} (some more than once){% endif %}.</li>
{% endif %}
{% if year_stats.movie_count %}<li class="movies">Watched <mark>{{ year_stats.movie_count }} {{ year_stats.movie_count | pluralize: "movie" }}</mark>{% if year_stats.movie_count != "1" %} (some more than once){% endif %}.</li>
{% endif %}
{% if year_stats.book_count %}
<li class="books">Read <mark>{{ year_stats.book_count }} {{ year_stats.book_count | pluralize: "book" }}</mark>.</li>
{% endif %}
{% if year_stats.post_count %}
<li class="article">Wrote <mark>{{ year_stats.post_count }} {{ year_stats.post_count | pluralize: "post" }}</mark>.</li>
{% endif %}
{% if year_stats.link_count %}
<li class="link">Shared <mark>{{ year_stats.link_count }} {{ year_stats.link_count | pluralize: "link" }}</mark>.</li>
{% endif %}
</ul>
{% endfor %}