From b0e154f7a3f8662929ead46101010a3bebf765a8 Mon Sep 17 00:00:00 2001 From: solonovamax Date: Sat, 14 Dec 2024 23:58:00 -0500 Subject: [PATCH 1/2] feat(files_sharing): Add twitter meta tags Adds the following twitter meta tags - `twitter:card`: `summary_large_image` if the shared file is an image & it has a preview, otherwise `summary` - `twitter:title`: same as `og:title` - `twitter:description`: same as `og:description` - `twitter:image`: same as `og:image` Fixes nextcloud/server#49871 Signed-off-by: solonovamax --- .../DefaultPublicShareTemplateProvider.php | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php index 0c76f0e1742d6..83bcd962b62f5 100644 --- a/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php +++ b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php @@ -118,8 +118,7 @@ public function renderPage(IShare $share, string $token, string $path): Template // Allow external apps to register their scripts $this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($share)); - // OpenGraph Support: http://ogp.me/ - $this->addOpenGraphHeaders($share); + $this->addMetaHeaders($share); // CSP to allow office $csp = new ContentSecurityPolicy(); @@ -190,15 +189,17 @@ public function renderPage(IShare $share, string $token, string $path): Template * Add OpenGraph headers to response for preview * @param IShare $share The share for which to add the headers */ - protected function addOpenGraphHeaders(IShare $share): void { + protected function addMetaHeaders(IShare $share): void { $shareNode = $share->getNode(); $token = $share->getToken(); $shareUrl = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]); // Handle preview generation for OpenGraph + $hasImagePreview = false; if ($this->previewManager->isMimeSupported($shareNode->getMimetype())) { // For images we can use direct links if ($shareNode->getMimePart() === 'image') { + $hasImagePreview = true; $ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $token]); // Whatsapp is kind of picky about their size requirements if ($this->request->isUserAgent(['/^WhatsApp/'])) { @@ -226,11 +227,22 @@ protected function addOpenGraphHeaders(IShare $share): void { $ogPreview = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png')); } - Util::addHeader('meta', ['property' => 'og:title', 'content' => $shareNode->getName()]); - Util::addHeader('meta', ['property' => 'og:description', 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]); - Util::addHeader('meta', ['property' => 'og:site_name', 'content' => $this->defaults->getName()]); + $title = $shareNode->getName(); + $siteName = $this->defaults->getName(); + $description = $siteName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''); + + // OpenGraph Support: http://ogp.me/ + Util::addHeader('meta', ['property' => 'og:title', 'content' => $title]); + Util::addHeader('meta', ['property' => 'og:description', 'content' => $description]); + Util::addHeader('meta', ['property' => 'og:site_name', 'content' => $siteName]); Util::addHeader('meta', ['property' => 'og:url', 'content' => $shareUrl]); Util::addHeader('meta', ['property' => 'og:type', 'content' => 'object']); Util::addHeader('meta', ['property' => 'og:image', 'content' => $ogPreview]); + + // Twitter Support: https://developer.x.com/en/docs/x-for-websites/cards/overview/markup + Util::addHeader('meta', ['property' => 'twitter:title', 'content' => $title]); + Util::addHeader('meta', ['property' => 'twitter:description', 'content' => $description]); + Util::addHeader('meta', ['property' => 'twitter:card', 'content' => $hasImagePreview ? 'summary_large_image' : 'summary']); + Util::addHeader('meta', ['property' => 'twitter:image', 'content' => $ogPreview]); } } From e1af281988db13267a12828f3af9d3ff86f47d99 Mon Sep 17 00:00:00 2001 From: solonovamax Date: Sun, 15 Dec 2024 15:15:15 -0500 Subject: [PATCH 2/2] feat(files_sharing): Add opengraph meta tags for multimedia, change opengraph type to website - Adds the following opengraph tags - images: - `og:image:type`: the mimetype of the image file - audio: - `og:audio`: a direct link to the audio file - `og:audio:type`: the mimetype of the audio file - video: - `og:video`: a direct link to the video file - `og:video:type`: the mimetype of the video file - Changes th `og:type` meta tag from `object` (which is not valid) to `website` Signed-off-by: solonovamax --- .../lib/DefaultPublicShareTemplateProvider.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php index 83bcd962b62f5..41cb74ebdc268 100644 --- a/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php +++ b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php @@ -236,8 +236,20 @@ protected function addMetaHeaders(IShare $share): void { Util::addHeader('meta', ['property' => 'og:description', 'content' => $description]); Util::addHeader('meta', ['property' => 'og:site_name', 'content' => $siteName]); Util::addHeader('meta', ['property' => 'og:url', 'content' => $shareUrl]); - Util::addHeader('meta', ['property' => 'og:type', 'content' => 'object']); - Util::addHeader('meta', ['property' => 'og:image', 'content' => $ogPreview]); + Util::addHeader('meta', ['property' => 'og:type', 'content' => 'website']); + Util::addHeader('meta', ['property' => 'og:image', 'content' => $ogPreview]); // recommended to always have the image + if ($shareNode->getMimePart() === 'image') { + Util::addHeader('meta', ['property' => 'og:image:type', 'content' => $shareNode->getMimeType()]); + } elseif ($shareNode->getMimePart() === 'audio') { + $audio = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadshare', ['token' => $token]); + Util::addHeader('meta', ['property' => 'og:audio', 'content' => $audio]); + Util::addHeader('meta', ['property' => 'og:audio:type', 'content' => $shareNode->getMimeType()]); + } elseif ($shareNode->getMimePart() === 'video') { + $video = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadshare', ['token' => $token]); + Util::addHeader('meta', ['property' => 'og:video', 'content' => $video]); + Util::addHeader('meta', ['property' => 'og:video:type', 'content' => $shareNode->getMimeType()]); + } + // Twitter Support: https://developer.x.com/en/docs/x-for-websites/cards/overview/markup Util::addHeader('meta', ['property' => 'twitter:title', 'content' => $title]);