Jump to content

FieldtypeOembed


Neue Rituale
 Share

Recommended Posts

Store, collect and update oembed data from external sources. This module uses the great PHP Library Essence by Félix Girault and adds some processwire magic. It is inspired by Ryan's example module FieldtypeEvents and the TextformatterOEmbed module by felixwahner. Thanks!

Download & Install
Github: https://github.com/neuerituale/FieldtypeOembed
Modules directory: https://processwire.com/modules/fieldtype-oembed/
Composer: composer require nr/fieldtypeoembed

  • Like 15
Link to comment
Share on other sites

  • 2 years later...

https://github.com/neuerituale/FieldtypeOembed#field-preview

I‘m not the author but in my case I use it when users need to be able to add an external video (or audio) to a page and I want to make sure they properly copied the video link. I always have a dedicated field for such videos so I have no use for a TextFormatter that would do something similar in a textarea. Also the field comes with various informations that I use: width/height, poster’s url, ...

One other (albeit weird) use I have of this module is to put it as an image’s custom field so that I can replace an image by a video when I have a gallery with both pictures and videos. Though note that in order for this to work you have to allow this Fieldtype in the FieldtypeFile config page and also make a small change in PW core until Ryan accepts my PR.

Also there’s no GDPR since it’s up to you to output the iframe’s code (the `html` prop).

Link to comment
Share on other sites

29 minutes ago, monollonom said:
29 minutes ago, monollonom said:

I‘m not the author but in my case I use it when users need to be able to add an external video (or audio) to a page and I want to make sure they properly copied the video link. I always have a dedicated field for such videos so I have no use for a TextFormatter that would do something similar in a textarea. Also the field comes with various informations that I use: width/height, poster’s url, ...

Thx, I've seen that screenshot but was not sure how the module is actually used. I've been using the TextFormatter solution so far so that clients can just copy/paste youtube urls and get the embedded video.

So my question was to better understand how this module is intended to be used. How it compares to other solutions (like Textformatters). How they could maybe be combined or if that is not the idea etc.

31 minutes ago, monollonom said:

Also there’s no GDPR since it’s up to you to output the iframe’s code (the `html` prop).

I either don't agree or don't understand. But I guess it means that the module does not provide any helpers to make the embedding comply with gdpr and that is something that the developer needs to take care of?

Link to comment
Share on other sites

21 minutes ago, bernhard said:

So my question was to better understand how this module is intended to be used. How it compares to other solutions (like Textformatters). How they could maybe be combined or if that is not the idea etc.

I guess it depends on the way you structure your templates. In my case I never rely on CKEditor / TinyMCE as a way for the client to structure the page’s content, I actually mostly use them just so they can put links and eventually set in bold or italic. So if I want them to be able to add videos (where I want them to) this is the module I use.

To me if you have a video within your template that is on its own (not within a text) then you could definitely use both.

Edit: here’s an example within a repeater matrix with image/video types:

1546685580_Screenshot2023-06-19at15_27_23.thumb.png.f23a77f82ae6a688f3006259fa31d4f4.png

(french says: "Go full-bleed?" / "Is it an external video?" / "Play automatically?" (I then str_replace the embed code to add the autoplay))

21 minutes ago, bernhard said:

that is something that the developer needs to take care of?

Sorry about this but this is what I meant yes 🙂

Edited by monollonom
  • Like 1
Link to comment
Share on other sites

Thx @monollonom makes sense 🙂 

6 minutes ago, monollonom said:

I guess it depends on the way you structure your templates. In my case I never rely on CKEditor / TinyMCE as a way for the client to structure the page’s content, I actually mostly use them just so they can put links and eventually set in bold or italic. So if I want them to be able to add videos (where I want them to) this is the module I use.

To me if you have a video within your template that is on its own (not within a text) then you could definitely use both.

Actually I'm also not using that approach any more because I'm using RockPageBuilder which works similar to RepeaterMatrix where clients have several blocks of content and actually this module seems to be a perfect fit for such use cases! I've already built custom solutions for grabbing youtube preview images because I didn't know this module existed or more importantly didn't know how it can be used: https://github.com/baumrock/RockVideoThumbnailGrabber 

@Neue Rituale what I'd still be interested is how the module caches data? I guess it only caches the json response from eg the youtube video? So if I used that image url in my websites markup it would generate an external request that violates GDPR if I have no prior consent.

Does it work like this or is there an option to download the image and store it in a PW image field? I didn't see anything like this in the readme. Wouldn't that be something nice to have? 🙂 

  • Like 1
Link to comment
Share on other sites

Quote

I either don't agree or don't understand. But I guess it means that the module does not provide any helpers to make the embedding comply with gdpr and that is something that the developer needs to take care of?

Yes, the developer needs to take care of it.

We use it in different ways. One variant works with the template tag. For this, the content from `html` is wrapped in a `<template>` tag. Instead of the content, a message is displayed that refers to the external content of its respective provider. After clicking, the content of the template tag is appended into the DOM with JavaScript.

