feat: add VideoObject JSON-LD schema for video content

Outputs VideoObject structured data when an article has a video URL
set, enabling Google video rich results. Closes #67
This commit is contained in:
Jonathan Miller
2026-06-23 11:24:56 -05:00
parent b4d5b73d15
commit aeea65423c
2 changed files with 42 additions and 0 deletions
@@ -282,6 +282,14 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
$doc->addCustomTag(JsonLdBuilder::toScriptTag($schema));
}
if (!empty($ogData->og_video)) {
$videoSchema = JsonLdBuilder::buildVideo($ogData->og_video, $title, $description, $imageUrl);
if ($videoSchema) {
$doc->addCustomTag(JsonLdBuilder::toScriptTag($videoSchema));
}
}
if ($this->params->get('jsonld_breadcrumbs', 1)) {
$breadcrumbs = JsonLdBuilder::buildBreadcrumbs();
@@ -248,6 +248,40 @@ class JsonLdBuilder
return $schema;
}
/**
* Build VideoObject schema for pages with a video URL.
*
* @param string $videoUrl Video URL (e.g. YouTube, Vimeo, or direct)
* @param string $title Video title
* @param string $description Video description
* @param string $imageUrl Thumbnail image URL (absolute)
*
* @return array|null
*/
public static function buildVideo(string $videoUrl, string $title, string $description, string $imageUrl): ?array
{
if (empty($videoUrl)) {
return null;
}
$schema = [
'@context' => 'https://schema.org',
'@type' => 'VideoObject',
'name' => $title,
'description' => $description,
'thumbnailUrl' => $imageUrl,
'contentUrl' => $videoUrl,
'uploadDate' => Factory::getDate()->toISO8601(),
];
// Add embedUrl for YouTube and Vimeo
if (preg_match('/youtube\.com|youtu\.be|vimeo\.com/i', $videoUrl)) {
$schema['embedUrl'] = $videoUrl;
}
return $schema;
}
/**
* Encode a schema array to a JSON-LD script tag string.
*