feat: initial commit
This commit is contained in:
commit
e214116e40
253 changed files with 17406 additions and 0 deletions
50
src/includes/blocks/associated-media.liquid
Normal file
50
src/includes/blocks/associated-media.liquid
Normal file
|
@ -0,0 +1,50 @@
|
|||
{% assign media = artists | concat:books | concat:genres | concat:movies | concat:posts | concat:shows %}
|
||||
{% if media.size > 0 %}
|
||||
<div class="associated-media">
|
||||
{% assign sections =
|
||||
"artists:headphones:music:Related artist(s)," | append:
|
||||
"books:books:books:Related book(s)," | append:
|
||||
"genres:headphones:music:Related genre(s)," | append:
|
||||
"movies:movie:movies:Related movie(s)," | append:
|
||||
"posts:article:article:Related post(s)," | append:
|
||||
"shows:device-tv-old:tv:Related show(s)"
|
||||
| split:"," %}
|
||||
{% for section in sections %}
|
||||
{% assign parts = section | split:":" %}
|
||||
{% assign key = parts[0] %}
|
||||
{% assign icon = parts[1] %}
|
||||
{% assign css_class = parts[2] %}
|
||||
{% assign label = parts[3] %}
|
||||
{% case key %}
|
||||
{% when "artists" %} {% assign items = artists %}
|
||||
{% when "books" %} {% assign items = books %}
|
||||
{% when "genres" %} {% assign items = genres %}
|
||||
{% when "movies" %} {% assign items = movies %}
|
||||
{% when "posts" %} {% assign items = posts %}
|
||||
{% when "shows" %} {% assign items = shows %}
|
||||
{% endcase %}
|
||||
{% if items and items.size > 0 %}
|
||||
<p id="{{ key }}" class="{{ css_class }}">
|
||||
{% tablericon icon %}
|
||||
{{ label }}
|
||||
</p>
|
||||
<ul>
|
||||
{% for item in items %}
|
||||
<li class="{{ css_class }}">
|
||||
<a href="{{ item.url }}">{{ item.title | default:item.name }}</a>
|
||||
{% if key == "artists" and item.total_plays > 0 %}
|
||||
({{ item.total_plays }} {{ item.total_plays | pluralize:"play" }})
|
||||
{% elsif key == "books" %}
|
||||
by {{ item.author }}
|
||||
{% elsif key == "movies" or key == "shows" %}
|
||||
({{ item.year }})
|
||||
{% elsif key == "posts" %}
|
||||
({{ item.date | date:"%B %e, %Y" }})
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
3
src/includes/blocks/banners/calendar.liquid
Normal file
3
src/includes/blocks/banners/calendar.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="banner calendar">
|
||||
<p>{% tablericon "calendar" %} <a href="{{ url }}">{{ text }}</a>.</p>
|
||||
</div>
|
5
src/includes/blocks/banners/coffee.liquid
Normal file
5
src/includes/blocks/banners/coffee.liquid
Normal file
|
@ -0,0 +1,5 @@
|
|||
<div class="banner coffee">
|
||||
<p>
|
||||
{% tablericon "coffee" %} <a class="coffee" href="https://buymeacoffee.com/cory">If you found this post helpful, you can buy me a coffee.</a>
|
||||
</p>
|
||||
</div>
|
3
src/includes/blocks/banners/error.liquid
Normal file
3
src/includes/blocks/banners/error.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="banner error">
|
||||
<p>{% tablericon "alert-circle" %} {{ text }}</p>
|
||||
</div>
|
3
src/includes/blocks/banners/github.liquid
Normal file
3
src/includes/blocks/banners/github.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="banner github">
|
||||
<p>{% tablericon "brand-github" %} Take a look at <a href="{{ url }}">the GitHub repository for this project</a>. (Give it a star if you feel like it.)</p>
|
||||
</div>
|
8
src/includes/blocks/banners/mastodon.liquid
Normal file
8
src/includes/blocks/banners/mastodon.liquid
Normal file
|
@ -0,0 +1,8 @@
|
|||
{%- if url -%}
|
||||
<div class="banner mastodon">
|
||||
<p>
|
||||
{% tablericon "brand-mastodon" %}
|
||||
<a class="mastodon" href="{{ url }}"> Discuss this post on Mastodon. </a>
|
||||
</p>
|
||||
</div>
|
||||
{%- endif -%}
|
3
src/includes/blocks/banners/npm.liquid
Normal file
3
src/includes/blocks/banners/npm.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="banner npm">
|
||||
<p>{% tablericon "brand-npm" %} <a href="{{ url }}">You can take a look at this package on NPM</a> or install it by running <code>{{ command }}</code>.</p>
|
||||
</div>
|
5
src/includes/blocks/banners/old-post.liquid
Normal file
5
src/includes/blocks/banners/old-post.liquid
Normal file
|
@ -0,0 +1,5 @@
|
|||
{%- if isOldPost -%}
|
||||
<div class="banner old-post">
|
||||
<p>{% tablericon "clock-x" %} This post is over 3 years old. I've probably changed my mind since it was written and it <em>could</em> be out of date.</p>
|
||||
</div>
|
||||
{%- endif -%}
|
3
src/includes/blocks/banners/rss.liquid
Normal file
3
src/includes/blocks/banners/rss.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="banner rss">
|
||||
<p>{% tablericon "rss" %} <a href="{{ url }}">{{ text }}</a>.</p>
|
||||
</div>
|
3
src/includes/blocks/banners/warning.liquid
Normal file
3
src/includes/blocks/banners/warning.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class="banner warning">
|
||||
<p>{% tablericon "alert-triangle" %} {{ text }}</p>
|
||||
</div>
|
17
src/includes/blocks/hero.liquid
Normal file
17
src/includes/blocks/hero.liquid
Normal file
|
@ -0,0 +1,17 @@
|
|||
<img
|
||||
srcset="
|
||||
{{ globals.cdn_url }}{{ image }}?class=bannersm&type=webp 256w,
|
||||
{{ globals.cdn_url }}{{ image }}?class=bannermd&type=webp 512w,
|
||||
{{ globals.cdn_url }}{{ image }}?class=bannerbase&type=webp 1024w
|
||||
"
|
||||
sizes="(max-width: 450px) 256px,
|
||||
(max-width: 850px) 512px
|
||||
1024px"
|
||||
src="{{ globals.cdn_url }}{{ image }}?class=bannersm&type=webp"
|
||||
alt="{{ alt | replaceQuotes }}"
|
||||
class="image-banner"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
width="720"
|
||||
height="480"
|
||||
/>
|
32
src/includes/blocks/index.liquid
Normal file
32
src/includes/blocks/index.liquid
Normal file
|
@ -0,0 +1,32 @@
|
|||
{%- for block in blocks -%}
|
||||
{%- case block.type -%}
|
||||
{%- when "youtube_player" -%}
|
||||
{% render "blocks/youtube-player.liquid",
|
||||
url:block.url
|
||||
%}
|
||||
{%- when "github_banner" -%}
|
||||
{% render "blocks/banners/github.liquid",
|
||||
url:block.url
|
||||
%}
|
||||
{%- when "npm_banner" -%}
|
||||
{% render "blocks/banners/npm.liquid",
|
||||
url:block.url,
|
||||
command:block.command
|
||||
%}
|
||||
{%- when "rss_banner" -%}
|
||||
{% render "blocks/banners/rss.liquid",
|
||||
url:block.url,
|
||||
text:block.text
|
||||
%}
|
||||
{%- when "hero" -%}
|
||||
{% render "blocks/hero.liquid",
|
||||
globals:globals,
|
||||
image:block.image,
|
||||
alt:block.alt
|
||||
%}
|
||||
{%- when "markdown" -%}
|
||||
{{ block.text | markdown }}
|
||||
{%- when "divider" -%}
|
||||
{{ block.markup | markdown }}
|
||||
{%- endcase -%}
|
||||
{%- endfor -%}
|
29
src/includes/blocks/modal.liquid
Normal file
29
src/includes/blocks/modal.liquid
Normal file
|
@ -0,0 +1,29 @@
|
|||
{%- capture labelContent -%}
|
||||
{%- if icon -%}
|
||||
{% tablericon icon %}
|
||||
{%- elsif label -%}
|
||||
{{ label }}
|
||||
{%- endif -%}
|
||||
{%- endcapture -%}
|
||||
{% assign modalId = id | default:"modal-controls" %}
|
||||
<noscript>
|
||||
<input class="modal-input" id="{{ modalId }}" type="checkbox" tabindex="0" />
|
||||
<label class="modal-open" for="{{ modalId }}">{{ labelContent }}</label>
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-body">
|
||||
<label class="modal-close" for="{{ modalId }}">
|
||||
{% tablericon "circle-x" %}
|
||||
</label>
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
<button class="modal-open client-side" data-modal-trigger="{{ modalId }}" data-modal-button>
|
||||
{{ labelContent }}
|
||||
</button>
|
||||
<dialog id="dialog-{{ modalId }}" class="client-side">
|
||||
<button class="modal-close" data-modal-button>
|
||||
{% tablericon "circle-x" %}
|
||||
</button>
|
||||
{{ content }}
|
||||
</dialog>
|
7
src/includes/blocks/now-playing.liquid
Normal file
7
src/includes/blocks/now-playing.liquid
Normal file
|
@ -0,0 +1,7 @@
|
|||
<script type="module" src="/assets/scripts/components/now-playing.js?v={% appVersion %}" defer></script>
|
||||
<p class="{{ section }}">
|
||||
<mark>Now playing</mark>
|
||||
<now-playing>
|
||||
<span class="content">{{ nowPlaying }}</span>
|
||||
</now-playing>
|
||||
</p>
|
2
src/includes/blocks/youtube-player.liquid
Normal file
2
src/includes/blocks/youtube-player.liquid
Normal file
|
@ -0,0 +1,2 @@
|
|||
<script type="module" src="/assets/scripts/components/youtube-video-element.js?v={% appVersion %}" defer></script>
|
||||
<youtube-video controls src="{{ url }}"></youtube-video>
|
80
src/includes/fetchers/artist.php.liquid
Normal file
80
src/includes/fetchers/artist.php.liquid
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
require __DIR__ . "/../../vendor/autoload.php";
|
||||
require __DIR__ . "/../../server/utils/init.php";
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
$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 (strpos($url, "music/artists/") !== 0) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$cacheKey = "artist_" . md5($url);
|
||||
$artist = null;
|
||||
$useRedis = false;
|
||||
|
||||
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)) {
|
||||
$artist = json_decode($redis->get($cacheKey), true);
|
||||
} else {
|
||||
$apiUrl = "$postgrestUrl/optimized_artists?url=eq./" . $url;
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->request("GET", $apiUrl, [
|
||||
"headers" => [
|
||||
"Accept" => "application/json",
|
||||
"Authorization" => "Bearer {$postgrestApiKey}",
|
||||
],
|
||||
]);
|
||||
|
||||
$artistData = json_decode($response->getBody(), true);
|
||||
|
||||
if (!$artistData) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$artist = $artistData[0];
|
||||
|
||||
if ($useRedis) {
|
||||
$redis->setex($cacheKey, 3600, json_encode($artist));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$artist["description"] = parseMarkdown($artist["description"]);
|
||||
$pageTitle = htmlspecialchars(
|
||||
"Artists • " . $artist["name"],
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
);
|
||||
$pageDescription = truncateText(htmlspecialchars(
|
||||
strip_tags($artist["description"]),
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
), 250);
|
||||
$ogImage = htmlspecialchars($artist["image"] . "?class=w800", ENT_QUOTES, "UTF-8");
|
||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||
|
||||
header("Cache-Control: public, max-age=3600");
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
|
||||
?>
|
103
src/includes/fetchers/book.php.liquid
Normal file
103
src/includes/fetchers/book.php.liquid
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
require __DIR__ . "/../vendor/autoload.php";
|
||||
require __DIR__ . "/../server/utils/init.php";
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
$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 (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") {
|
||||
echo file_get_contents(__DIR__ . "/../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($url === "books") {
|
||||
readfile("index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!preg_match('/^books\/[\w-]+$/', $url)) {
|
||||
echo file_get_contents(__DIR__ . "/../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$cacheKey = "book_" . md5($url);
|
||||
|
||||
$book = null;
|
||||
$useRedis = false;
|
||||
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)) {
|
||||
$book = json_decode($redis->get($cacheKey), true);
|
||||
} else {
|
||||
$apiUrl = "$postgrestUrl/optimized_books?url=eq./" . $url;
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->request("GET", $apiUrl, [
|
||||
"headers" => [
|
||||
"Accept" => "application/json",
|
||||
"Authorization" => "Bearer {$postgrestApiKey}",
|
||||
],
|
||||
]);
|
||||
|
||||
$bookData = json_decode($response->getBody(), true);
|
||||
|
||||
if (!$bookData) {
|
||||
echo file_get_contents(__DIR__ . "/../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$book = $bookData[0];
|
||||
|
||||
if ($useRedis) {
|
||||
$redis->setex($cacheKey, 3600, json_encode($book));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
echo file_get_contents(__DIR__ . "/../404/index.html");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$book["description"] = parseMarkdown($book["description"]);
|
||||
$pageTitle = htmlspecialchars(
|
||||
"Books • " . $book["title"] . " by " . $book["author"],
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
);
|
||||
$pageDescription = truncateText(htmlspecialchars(
|
||||
strip_tags($book["description"]),
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
), 250);
|
||||
$ogImage = htmlspecialchars($book["image"] . "?class=w800", ENT_QUOTES, "UTF-8");
|
||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||
|
||||
header("Cache-Control: public, max-age=3600");
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
|
||||
?>
|
71
src/includes/fetchers/genre.php.liquid
Normal file
71
src/includes/fetchers/genre.php.liquid
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
require __DIR__ . "/../../vendor/autoload.php";
|
||||
require __DIR__ . "/../../server/utils/init.php";
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
$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 (!preg_match('/^music\/genres\/[\w-]+$/', $url)) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$cacheKey = "genre_" . md5($url);
|
||||
$genre = null;
|
||||
$useRedis = false;
|
||||
|
||||
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)) {
|
||||
$genre = json_decode($redis->get($cacheKey), true);
|
||||
} else {
|
||||
$apiUrl = "$postgrestUrl/optimized_genres?url=eq./" . $url;
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->request("GET", $apiUrl, [
|
||||
"headers" => [
|
||||
"Accept" => "application/json",
|
||||
"Authorization" => "Bearer {$postgrestApiKey}",
|
||||
],
|
||||
]);
|
||||
|
||||
$genreData = json_decode($response->getBody(), true);
|
||||
|
||||
if (!$genreData) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$genre = $genreData[0];
|
||||
|
||||
if ($useRedis) {
|
||||
$redis->setex($cacheKey, 3600, json_encode($genre));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$pageTitle = htmlspecialchars("Genres • " . $genre["name"], ENT_QUOTES, "UTF-8");
|
||||
$pageDescription = truncateText(htmlspecialchars(strip_tags($genre["description"]), ENT_QUOTES, "UTF-8"), 250);
|
||||
$ogImage = htmlspecialchars($genre["artists"][0]["image"] . "?class=w800", ENT_QUOTES, "UTF-8");
|
||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||
|
||||
header("Cache-Control: public, max-age=3600");
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
|
||||
?>
|
80
src/includes/fetchers/movie.php.liquid
Normal file
80
src/includes/fetchers/movie.php.liquid
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
require __DIR__ . "/../../vendor/autoload.php";
|
||||
require __DIR__ . "/../../server/utils/init.php";
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
$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 (!preg_match('/^watching\/movies\/[\w-]+$/', $url)) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$cacheKey = "movie_" . md5($url);
|
||||
$movie = null;
|
||||
$useRedis = false;
|
||||
|
||||
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)) {
|
||||
$movie = json_decode($redis->get($cacheKey), true);
|
||||
} else {
|
||||
$apiUrl = "$postgrestUrl/optimized_movies?url=eq./" . $url;
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->request("GET", $apiUrl, [
|
||||
"headers" => [
|
||||
"Accept" => "application/json",
|
||||
"Authorization" => "Bearer {$postgrestApiKey}",
|
||||
],
|
||||
]);
|
||||
|
||||
$movieData = json_decode($response->getBody(), true);
|
||||
|
||||
if (!$movieData) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$movie = $movieData[0];
|
||||
|
||||
if ($useRedis) {
|
||||
$redis->setex($cacheKey, 3600, json_encode($movie));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$movie["description"] = parseMarkdown($movie["description"]);
|
||||
$pageTitle = htmlspecialchars(
|
||||
"Movies • " . $movie["title"],
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
);
|
||||
$pageDescription = truncateText(htmlspecialchars(
|
||||
strip_tags($movie["description"]),
|
||||
ENT_QUOTES,
|
||||
"UTF-8"
|
||||
), 250);
|
||||
$ogImage = htmlspecialchars($movie["backdrop"] . "?class=w800", ENT_QUOTES, "UTF-8");
|
||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||
|
||||
header("Cache-Control: public, max-age=3600");
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
|
||||
?>
|
71
src/includes/fetchers/show.php.liquid
Normal file
71
src/includes/fetchers/show.php.liquid
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
require __DIR__ . "/../../vendor/autoload.php";
|
||||
require __DIR__ . "/../../server/utils/init.php";
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
$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 (!preg_match('/^watching\/shows\/[\w-]+$/', $url)) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$cacheKey = "show_" . md5($url);
|
||||
$show = null;
|
||||
$useRedis = false;
|
||||
|
||||
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)) {
|
||||
$show = json_decode($redis->get($cacheKey), true);
|
||||
} else {
|
||||
$apiUrl = "$postgrestUrl/optimized_shows?url=eq./" . $url;
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->request("GET", $apiUrl, [
|
||||
"headers" => [
|
||||
"Accept" => "application/json",
|
||||
"Authorization" => "Bearer {$postgrestApiKey}",
|
||||
],
|
||||
]);
|
||||
|
||||
$showData = json_decode($response->getBody(), true);
|
||||
|
||||
if (!$showData) {
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
|
||||
$show = $showData[0];
|
||||
|
||||
if ($useRedis) {
|
||||
$redis->setex($cacheKey, 3600, json_encode($show));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
echo file_get_contents(__DIR__ . "/../../404/index.html");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$pageTitle = htmlspecialchars("Show • " . $show["title"], ENT_QUOTES, "UTF-8");
|
||||
$pageDescription = truncateText(htmlspecialchars(strip_tags($show["description"]), ENT_QUOTES, "UTF-8"), 250);
|
||||
$ogImage = htmlspecialchars($show["image"] . "?class=w800", ENT_QUOTES, "UTF-8");
|
||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||
|
||||
header("Cache-Control: public, max-age=3600");
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
|
||||
?>
|
8
src/includes/home/intro.liquid
Normal file
8
src/includes/home/intro.liquid
Normal file
|
@ -0,0 +1,8 @@
|
|||
<article class="intro">
|
||||
{{ intro }}
|
||||
{% render "blocks/now-playing.liquid",
|
||||
nowPlaying:nowPlaying
|
||||
section:"music"
|
||||
%}
|
||||
<hr />
|
||||
</article>
|
60
src/includes/home/recent-activity.liquid
Normal file
60
src/includes/home/recent-activity.liquid
Normal file
|
@ -0,0 +1,60 @@
|
|||
<article>
|
||||
<h2>
|
||||
{% tablericon "activity" %}
|
||||
Recent activity
|
||||
</h2>
|
||||
<p>
|
||||
<a href="/posts" class="article">Posts</a> •
|
||||
<a href="/links" class="link">Links</a> •
|
||||
<a href="/watching" class="movies">Watching</a> •
|
||||
<a href="/books" class="books">Books</a>
|
||||
</p>
|
||||
{%- for item in items -%}
|
||||
<article class="{{ item.type }}">
|
||||
<aside>
|
||||
<time datetime="{{ item.content_date }}">
|
||||
{{ item.content_date | date:"%B %e, %Y" }}
|
||||
</time>
|
||||
• {{ item.label }}
|
||||
{%- if item.notes -%}
|
||||
{% assign notes = item.notes | prepend: "### Notes\n" | markdown %}
|
||||
• {% render "blocks/modal.liquid",
|
||||
label:"Notes",
|
||||
content:notes,
|
||||
id:item.content_date
|
||||
%}
|
||||
{%- endif -%}
|
||||
</aside>
|
||||
<h3>
|
||||
{%- if item.type == "concerts" -%}
|
||||
{%- capture artistName -%}
|
||||
{%- if item.artist_url -%}
|
||||
<a href="{{ item.artist_url }}">{{ item.title | split: ' at ' | first }}</a>
|
||||
{%- else -%}
|
||||
{{ item.title | split: ' at ' | first }}
|
||||
{%- endif -%}
|
||||
{%- endcapture -%}
|
||||
{%- capture venue -%}
|
||||
{%- if item.venue_lat and item.venue_lon -%}
|
||||
<a href="https://www.openstreetmap.org/?mlat={{ item.venue_lat }}&mlon={{ item.venue_lon }}#map=18/{{ item.venue_lat }}/{{ item.venue_lon }}">{{ item.venue_name }}</a>
|
||||
{%- else -%}
|
||||
{{ item.venue_name }}
|
||||
{%- endif -%}
|
||||
{%- endcapture -%}
|
||||
{{ artistName }}
|
||||
{% if venue %} at {{ venue }}{% endif %}
|
||||
{%- else -%}
|
||||
<a href="{{ item.url | prepend: globals.url }}">{{ item.title }}</a>
|
||||
{%- if item.type == "link" and item.author -%}
|
||||
<span> via </span>
|
||||
{%- if item.author.url -%}
|
||||
<a href="{{ item.author.url }}">{{ item.author.name }}</a>
|
||||
{%- else -%}
|
||||
{{ item.author.name }}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
</h3>
|
||||
</article>
|
||||
{%- endfor -%}
|
||||
</article>
|
19
src/includes/home/recent-media.liquid
Normal file
19
src/includes/home/recent-media.liquid
Normal file
|
@ -0,0 +1,19 @@
|
|||
<article>
|
||||
{% render "media/grid.liquid",
|
||||
globals:globals,
|
||||
data:media.recentMusic,
|
||||
count:8,
|
||||
loading:"eager"
|
||||
%}
|
||||
{% render "media/grid.liquid",
|
||||
globals:globals,
|
||||
data:media.recentWatchedRead,
|
||||
shape:"vertical",
|
||||
count:6
|
||||
loading:"eager"
|
||||
%}
|
||||
{% render "blocks/banners/rss.liquid",
|
||||
url:"/feeds",
|
||||
text:"Subscribe to my movies, books, links or activity feed(s)"
|
||||
%}
|
||||
</article>
|
19
src/includes/layout/footer.liquid
Normal file
19
src/includes/layout/footer.liquid
Normal file
|
@ -0,0 +1,19 @@
|
|||
{%- assign updateTime = "" -%}
|
||||
{%- if updated == "now" -%}
|
||||
{%- assign updateTime = "now" | date:"%B %-d, %l:%M %P", "America/Los_Angeles" -%}
|
||||
{%- elsif pageUpdated -%}
|
||||
{%- assign updateTime = page.updated | date:"%B %-d, %l:%M %P", "America/Los_Angeles" -%}
|
||||
{%- endif -%}
|
||||
<footer{% unless updateTime %} style="margin-top:var(--spacing-3xl)"{% endunless %}>
|
||||
{%- if updateTime -%}
|
||||
<p class="updated"><em>This page was last updated on {{ updateTime | strip }}.</em></p>
|
||||
{%- endif -%}
|
||||
{% render "nav/social.liquid",
|
||||
page:page,
|
||||
links:nav.footer_icons
|
||||
%}
|
||||
{% render "nav/secondary.liquid",
|
||||
page:page,
|
||||
links:nav.footer_text
|
||||
%}
|
||||
</footer>
|
13
src/includes/layout/header.liquid
Normal file
13
src/includes/layout/header.liquid
Normal file
|
@ -0,0 +1,13 @@
|
|||
<section class="main-title">
|
||||
<h1>
|
||||
{%- if page.url == "/" -%}
|
||||
{{ globals.site_name }}
|
||||
{%- else -%}
|
||||
<a href="/" tabindex="0">{{ globals.site_name }}</a>
|
||||
{%- endif -%}
|
||||
</h1>
|
||||
{% render "nav/primary.liquid",
|
||||
page:page,
|
||||
nav:nav
|
||||
%}
|
||||
</section>
|
47
src/includes/media/grid.liquid
Normal file
47
src/includes/media/grid.liquid
Normal file
|
@ -0,0 +1,47 @@
|
|||
<div class="media-grid {{ shape | default: square }}">
|
||||
{%- assign loadingStrategy = loading | default:"lazy" -%}
|
||||
{%- for item in data limit:count -%}
|
||||
{%- assign alt = item.grid.alt | replaceQuotes -%}
|
||||
{%- assign imageUrl = item.grid.image -%}
|
||||
<a href="{{ item.grid.url }}" title="{{ alt }}">
|
||||
<div class="media-grid-item">
|
||||
{%- if item.grid.title or item.grid.subtext -%}
|
||||
<div class="meta-text {{ item.type }}">
|
||||
{% if item.grid.title %}
|
||||
<div class="header">{{ item.grid.title }}</div>
|
||||
{% endif %}
|
||||
{% if item.grid.subtext %}
|
||||
<div class="subheader">{{ item.grid.subtext }}</div>
|
||||
{% endif %}
|
||||
</mark>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
{%- assign imageClass = "square" -%}
|
||||
{%- assign width = 150 -%}
|
||||
{%- assign height = 150 -%}
|
||||
{%- case shape -%}
|
||||
{%- when "vertical" -%}
|
||||
{%- assign imageClass = "vertical" -%}
|
||||
{%- assign width = 120 -%}
|
||||
{%- assign height = 184 -%}
|
||||
{%- endcase -%}
|
||||
<img
|
||||
srcset="
|
||||
{{ globals.cdn_url }}{{ imageUrl }}?class={{ imageClass }}sm&type=webp {{ width }}w,
|
||||
{{ globals.cdn_url }}{{ imageUrl }}?class={{ imageClass }}md&type=webp {{ width | times:2 }}w
|
||||
"
|
||||
sizes="(max-width: 450px) {{ width }}px, {{ width | times:2 }}px"
|
||||
src="{{ globals.cdn_url }}{{ imageUrl }}?class={{ imageClass }}sm&type=webp"
|
||||
alt="{{ alt }}"
|
||||
loading="{{ loadingStrategy }}"
|
||||
decoding="async"
|
||||
width="{{ width }}"
|
||||
height="{{ height }}"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
{% render "nav/paginator.liquid",
|
||||
pagination:pagination
|
||||
%}
|
13
src/includes/media/music/charts/item.liquid
Normal file
13
src/includes/media/music/charts/item.liquid
Normal file
|
@ -0,0 +1,13 @@
|
|||
<div class="chart-item">
|
||||
<div class="chart-item-info">
|
||||
<a class="title" href="{{ item.chart.url }}">{{ item.chart.title }}</a>
|
||||
{%- assign playsLabel = item.chart.plays | pluralize:"play" -%}
|
||||
<span class="subheader">{{ item.chart.artist }}</span>
|
||||
<span class="subheader">{{ item.chart.plays }} {{ playsLabel }}</span>
|
||||
</div>
|
||||
<div class="chart-item-progress">
|
||||
{% render "media/progress-bar.liquid",
|
||||
percentage:item.chart.percentage
|
||||
%}
|
||||
</div>
|
||||
</div>
|
24
src/includes/media/music/charts/rank.liquid
Normal file
24
src/includes/media/music/charts/rank.liquid
Normal file
|
@ -0,0 +1,24 @@
|
|||
<div class="music-chart">
|
||||
<ol type="1">
|
||||
{%- if count -%}
|
||||
{%- for item in data limit:count -%}
|
||||
<li value="{{ item.chart.rank }}">
|
||||
{% render "media/music/charts/item.liquid",
|
||||
item:item
|
||||
%}
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
{%- else -%}
|
||||
{%- for item in pagination.items -%}
|
||||
<li value="{{ item.chart.rank }}">
|
||||
{% render "media/music/charts/item.liquid",
|
||||
item:item
|
||||
%}
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
</ol>
|
||||
</div>
|
||||
{% render "nav/paginator.liquid",
|
||||
pagination:pagination
|
||||
%}
|
30
src/includes/media/music/charts/recent.liquid
Normal file
30
src/includes/media/music/charts/recent.liquid
Normal file
|
@ -0,0 +1,30 @@
|
|||
<div class="music-chart">
|
||||
{%- for item in data limit:10 -%}
|
||||
<div class="chart-item">
|
||||
<div class="meta">
|
||||
<a href="{{ item.chart.url }}">
|
||||
<img
|
||||
srcset="
|
||||
{{ globals.cdn_url }}{{ item.chart.image }}?class=w50&type=webp 50w,
|
||||
{{ globals.cdn_url }}{{ item.chart.image }}?class=w100&type=webp 100w
|
||||
"
|
||||
sizes="(max-width: 450px) 50px, 100px"
|
||||
src="{{ globals.cdn_url }}{{ item.chart.image }}?class=w50&type=webp"
|
||||
alt="{{ item.chart.alt | replaceQuotes }}"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
width="64"
|
||||
height="64"
|
||||
/>
|
||||
</a>
|
||||
<div class="meta-text">
|
||||
<a class="title" href="{{ item.chart.url }}">{{ item.chart.title }}</a>
|
||||
<span class="subheader">{{ item.chart.subtext }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<time datetime="item.chart.played_at">
|
||||
{{ item.chart.played_at | date:"%B %-d, %-I:%M%p", "America/Los_Angeles" }}
|
||||
</time>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
21
src/includes/media/music/tables/all-time/albums.liquid
Normal file
21
src/includes/media/music/tables/all-time/albums.liquid
Normal file
|
@ -0,0 +1,21 @@
|
|||
<table class="music-ranking">
|
||||
<tr>
|
||||
<th>Albums (all time)</th>
|
||||
<th>Artist</th>
|
||||
<th>Plays</th>
|
||||
<th>Year</th>
|
||||
</tr>
|
||||
{% for album in topAlbums %}
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<img src="{{ globals.cdn_url }}{{ album.table.image }}?class=w100" alt="{{ album.table.alt }}" width="50">
|
||||
{{ album.table.title }}
|
||||
</div>
|
||||
</td>
|
||||
<td><a href="{{ album.table.url }}">{{ album.table.artist }}</a></td>
|
||||
<td>{{ album.table.plays }}</td>
|
||||
<td>{{ album.table.year }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
19
src/includes/media/music/tables/all-time/artists.liquid
Normal file
19
src/includes/media/music/tables/all-time/artists.liquid
Normal file
|
@ -0,0 +1,19 @@
|
|||
<table class="music-ranking">
|
||||
<tr>
|
||||
<th>Artists (all time)</th>
|
||||
<th>Genre</th>
|
||||
<th>Plays</th>
|
||||
</tr>
|
||||
{% for artist in topArtists %}
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<img src="{{ globals.cdn_url }}{{ artist.table.image }}?class=w100" alt="{{ artist.table.alt }}" width="50">
|
||||
<a href="{{ artist.table.url }}">{{ artist.table.title }}</a>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ artist.table.emoji }} <a href="{{ artist.table.genre_url }}">{{ artist.table.genre }}</a></td>
|
||||
<td>{{ artist.table.plays }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
3
src/includes/media/progress-bar.liquid
Normal file
3
src/includes/media/progress-bar.liquid
Normal file
|
@ -0,0 +1,3 @@
|
|||
{%- if percentage -%}
|
||||
<progress value="{{ percentage }}" max="100">{{ percentage }}%</progress>
|
||||
{%- endif -%}
|
18
src/includes/media/watching/hero.liquid
Normal file
18
src/includes/media/watching/hero.liquid
Normal file
|
@ -0,0 +1,18 @@
|
|||
<a href="{{ movie.url }}">
|
||||
<div class="watching hero">
|
||||
<div class="meta-text highlight-text">
|
||||
<div class="header">{{ movie.title }}</div>
|
||||
<div class="subheader">
|
||||
{%- if movie.rating -%}
|
||||
<span class="rating">{{ movie.rating }} </span>
|
||||
{%- endif -%}
|
||||
({{ movie.year }})
|
||||
</div>
|
||||
</div>
|
||||
{% render "blocks/hero.liquid",
|
||||
globals:globals,
|
||||
image:movie.backdrop,
|
||||
alt:movie.title
|
||||
%}
|
||||
</div>
|
||||
</a>
|
13
src/includes/metadata/base.liquid
Normal file
13
src/includes/metadata/base.liquid
Normal file
|
@ -0,0 +1,13 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="theme-color" content="{{ globals.theme_color }}" />
|
||||
<meta name="fediverse:creator" content="{{ globals.mastodon }}" />
|
||||
<meta name="generator" content="{{ eleventy.generator }}" />
|
||||
<link href="{{ globals.cdn_url }}{{ globals.avatar_transparent }}?class=w50&v={% appVersion %}" rel="icon" sizes="any" />
|
||||
<link href="{{ globals.cdn_url }}{{ globals.avatar_transparent }}?class=w50&v={% appVersion %}&type=svg" rel="icon" type="image/svg+xml" />
|
||||
<link href="{{ globals.cdn_url }}{{ globals.avatar }}?class=w800&v={% appVersion %}" rel="apple-touch-icon" />
|
||||
<link rel="alternate" href="{{ globals.url }}/feeds/posts.xml" title="Posts • {{ globals.site_name }}" />
|
||||
<link rel="alternate" href="{{ globals.url }}/feeds/links.xml" title="Links • {{ globals.site_name }}" type="application/rss+xml" />
|
||||
<link rel="alternate" href="{{ globals.url }}/feeds/movies.xml" title="Movies • {{ globals.site_name }}" type="application/rss+xml" />
|
||||
<link rel="alternate" href="{{ globals.url }}/feeds/books.xml" title="Books • {{ globals.site_name }}" type="application/rss+xml" />
|
||||
<link rel="alternate" href="{{ globals.url }}/feeds/all.xml" title="All activity • {{ globals.site_name }}" type="application/rss+xml" />
|
7
src/includes/metadata/dynamic.php.liquid
Normal file
7
src/includes/metadata/dynamic.php.liquid
Normal file
|
@ -0,0 +1,7 @@
|
|||
<title><?= htmlspecialchars($pageTitle ?? "{{ pageTitle }}", ENT_QUOTES, 'UTF-8') ?> • {{ globals.site_name }}</title>
|
||||
<meta name="description" content="<?= htmlspecialchars($pageDescription ?? '{{ pageDescription | escape }}', ENT_QUOTES, 'UTF-8') ?>" />
|
||||
<meta property="og:title" content="<?= htmlspecialchars($pageTitle ?? '{{ pageTitle }}', ENT_QUOTES, 'UTF-8') ?> • {{ globals.site_name }}" />
|
||||
<meta property="og:description" content="<?= htmlspecialchars($pageDescription ?? '{{ pageDescription | escape }}', ENT_QUOTES, 'UTF-8') ?>" />
|
||||
<meta property="og:image" content="<?= htmlspecialchars("{{ globals.cdn_url }}" . ($ogImage ?? '{{ ogImage }}'), ENT_QUOTES, 'UTF-8') ?>" />
|
||||
<meta property="og:url" content="<?= htmlspecialchars($fullUrl ?? '{{ fullUrl }}', ENT_QUOTES, 'UTF-8') ?>" />
|
||||
<link rel="canonical" href="<?= htmlspecialchars($fullUrl ?? '{{ fullUrl }}', ENT_QUOTES, 'UTF-8') ?>" />
|
94
src/includes/metadata/index.liquid
Normal file
94
src/includes/metadata/index.liquid
Normal file
|
@ -0,0 +1,94 @@
|
|||
{%- assign fullUrl = globals.url | append: page.url -%}
|
||||
{%- capture pageTitle -%}
|
||||
{%- if page.title -%}
|
||||
{{ page.title | append: ' • ' | append: globals.site_name }}
|
||||
{%- elsif title -%}
|
||||
{{ title | append: ' • ' | append: globals.site_name }}
|
||||
{%- else -%}
|
||||
{{ globals.site_name }}
|
||||
{%- endif -%}
|
||||
{%- endcapture -%}
|
||||
{%- capture pageDescription -%}
|
||||
{% if page.description %}
|
||||
{{ page.description }}
|
||||
{% elsif description %}
|
||||
{{ description }}
|
||||
{% else %}
|
||||
{{ globals.site_description }}
|
||||
{% endif %}
|
||||
{%- endcapture -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: globals.avatar -%}
|
||||
{%- case schema -%}
|
||||
{%- when 'artist' -%}
|
||||
{% render "fetchers/artist.php.liquid" %}
|
||||
{%- when 'genre' -%}
|
||||
{% render "fetchers/genre.php.liquid" %}
|
||||
{%- when 'book' -%}
|
||||
{% render "fetchers/book.php.liquid" %}
|
||||
{%- when 'movie' -%}
|
||||
{% render "fetchers/movie.php.liquid" %}
|
||||
{%- when 'show' -%}
|
||||
{% render "fetchers/show.php.liquid" %}
|
||||
{%- when 'blog' -%}
|
||||
{%- assign pageTitle = post.title -%}
|
||||
{%- assign pageDescription = post.description -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: post.image -%}
|
||||
{%- when 'music-index', 'music-week-artists' -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: music.week.artists[0].grid.image -%}
|
||||
{%- when 'music-week-albums', 'music-week-tracks' -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: music.week.albums[0].grid.image -%}
|
||||
{%- when 'music-month-artists' -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: music.month.artists[0].grid.image -%}
|
||||
{%- when 'music-month-albums' -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: music.month.albums[0].grid.image -%}
|
||||
{%- when 'music-releases' -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: albumReleases.upcoming[0].grid.image -%}
|
||||
{%- when 'books' -%}
|
||||
{%- assign overviewBook = books.all | filterBooksByStatus: 'started' | reverse | first %}
|
||||
{%- assign ogImage = globals.cdn_url | append: overviewBook.image -%}
|
||||
{%- when 'books-year' -%}
|
||||
{%- assign pageTitle = 'Books' | append: ' • ' | append: year.value | append: ' • ' | append: globals.site_name -%}
|
||||
{%- capture pageDescription -%}
|
||||
Here's what I read in {{ year.value }}.
|
||||
{%- endcapture -%}
|
||||
{%- assign bookData = year.data | filterBooksByStatus: 'finished' -%}
|
||||
{%- assign bookYear = bookData | shuffleArray | first -%}
|
||||
{%- assign ogImage = globals.cdn_url | append: bookYear.image -%}
|
||||
{%- when 'favorite-movies' -%}
|
||||
{%- assign favoriteMovie = movies.favorites | shuffleArray | first %}
|
||||
{%- assign ogImage = globals.cdn_url | append: favoriteMovie.backdrop -%}
|
||||
{%- when 'favorite-shows' -%}
|
||||
{%- assign favoriteShow = tv.favorites | shuffleArray | first %}
|
||||
{%- assign ogImage = globals.cdn_url | append: favoriteShow.backdrop -%}
|
||||
{%- when 'watching' -%}
|
||||
{%- assign overviewMovie = movies.recentlyWatched | first %}
|
||||
{%- assign ogImage = globals.cdn_url | append: overviewMovie.backdrop -%}
|
||||
{%- when 'upcoming-shows' -%}
|
||||
{%- assign upcomingShow = upcomingShows.watching | shuffleArray | first %}
|
||||
{%- assign ogImage = globals.cdn_url | append: upcomingShow.backdrop -%}
|
||||
{%- when 'page' -%}
|
||||
{%- assign pageDescription = page.description -%}
|
||||
{% endcase %}
|
||||
{%- if type == 'dynamic' -%}
|
||||
{% render "metadata/dynamic.php.liquid"
|
||||
fullUrl:fullUrl,
|
||||
pageTitle:pageTitle,
|
||||
pageDescription:pageDescription,
|
||||
ogImage:ogImage,
|
||||
globals:globals,
|
||||
%}
|
||||
{%- else -%}
|
||||
{% render "metadata/static.liquid"
|
||||
fullUrl:fullUrl,
|
||||
pageTitle:pageTitle,
|
||||
pageDescription:pageDescription
|
||||
ogImage:ogImage,
|
||||
globals:globals,
|
||||
%}
|
||||
{%- endif -%}
|
||||
{% render "metadata/base.liquid"
|
||||
pageTitle:pageTitle,
|
||||
globals:globals,
|
||||
eleventy:eleventy,
|
||||
appVersion:appVersion,
|
||||
%}
|
9
src/includes/metadata/static.liquid
Normal file
9
src/includes/metadata/static.liquid
Normal file
|
@ -0,0 +1,9 @@
|
|||
{%- assign description = pageDescription | markdown | strip_html | htmlTruncate | escape -%}
|
||||
<title>{{- pageTitle -}}</title>
|
||||
<meta property="og:title" content="{{- pageTitle -}}" />
|
||||
<meta name="description" content="{{- description -}}" />
|
||||
<meta property="og:description" content="{{- description -}}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{ fullUrl }}" />
|
||||
<link rel="canonical" href="{{ fullUrl }}" />
|
||||
<meta property="og:image" content="{{ ogImage }}?class=w800" />
|
30
src/includes/nav/link.liquid
Normal file
30
src/includes/nav/link.liquid
Normal file
|
@ -0,0 +1,30 @@
|
|||
{%- assign categoryUrl = link.permalink | downcase -%}
|
||||
{%- assign isHttp = categoryUrl contains "http" -%}
|
||||
{%- if categoryUrl | isLinkActive:page.url -%}
|
||||
<span
|
||||
class="active {{ link.class }}"
|
||||
aria-current="page"
|
||||
>
|
||||
{%- if link.icon -%}
|
||||
{% tablericon link.icon %}
|
||||
<span>{{ link.title }}</span>
|
||||
{%- else -%}
|
||||
{{ link.title }}
|
||||
{%- endif -%}
|
||||
</span>
|
||||
{%- else -%}
|
||||
<a
|
||||
class="{% if link.icon %}{{ link.icon | downcase }} icon {% endif %}{{ link.class }}"
|
||||
href="{{ categoryUrl }}"
|
||||
{% if isHttp -%} rel="me" {%- endif %}
|
||||
title="{{ link.title }}"
|
||||
aria-label="{{ link.title }}"
|
||||
>
|
||||
{%- if link.icon -%}
|
||||
{% tablericon link.icon %}
|
||||
<span>{{ link.title }}</span>
|
||||
{%- else -%}
|
||||
{{ link.title }}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
{%- endif -%}
|
47
src/includes/nav/paginator.liquid
Normal file
47
src/includes/nav/paginator.liquid
Normal file
|
@ -0,0 +1,47 @@
|
|||
{%- assign pageCount = pagination.pages.size | default:0 -%}
|
||||
{%- assign hidePagination = pageCount <= 1 -%}
|
||||
{%- unless hidePagination -%}
|
||||
<script type="module" src="/assets/scripts/components/select-pagination.js?v={% appVersion %}" defer></script>
|
||||
<nav aria-label="Pagination" class="pagination">
|
||||
{%- assign prevHref = pagination.href.previous -%}
|
||||
{%- assign nextHref = pagination.href.next -%}
|
||||
{% if prevHref %}
|
||||
<a
|
||||
href="{{ prevHref }}"
|
||||
aria-label="Previous page"
|
||||
>
|
||||
{% tablericon "arrow-left" %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span>
|
||||
{% tablericon "arrow-left" %}
|
||||
</span>
|
||||
{% endif %}
|
||||
<select-pagination>
|
||||
<select class="client-side" aria-label="Page selection">
|
||||
{%- for pageEntry in pagination.pages -%}
|
||||
<option value="{{ forloop.index | minus:1 }}">
|
||||
{{ forloop.index }} of {{ pagination.links.size }}
|
||||
</option>
|
||||
{%- endfor -%}
|
||||
</select>
|
||||
<noscript>
|
||||
<p>
|
||||
<span aria-current="page">{{ pagination.pageNumber | plus:1 }}</span> of {{ pagination.links.size }}
|
||||
</p>
|
||||
</noscript>
|
||||
</select-pagination>
|
||||
{% if nextHref %}
|
||||
<a
|
||||
href="{{ nextHref }}"
|
||||
aria-label="Next page"
|
||||
>
|
||||
{% tablericon "arrow-right" %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span>
|
||||
{% tablericon "arrow-right" %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{%- endunless -%}
|
12
src/includes/nav/primary.liquid
Normal file
12
src/includes/nav/primary.liquid
Normal file
|
@ -0,0 +1,12 @@
|
|||
<nav class="primary-navigation">
|
||||
<ul class="nav-list">
|
||||
{%- for link in nav.primary -%}
|
||||
<li>
|
||||
{% render "nav/link.liquid",
|
||||
page:page,
|
||||
link:link
|
||||
%}
|
||||
</li>
|
||||
{%- endfor -%}
|
||||
</ul>
|
||||
</nav>
|
9
src/includes/nav/secondary.liquid
Normal file
9
src/includes/nav/secondary.liquid
Normal file
|
@ -0,0 +1,9 @@
|
|||
<nav aria-label="Secondary site navigation" class="sub-pages">
|
||||
{%- for link in links -%}
|
||||
{% render "nav/link.liquid",
|
||||
page:page,
|
||||
link:link
|
||||
%}
|
||||
{% unless forloop.last %}<span>•</span>{% endunless %}
|
||||
{%- endfor -%}
|
||||
</nav>
|
8
src/includes/nav/social.liquid
Normal file
8
src/includes/nav/social.liquid
Normal file
|
@ -0,0 +1,8 @@
|
|||
<nav aria-label="Social icons" class="social">
|
||||
{%- for link in links -%}
|
||||
{% render "nav/link.liquid",
|
||||
page:page,
|
||||
link:link
|
||||
%}
|
||||
{%- endfor -%}
|
||||
</nav>
|
Loading…
Add table
Add a link
Reference in a new issue