Here is an example: https://koerber-stiftung.de/en/projects/the-berlin-pulse/highlight-the-berlin-pulse-digital-tools-give-repressive-governments-the-upper-hand/#s18430

Another way is to insert the `html` (iframe) of videos (Youtube or Vimeo) via the nocookie domain or with dnt=1 parameter into Plyr. The embed data can also be used to configure the video player and placeholder (poster image, duration, aspect ratio).

The click on the play button is then also the consent. Data is then also sent via the "normal" youtube domain. The advantage of this method is that it only requires one click (trusted click) because the html is already initialised.

https://koerber-stiftung.de/mediathek/debattle-das-wortgefecht-4/

Another feature is you can find pages by OEmbed properties like:`$pages->find('my-embed-field.providerName=YouTube')`

 

  • Like 1
Link to comment
Share on other sites

Quote

... So if I used that image url in my websites markup it would generate an external request that violates GDPR if I have no prior consent

Are you sure? I thought only when personal data is transferred. (e.g. in cookies).

By the way, here is a basic example of how to store the oembed image in a separate image field. In this example, the field name is "mediaImage". But i think it is a good idea to integrate this as a feature of FieldtypeOembed.

Spoiler
// If media and no preview image exists
if(
	$page->template->name === 'media' &&
	$page->id &&
	($page->mediaImage instanceof Pageimages && $page->mediaImage->count() === 0) &&
	!empty($page->mediaEmbed)
) {

	// get data from db
	// return if no oembed data found
	$mediaEmbed = $this->pages->getRaw('id=' . $page->id, ['mediaEmbed'])['mediaEmbed'] ?? null;
	$oembed = json_decode($mediaEmbed['oembed'], JSON_OBJECT_AS_ARRAY);
	if(!$oembed || !(is_array($oembed) && array_key_exists('thumbnailUrl', $oembed))) return;

	// get field
	/** @var FieldtypeImage|FieldtypeFile $mediaImageField */
	$mediaImageField = $page->getField('mediaImage');
	$allowedExtensions = explode(' ', $mediaImageField->extensions);

	// build filename form oembed data, merge and sanitize
	$filename = array_filter(array_intersect_key($oembed, array_flip(['title', 'providerName', 'type'])));
	if(!count($filename)) $filename[] = 'thumbnail';
	$filename = $this->sanitizer->snakeCase(strtolower( implode(' ', $filename) ));

	// download file and save in tmp folder
	$fileContent = $this->files->fileGetContents($oembed['thumbnailUrl']);
	$tempDir = $this->files->tempDir();
	$path = $tempDir->get();
	$pathToFile = $path . $filename;
	$tmpFile = $this->files->filePutContents($pathToFile, $fileContent);
	if(!$tmpFile) throw new Exception('Thumbnail file is empty');

	// find extension by mime type and check if is allowed in this field
	$internalFileExtensionFromMimeType = strtolower(explode('/', mime_content_type($pathToFile))[1] ?? 'unknown');
	if(!in_array($internalFileExtensionFromMimeType, $allowedExtensions)) throw new Exception("Invalid internal filetype, \"$internalFileExtensionFromMimeType\" now allowed");

	// add mime type file extension to filename
	if(!$this->files->rename($pathToFile, $pathToFile . '.' . $internalFileExtensionFromMimeType)) throw new Exception("Error while renaming file ($filename)");
	$pathToFile = $pathToFile . '.' . $internalFileExtensionFromMimeType;

	// add file to page
	$page->of(false);
	$page->mediaImage->add($pathToFile);
	$page->save('mediaImage');
}

This code can be called in a Page::saveReady Hook with $page = $event->arguments(0);

  • Like 1
Link to comment
Share on other sites

9 minutes ago, Neue Rituale said:

Are you sure? I thought only when personal data is transferred. (e.g. in cookies).

 

It depends: at least here in Finland IP address is considered personal data, since it can be used to identify a specific person. Thus any request for a server that passes along IP address... is also passing along personal data.

  • Like 1
Link to comment
Share on other sites

43 minutes ago, Neue Rituale said:

Are you sure? I thought only when personal data is transferred. (e.g. in cookies).

Unfortunately I'm quite sure with that. It's the same with external loaded Google Fonts which means that adding youtube iframes with the nocookie options is also not ok. Unfortunately. The problem is that google says they don't store anything but that's (for good reasons) not enough for GDPR. So the only clean solution is to make sure that no personal data goes to whatever external party and yes, the IP address is also considered to be personal data.

Whether all that makes sense or not is a different question, because - as Google said itself regarding that topic - that's how the internet works. Saving youtube's preview images on your own server on the other hand might also be problematic because it could violate there terms of use. But personally I consider the risk of google complaining about that much smaller than getting a letter from some crazy lawyer because of not properly including some third party services.

1 hour ago, Neue Rituale said:

But i think it is a good idea to integrate this as a feature of FieldtypeOembed.

Great 🙂 

Link to comment
Share on other sites

  • 4 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...