feat(oembed.php): add oembed api and implement in dependent pages
This commit is contained in:
parent
d95df47274
commit
ec03d7ccef
15 changed files with 173 additions and 3 deletions
68
api/oembed.php
Normal file
68
api/oembed.php
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require __DIR__ . "/Classes/BaseHandler.php";
|
||||||
|
|
||||||
|
use App\Classes\BaseHandler;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
|
||||||
|
class OembedHandler extends BaseHandler
|
||||||
|
{
|
||||||
|
public function handleRequest(): void
|
||||||
|
{
|
||||||
|
$requestUrl = $_GET['url'] ?? null;
|
||||||
|
if (!$requestUrl) $this->sendErrorResponse('Missing url parameter', 400);
|
||||||
|
|
||||||
|
$parsed = parse_url($requestUrl);
|
||||||
|
$relativePath = $parsed['path'] ?? null;
|
||||||
|
if (!$relativePath) $this->sendErrorResponse('Invalid url', 400);
|
||||||
|
if ($relativePath !== '/' && str_ends_with($relativePath, '/')) $relativePath = rtrim($relativePath, '/');
|
||||||
|
|
||||||
|
$globals = $this->fetchGlobals();
|
||||||
|
|
||||||
|
$results = $this->fetchFromApi('optimized_oembed', 'url=eq.' . urlencode($relativePath));
|
||||||
|
if (!empty($results)) {
|
||||||
|
$item = $results[0];
|
||||||
|
$this->sendResponse([
|
||||||
|
'version' => '1.0',
|
||||||
|
'type' => 'link',
|
||||||
|
'title' => $item['title'],
|
||||||
|
'author_name' => $globals['author'],
|
||||||
|
'provider_name' => $globals['site_name'],
|
||||||
|
'provider_url' => $globals['url'],
|
||||||
|
'thumbnail_url' => $globals['url'] . $item['image_url'],
|
||||||
|
'html' => '<a href="' . htmlspecialchars($item['url']) . '">' . htmlspecialchars($item['title']) . '</a>',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$segments = explode('/', trim($relativePath, '/'));
|
||||||
|
if (count($segments) === 1 && $segments[0] !== '') {
|
||||||
|
$title = ucwords(str_replace('-', ' ', $segments[0])) . ' • ' . $globals['author'];
|
||||||
|
$this->sendResponse([
|
||||||
|
'version' => '1.0',
|
||||||
|
'type' => 'link',
|
||||||
|
'title' => $title,
|
||||||
|
'author_name' => $globals['author'],
|
||||||
|
'provider_name' => $globals['site_name'],
|
||||||
|
'provider_url' => $globals['url'],
|
||||||
|
'thumbnail_url' => $globals['url'] . $globals['avatar'],
|
||||||
|
'html' => '<a href="' . htmlspecialchars($relativePath) . '">' . htmlspecialchars($title) . '</a>',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendErrorResponse('No match found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fetchGlobals(): array
|
||||||
|
{
|
||||||
|
$globals = $this->fetchFromApi('optimized_globals', 'limit=1');
|
||||||
|
return $globals[0] ?? [
|
||||||
|
'author' => 'Cory Dransfeldt',
|
||||||
|
'site_name' => 'coryd.dev',
|
||||||
|
'url' => 'https://www.coryd.dev',
|
||||||
|
'avatar' => ''
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$handler = new OembedHandler();
|
||||||
|
$handler->handleRequest();
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "coryd.dev",
|
"name": "coryd.dev",
|
||||||
"version": "3.9.0",
|
"version": "4.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "coryd.dev",
|
"name": "coryd.dev",
|
||||||
"version": "3.9.0",
|
"version": "4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"html-minifier-terser": "7.2.0",
|
"html-minifier-terser": "7.2.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "coryd.dev",
|
"name": "coryd.dev",
|
||||||
"version": "3.9.0",
|
"version": "4.0.0",
|
||||||
"description": "The source for my personal site. Built using 11ty (and other tools).",
|
"description": "The source for my personal site. Built using 11ty (and other tools).",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
87
queries/views/feeds/oembed.sql
Normal file
87
queries/views/feeds/oembed.sql
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
CREATE OR REPLACE VIEW optimized_oembed AS
|
||||||
|
WITH oembed_data AS (
|
||||||
|
SELECT
|
||||||
|
'post' AS type,
|
||||||
|
p.url::TEXT AS url,
|
||||||
|
p.title AS title,
|
||||||
|
p.description AS description,
|
||||||
|
CASE
|
||||||
|
WHEN df.filename_disk IS NOT NULL AND df.filename_disk != '' AND df.filename_disk != '/' THEN df.filename_disk
|
||||||
|
ELSE (SELECT g.avatar FROM optimized_globals g LIMIT 1)
|
||||||
|
END AS image_url,
|
||||||
|
p.date AS content_date
|
||||||
|
FROM optimized_posts p
|
||||||
|
LEFT JOIN directus_files df ON p.image = df.filename_disk
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'book' AS type,
|
||||||
|
b.url::TEXT AS url,
|
||||||
|
b.title AS title,
|
||||||
|
b.description AS description,
|
||||||
|
CASE
|
||||||
|
WHEN b.image IS NOT NULL AND b.image != '' THEN b.image
|
||||||
|
ELSE (SELECT g.avatar FROM optimized_globals g LIMIT 1)
|
||||||
|
END AS image_url,
|
||||||
|
b.date_finished AS content_date
|
||||||
|
FROM optimized_books b
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'artist' AS type,
|
||||||
|
ar.url::TEXT AS url,
|
||||||
|
ar.name AS title,
|
||||||
|
ar.description AS description,
|
||||||
|
CASE
|
||||||
|
WHEN ar.image IS NOT NULL AND ar.image != '' THEN ar.image
|
||||||
|
ELSE (SELECT g.avatar FROM optimized_globals g LIMIT 1)
|
||||||
|
END AS image_url,
|
||||||
|
CURRENT_TIMESTAMP AS content_date
|
||||||
|
FROM optimized_artists ar
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'genre' AS type,
|
||||||
|
g.url::TEXT AS url,
|
||||||
|
g.name AS title,
|
||||||
|
g.description AS description,
|
||||||
|
CASE
|
||||||
|
WHEN top_artist.image IS NOT NULL AND top_artist.image != '' THEN top_artist.image
|
||||||
|
ELSE (SELECT g.avatar FROM optimized_globals g LIMIT 1)
|
||||||
|
END AS image_url,
|
||||||
|
CURRENT_TIMESTAMP AS content_date
|
||||||
|
FROM optimized_genres g
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT ar.image
|
||||||
|
FROM optimized_artists ar
|
||||||
|
WHERE (ar.genre->>'id')::bigint = g.id
|
||||||
|
ORDER BY ar.total_plays DESC
|
||||||
|
LIMIT 1
|
||||||
|
) top_artist ON true
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'show' AS type,
|
||||||
|
s.url::TEXT AS url,
|
||||||
|
s.title AS title,
|
||||||
|
s.description AS description,
|
||||||
|
CASE
|
||||||
|
WHEN s.image IS NOT NULL AND s.image != '' THEN s.image
|
||||||
|
ELSE (SELECT g.avatar FROM optimized_globals g LIMIT 1)
|
||||||
|
END AS image_url,
|
||||||
|
s.last_watched_at AS content_date
|
||||||
|
FROM optimized_shows s
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'movie' AS type,
|
||||||
|
m.url::TEXT AS url,
|
||||||
|
m.title AS title,
|
||||||
|
m.description AS description,
|
||||||
|
CASE
|
||||||
|
WHEN m.image IS NOT NULL AND m.image != '' THEN m.image
|
||||||
|
ELSE (SELECT g.avatar FROM optimized_globals g LIMIT 1)
|
||||||
|
END AS image_url,
|
||||||
|
m.last_watched AS content_date
|
||||||
|
FROM optimized_movies m
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
ROW_NUMBER() OVER (ORDER BY url) AS id,
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
oembed_data;
|
|
@ -75,6 +75,7 @@
|
||||||
), 250);
|
), 250);
|
||||||
$ogImage = htmlspecialchars($artist["image"], ENT_QUOTES, "UTF-8");
|
$ogImage = htmlspecialchars($artist["image"], ENT_QUOTES, "UTF-8");
|
||||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||||
|
$oembedUrl = "https://www.coryd.dev/oembed" . $requestUri;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
), 250);
|
), 250);
|
||||||
$ogImage = htmlspecialchars($book["image"], ENT_QUOTES, "UTF-8");
|
$ogImage = htmlspecialchars($book["image"], ENT_QUOTES, "UTF-8");
|
||||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||||
|
$oembedUrl = "https://www.coryd.dev/oembed" . $requestUri;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
$pageDescription = truncateText(htmlspecialchars(strip_tags($genre["description"]), ENT_QUOTES, "UTF-8"), 250);
|
$pageDescription = truncateText(htmlspecialchars(strip_tags($genre["description"]), ENT_QUOTES, "UTF-8"), 250);
|
||||||
$ogImage = htmlspecialchars($genre["artists"][0]["image"], ENT_QUOTES, "UTF-8");
|
$ogImage = htmlspecialchars($genre["artists"][0]["image"], ENT_QUOTES, "UTF-8");
|
||||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||||
|
$oembedUrl = "https://www.coryd.dev/oembed" . $requestUri;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
), 250);
|
), 250);
|
||||||
$ogImage = htmlspecialchars($movie["backdrop"], ENT_QUOTES, "UTF-8");
|
$ogImage = htmlspecialchars($movie["backdrop"], ENT_QUOTES, "UTF-8");
|
||||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||||
|
$oembedUrl = "https://www.coryd.dev/oembed" . $requestUri;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
$pageDescription = truncateText(htmlspecialchars(strip_tags($show["description"]), ENT_QUOTES, "UTF-8"), 250);
|
$pageDescription = truncateText(htmlspecialchars(strip_tags($show["description"]), ENT_QUOTES, "UTF-8"), 250);
|
||||||
$ogImage = htmlspecialchars($show["image"], ENT_QUOTES, "UTF-8");
|
$ogImage = htmlspecialchars($show["image"], ENT_QUOTES, "UTF-8");
|
||||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||||
|
$oembedUrl = "https://www.coryd.dev/oembed" . $requestUri;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ $pagination = [
|
||||||
$pageTitle = "#" . strtolower(ucfirst($tag)) . "";
|
$pageTitle = "#" . strtolower(ucfirst($tag)) . "";
|
||||||
$pageDescription = "All content tagged with #" . strtolower(ucfirst($tag)) . ".";
|
$pageDescription = "All content tagged with #" . strtolower(ucfirst($tag)) . ".";
|
||||||
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
$fullUrl = "https://www.coryd.dev" . $requestUri;
|
||||||
|
$oembedUrl = "https://www.coryd.dev/oembed" . $requestUri;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="color-scheme" content="light dark" />
|
<meta name="color-scheme" content="light dark" />
|
||||||
<meta name="theme-color" content="{{ globals.theme_color }}" />
|
<meta name="theme-color" content="{{ globals.theme_color }}" />
|
||||||
|
<meta name="msapplication-TileColor" content="{{ globals.theme_color }}">
|
||||||
<meta name="fediverse:creator" content="{{ globals.mastodon }}" />
|
<meta name="fediverse:creator" content="{{ globals.mastodon }}" />
|
||||||
<meta name="generator" content="{{ eleventy.generator }}" />
|
<meta name="generator" content="{{ eleventy.generator }}" />
|
||||||
<link href="{{ globals.url }}/og/w50/{% appVersion %}{{ globals.avatar_transparent }}" rel="icon" sizes="any" />
|
<link href="{{ globals.url }}/og/w50/{% appVersion %}{{ globals.avatar_transparent }}" rel="icon" sizes="any" />
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<meta property="og:description" content="<?= cleanMeta($pageDescription ?? '{{ pageDescription | escape }}') ?>" />
|
<meta property="og:description" content="<?= cleanMeta($pageDescription ?? '{{ pageDescription | escape }}') ?>" />
|
||||||
<meta property="og:image" content="{{ globals.url }}<?= cleanMeta("/og/w800/{% appVersion %}" . ($ogImage ?? '{{ ogImage }}')) ?>" />
|
<meta property="og:image" content="{{ globals.url }}<?= cleanMeta("/og/w800/{% appVersion %}" . ($ogImage ?? '{{ ogImage }}')) ?>" />
|
||||||
<meta property="og:url" content="<?= cleanMeta($fullUrl ?? '{{ fullUrl }}') ?>" />
|
<meta property="og:url" content="<?= cleanMeta($fullUrl ?? '{{ fullUrl }}') ?>" />
|
||||||
|
<link rel="alternate" type="application/json+oembed" href="<?= cleanMeta($oembedUrl ?? '{{ oembedUrl }}') ?>" title="<?= cleanMeta($pageTitle ?? '{{ pageTitle }}') ?> • {{ globals.site_name }}">
|
||||||
<link rel="canonical" href="<?= cleanMeta($fullUrl ?? '{{ fullUrl }}') ?>" />
|
<link rel="canonical" href="<?= cleanMeta($fullUrl ?? '{{ fullUrl }}') ?>" />
|
||||||
<?php if (!empty($pagination)): ?>
|
<?php if (!empty($pagination)): ?>
|
||||||
<?php if (!empty($pagination['href']['next'])): ?>
|
<?php if (!empty($pagination['href']['next'])): ?>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{%- assign fullUrl = globals.url | append: page.url -%}
|
{%- assign fullUrl = globals.url | append: page.url -%}
|
||||||
|
{%- assign oembedUrl = globals.url | append: "/oembed" | append: page.url -%}
|
||||||
{%- capture pageTitle -%}
|
{%- capture pageTitle -%}
|
||||||
{%- if page.title -%}
|
{%- if page.title -%}
|
||||||
{{ page.title | append: ' • ' | append: globals.site_name }}
|
{{ page.title | append: ' • ' | append: globals.site_name }}
|
||||||
|
@ -74,6 +75,7 @@
|
||||||
{%- if type == 'dynamic' -%}
|
{%- if type == 'dynamic' -%}
|
||||||
{% render "metadata/dynamic.php.liquid"
|
{% render "metadata/dynamic.php.liquid"
|
||||||
fullUrl:fullUrl,
|
fullUrl:fullUrl,
|
||||||
|
oembedUrl:oembedUrl,
|
||||||
pageTitle:pageTitle,
|
pageTitle:pageTitle,
|
||||||
pageDescription:pageDescription,
|
pageDescription:pageDescription,
|
||||||
ogImage:ogImage,
|
ogImage:ogImage,
|
||||||
|
@ -82,6 +84,7 @@
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{% render "metadata/static.liquid"
|
{% render "metadata/static.liquid"
|
||||||
fullUrl:fullUrl,
|
fullUrl:fullUrl,
|
||||||
|
oembedUrl:oembedUrl,
|
||||||
pageTitle:pageTitle,
|
pageTitle:pageTitle,
|
||||||
pageDescription:pageDescription,
|
pageDescription:pageDescription,
|
||||||
ogImage:ogImage,
|
ogImage:ogImage,
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
<meta property="og:description" content="{{ description }}" />
|
<meta property="og:description" content="{{ description }}" />
|
||||||
<meta property="og:type" content="article" />
|
<meta property="og:type" content="article" />
|
||||||
<meta property="og:url" content="{{ fullUrl }}" />
|
<meta property="og:url" content="{{ fullUrl }}" />
|
||||||
|
<link rel="alternate" type="application/json+oembed" href="{{ oembedUrl }}" title="{{ pageTitle }}">
|
||||||
<link rel="canonical" href="{{ fullUrl }}" />
|
<link rel="canonical" href="{{ fullUrl }}" />
|
||||||
<meta property="og:image" content="{{ globals.url }}/og/w800/{% appVersion %}{{ globals.avatar }}" />
|
<meta property="og:image" content="{{ globals.url }}/og/w800/{% appVersion %}{{ globals.avatar }}" />
|
||||||
|
|
|
@ -50,6 +50,9 @@ RewriteRule ^tags/([^/]+)(?:/([0-9]+))?/?$ tags/index.php [L]
|
||||||
## open graph assets
|
## open graph assets
|
||||||
RewriteRule ^og/([a-z0-9\-]+)/([\d\.]+)/([a-f0-9\-]+)\.([a-z0-9]+)$ /api/og-image.php?id=$3&class=$1&v=$2&extension=$4 [L]
|
RewriteRule ^og/([a-z0-9\-]+)/([\d\.]+)/([a-f0-9\-]+)\.([a-z0-9]+)$ /api/og-image.php?id=$3&class=$1&v=$2&extension=$4 [L]
|
||||||
|
|
||||||
|
## oembed
|
||||||
|
RewriteRule ^oembed/(.*)$ /api/oembed.php?url=https://www.coryd.dev/$1 [L,QSA]
|
||||||
|
|
||||||
{% for redirect in redirects -%}
|
{% for redirect in redirects -%}
|
||||||
Redirect {{ redirect.status_code | default: "301" }} {{ redirect.source_url }} {{ redirect.destination_url }}
|
Redirect {{ redirect.status_code | default: "301" }} {{ redirect.source_url }} {{ redirect.destination_url }}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue