Code Monkey home page Code Monkey logo

oembed's Introduction

oEmbed plugin for Craft CMS 3.x

oEmbed

A simple plugin to extract media information from websites, like youtube videos, twitter statuses or blog articles.

Requirements

This plugin requires Craft CMS 3.0.0-beta.23 or later.

If use are looking for CraftCMS 2.5 support use previous project version 1.0.4 which is the latest release for CraftCMS 2.5.

Installing

To install the plugin, follow these instructions.

  1. Open your terminal and go to your Craft project:

     cd /path/to/project
    
  2. Then tell Composer to load the plugin:

     composer require wrav/oembed
    
  3. In the Control Panel, go to Settings → Plugins and click the “Install” button for oEmbed.

Using oEmbed

To use simply call one of the following methods on your field type

{{ entry.field.valid }} # Get the embed object
{{ entry.field.render }} # Renders HTML
{{ entry.field.embed }} # Get the embed object
{{ entry.field.media }} # Get the embed object

We also provide option to use as a Twig variable

{{ craft.oembed.valid(url, options, cacheFields) }}
{{ craft.oembed.render(url, options, cacheFields) }}
{% set embed = craft.oembed.embed(url, options, cacheFields) %}
{% set media = craft.oembed.media(url, options, cacheFields) %}

Updating the embed URL, such as autoplay, rel, mute paramaters. This allows for you to support features the provider might not yet support

{{ 
    entry.oembed_field.render({
        params: {
            autoplay: 1,
            rel: 0,
            mute: 0,
            loop: 1,
            autopause: 1,
        },
        attributes: {
            title: 'Main title',
            'data-title': 'Some other title',
        }
    }) 
}}

We still support hte old legacy method, however this might be deprecated in future versions.

{{ 
    entry.oembed_field.render({
         autoplay: 1,
         rel: 0,
         mute: 0,
         loop: 1,
         autopause: 1,
    }) 
}}

Updating the width & height attributes on the iframe can be done using the following method, however is CSS is still recommended view for sizing your iframe.

{{ 
    entry.oembed_field.render({
        width: 640,
        height: 480,
    }) 
}}

or

{{ 
    entry.oembed_field.render({
        attributes: {
            width: 640,
            height: 480,
        }
    }) 
}}

You can access additional media details using the examples below, these are the default keys.

entry.field.media.title
entry.field.media.description
entry.field.media.url
entry.field.media.type
entry.field.media.tags
entry.field.media.images
entry.field.media.image
entry.field.media.imageWidth
entry.field.media.imageHeight
entry.field.media.code
entry.field.media.width
entry.field.media.height
entry.field.media.aspectRatio
entry.field.media.authorName
entry.field.media.authorUrl
entry.field.media.providerName
entry.field.media.providerUrl
entry.field.media.providerIcons
entry.field.media.providerIcon
entry.field.media.publishedDate
entry.field.media.license
entry.field.media.linkedData
entry.field.media.feeds

You can access additional media details from the data array. These will be snake_case so be aware.

{{ dump(entry.field.media.data) }}

Additional Embed information can be found here

Cache

By default, the plugin will cache the following keys on the oembed object. The plugin can cache additional missing fields using the cache prop parameter which will take an array of strings.

{{ entry.oembed_field.render( { width: 640, height: 480, }, [ 'cacheable_key' ] ) }}

Default Keys

  • title
  • description
  • url
  • type
  • tags
  • images
  • image
  • imageWidth
  • imageHeight
  • code
  • width
  • height
  • aspectRatio
  • authorName
  • authorUrl
  • providerName
  • providerUrl
  • providerIcons
  • providerIcon
  • publishedDate
  • license
  • linkedData
  • feeds

GraphQL

I recommend enabling caching in the plugin settings menu to speed up the API resolve timing.

Below is an example of a Oembed field called "foobar" add accessing properties from the embed object.

{
  entries {
    id,
    ... on page_page_Entry {
      foobar {
        code,
        providerUrl,
        aspectRatio
      }
    }
  }
}

Credits

Original built while working at HutSix I've since been granted permission to continue development here.

Change Log

Changes can be viewed here

Support

Get in touch via email, Discord, or by creating a Github issue

oembed's People

Contributors

davidwebca avatar florisderks avatar gglnx avatar joshuabaker avatar juban avatar mijewe avatar raymondelooff avatar reganlawton avatar samuelbirch avatar sgtpenguin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

oembed's Issues

Not able to change Soundcloud embed size

How can I embed a smaller Soundcloud iframe? I tried in Craft CMS

artistAudio.audioUrl.render( {attributes: { height: 300 } } )

but it does not change the size of the widget. Soundcloud says it has different sizes for embedding and 300 is the smallest, I but prefer even a smaller iframe than 300.

Any input would really be appreciated

Youtube autoplay or mute options not working

I am trying to add the autoplay and mute options to my youtube embed but it does not work.

Here is my options defined :

{% set url = entry.oEmbedField %}
{% set options = {
  autoplay: 1,
  mute: 1
} %}
{{ craft.oembed.render(url, options) }}

And the resulted HTML :

<iframe 
    width="480" 
    height="270" 
    src="https://www.youtube.com/embed/cfcHQA175g8?feature=oembed" 
    frameborder="0" 
    allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" 
    allowfullscreen=""></iframe>

Thanks for your help.

After Update to Craft 3.2.10 the media call is unrecognized

After Update to Craft 3.2.10 the media call is unrecognized. I got this error on all lines that uses the media object.
Calling unknown method: craft\elements\MatrixBlock::media()

{% for movie in movies %}
    {% set ratio = (movie.source.media.width / movie.source.media.height)|round(2) * 100 %}
    <li class="landscape embed r_{{ ratio }}">{{ movie.source.render }}</li>
{% endfor %}

Preview is a bit large

The preview is kinda large (especially on Instagram embeds). I wonder if there is a good way to make the preview be collapsed by default, or something to that effect.

Caching issue

It seems that Craft's caching is not playing well when embedding with options, at least from Vimeo.
I have the following code:

{% set options = {'oembed' : {'parameters' : {'color': 'FF0000', 'byline': 0, 'portrait': 0, 'title': 0, 'width': '800px'}}} %}
{{ craft.oembed.render(field.media.url, options) }}

The options are ignored (video displayed with default values). I tried removing the following code from the embed function in OembedService.php:

if (Craft::$app->cache->exists($url)) {
    return \Craft::$app->cache->get($url);
}

After removing the above code, the options are working and the video is displaying as expected. Clearing the Craft cache does not fix the problem.

Internal Server Error: GraphQL fails to get oembed fields

Since version 1.3.0 the oEmbed field fails in GraphQL with an internal server error. For example:

oembed {
    ... on oembed_OembedField {
        code
    }
}

results in:

Undefined property: class@anonymous::$code

Versions:
CraftCMS – 3.4.22.1
oEmbed – 1.3.1

Width and height params do not work

I am adding the width and height params to make the iframe bigger but it does not work.
I got oEmbed plugin last version (1.2.4).

Here is my twig code :

{{
entry.resourceLinkEmbed.render({
                params: {
                  width: 1000,
                  height: 500,
                  autoplay: 1,
                  rel: 0,
                  mute: 0,
                  loop: 1,
                  autopause: 1,
                }
              })
}}

Et voici le code iframe en output :

image

Thanks for help.

YouTube or Vimeo embed with autoplay?

I can't for the life of me figure out how to use this oEmbed plugin to parse a URL to a YouTube or Vimeo video and render an iframe with control over things like width/height and autoplay. Could you possibly provide a code example?

The problem I'm running into seems to be that the options object does nothing to affect the output. Here's my code:

{% set url = entry.oEmbedField %}
{% set options = {
	autoplay: 1,
	width: "800px",
	height: "450px"
 } %}
{{ craft.oembed.render(url, options) }}

The output ends up being this (linebreaks added for readability):

<iframe
    width="480"
    height="270"
    src="https://www.youtube.com/embed/[VIDEO_ID_HERE]?feature=oembed"
    frameborder="0"
    allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
    allowfullscreen=""></iframe>

Thanks for any help you can provide!

Dealing defensively with rubbish field entries

My content editors are wonderful, but I want to ensure that even if they put something dumb in the field that errors are handled as gracefully as possible.

I am using {{ entry.field.render }} and it works well (thanks!) but if an invalid value is added to the oEmbed field, then the whole template will error: Embed\Exceptions\InvalidUrlException

Is there a way I can handle this more gracefully? I'd like the page to render with the video simply missing.

[FR] Add an option to completely disable `Preview` mode, or `Preview` on demand

Not urgent at all.

Our client usually have 10-20 instagram embeds in one single entry.
The current preview might initiate a very long load time ( i have seen 28s) when loading into the entry editing page.
Plus, if some instagram embeds failes (say, wrong link, removed post), it's even longer.

Cache could help, but i think another option is just to not preview at all.
User might only want to check when they add it in the entry.

Searching for oembed fields that contain a URL

I would like to make a query in Craft CMS for oembed fields that contain a link and skip entries that don't. It does

I tried to add this to my query:

{% set videoNews = craft.entries
.section('news')
.search('videoEmbed.media.url:*')
.orderBy('postDate desc')
.one() %}

Even adding .search('videoEmbed:*') does not work. How to find embedded fields that are not empty?

Error on Frontend

I'm getting;

Uncaught ReferenceError: $ is not defined at oembed.js?v=1543396115:15

Is it possible to disable this being referenced on the frontend? I'm not using jQuery which I assume is this issue?

Slow Twig Rendering Times

Howdy!

I've noticed a trend where entries on my site that are using embed fields inside of a matrix block are taking a very long time to load. Here's a screenshot, for example, of a nearly 8 second render time for an article with a single embed of a CNN video.

Screen Shot 2019-08-04 at 10 28 31 PM

These slow rendering times seem pretty deterministic. The only solution I've found has been to cache the article itself, which definitely helps.

I'm curious, though, whether you can think of any opportunities for optimization here on the PHP/Twig side of things.

One thing that would be cool, too, is if users could pass a custom class to the iframe that gets rendered by Twig, e.g., lazyload if you're using the lazysizes plugin, as well as being able to specify data-src instead of src.

Any ideas would be greatly appreciated!

CP resources for oEmbed plugin are added after HTML end tag

I just installed the oEmbed plugin (v1.3.4 on Craft 3.5.5) and added a oEmbed field to an entry type. When editing an entry, I noticed that the control panel resources, i.e. the JavaScript and CSS, are outside the HTML document:

...
</body>
</html>
<script src='https://paleo.test/cpresources/14d5b05b/oembed.js?v=1598262036'></script><link rel='stylesheet' href='https://paleo.test/cpresources/3ebdc379/oembed.css?v=1598262036'>

I am not sure if this is a bug in the plugin; I haven't looked that far into the code. The first oEmbed item I tried to load (https://purl.stanford.edu/fw090jw3474) would not show and wanted to look at the browser's network monitor panel to find out why, which is when I noticed the issue above.

Embed Instagram with params `hidecaption` didnt work

The instagram hidecaption params didnt work
{{ block.embed.render({ parms:{ hidecaption: true } }) }}

Temporary fix:
{{ block.embed.render() | replace({'data-instgrm-captioned': ''}) | raw }}

any idea on why it isnt working?

ErrorException: Array to string conversion

When I change the propagation method on an section, I get this error inside queue.log - and Craft will attempt rerunning the job over and over again:

2019-08-12 03:00:19 [-][1][-][info][yii\db\Command::query] SELECT `elements`.`id`, `elements`.`fieldLayoutId`, `elements`.`uid`, `elements`.`enabled`, `elements`.`archived`, `elements`.`dateCreated`, `elements`.`dateUpdated`, `elements_sites`.`slug`, `elements_sites`.`siteId`, `elements_sites`.`uri`, `elements_sites`.`enabled` AS `enabledForSite`, `entries`.`sectionId`, `entries`.`typeId`, `entries`.`authorId`, `entries`.`postDate`, `entries`.`expiryDate`, `content`.`id` AS `contentId`, `content`.`title`, `content`.`field_acknowledgementsLink`, `content`.`field_nominalPressure`, `content`.`field_bodyText`, `content`.`field_button`, `content`.`field_cookiesLink`, `content`.`field_description`, `content`.`field_productDescription`, `content`.`field_personEmail`, `content`.`field_externalLink`, `content`.`field_dispersedAirVolume`, `content`.`field_cylinderVolume`, `content`.`field_groupListHeader`, `content`.`field_locationIntro`, `content`.`field_mainEmail`, `content`.`field_maxPressure`, `content`.`field_moreContactInfoLink`, `content`.`field_effect`, `content`.`field_locationName`, `content`.`field_personName`, `content`.`field_productName`, `content`.`field_openInNewWindow`, `content`.`field_overskrift`, `content`.`field_personPhone`, `content`.`field_buttonPrimary`, `content`.`field_relatedElementsHeader`, `content`.`field_relationTypes`, `content`.`field_seo`, `content`.`field_showRelatedElements`, `content`.`field_size`, `content`.`field_slideText`, `content`.`field_videoSlideText`, `content`.`field_slideTitle`, `content`.`field_videoSlideTitle`, `content`.`field_stretch`, `content`.`field_power`, `content`.`field_db`, `content`.`field_focusItemSubtitle`, `content`.`field_heroSubtitle`, `content`.`field_subtitle`, `content`.`field_bodyIntro`, `content`.`field_featureText`, `content`.`field_storyText`, `content`.`field_bodyTitle`, `content`.`field_featureTitle`, `content`.`field_focusItemTitle`, `content`.`field_focusTitle`, `content`.`field_heroTitle`, `content`.`field_personTitle`, `content`.`field_storyTitle`, `content`.`field_embed`, `content`.`field_videoUrl`, `content`.`field_volume`, `structureelements`.`root`, `structureelements`.`lft`, `structureelements`.`rgt`, `structureelements`.`level`, `structureelements`.`structureId`
FROM (SELECT `elements`.`id` AS `elementsId`, `elements_sites`.`id` AS `elementsSitesId`, `content`.`id` AS `contentId`, `structureelements`.`structureId`
FROM `elements` `elements`
INNER JOIN `entries` `entries` ON `entries`.`id` = `elements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `elements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `elements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `elements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `elements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
WHERE (`elements`.`archived`=FALSE) AND (`elements`.`dateDeleted` IS NULL) AND (`elements`.`draftId` IS NULL) AND (`elements`.`revisionId` IS NULL) AND (`elements_sites`.`id` = (SELECT `elements_sites`.`id`
FROM `elements` `subElements`
INNER JOIN `entries` `entries` ON `entries`.`id` = `subElements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `subElements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `subElements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subElements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `subElements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
WHERE (`subElements`.`archived`=FALSE) AND (`subElements`.`dateDeleted` IS NULL) AND (`subElements`.`draftId` IS NULL) AND (`subElements`.`revisionId` IS NULL) AND (`subElements`.`id` = `elements`.`id`)
ORDER BY case when `elements_sites`.`siteId` = 1 then 0 else 1 end, `elements_sites`.`id`
LIMIT 1))
ORDER BY `relations`.`sortOrder`
LIMIT 1) `subquery`
INNER JOIN `entries` `entries` ON `entries`.`id` = `subquery`.`elementsId`
INNER JOIN `elements` `elements` ON `elements`.`id` = `subquery`.`elementsId`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`id` = `subquery`.`elementsSitesId`
INNER JOIN `content` `content` ON `content`.`id` = `subquery`.`contentId`
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subquery`.`elementsId`) AND (`structureelements`.`structureId` = `subquery`.`structureId`)
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `elements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
ORDER BY `relations`.`sortOrder`
2019-08-12 03:00:19 [-][1][-][profile begin][yii\db\Command::query] SELECT `elements`.`id`, `elements`.`fieldLayoutId`, `elements`.`uid`, `elements`.`enabled`, `elements`.`archived`, `elements`.`dateCreated`, `elements`.`dateUpdated`, `elements_sites`.`slug`, `elements_sites`.`siteId`, `elements_sites`.`uri`, `elements_sites`.`enabled` AS `enabledForSite`, `entries`.`sectionId`, `entries`.`typeId`, `entries`.`authorId`, `entries`.`postDate`, `entries`.`expiryDate`, `content`.`id` AS `contentId`, `content`.`title`, `content`.`field_acknowledgementsLink`, `content`.`field_nominalPressure`, `content`.`field_bodyText`, `content`.`field_button`, `content`.`field_cookiesLink`, `content`.`field_description`, `content`.`field_productDescription`, `content`.`field_personEmail`, `content`.`field_externalLink`, `content`.`field_dispersedAirVolume`, `content`.`field_cylinderVolume`, `content`.`field_groupListHeader`, `content`.`field_locationIntro`, `content`.`field_mainEmail`, `content`.`field_maxPressure`, `content`.`field_moreContactInfoLink`, `content`.`field_effect`, `content`.`field_locationName`, `content`.`field_personName`, `content`.`field_productName`, `content`.`field_openInNewWindow`, `content`.`field_overskrift`, `content`.`field_personPhone`, `content`.`field_buttonPrimary`, `content`.`field_relatedElementsHeader`, `content`.`field_relationTypes`, `content`.`field_seo`, `content`.`field_showRelatedElements`, `content`.`field_size`, `content`.`field_slideText`, `content`.`field_videoSlideText`, `content`.`field_slideTitle`, `content`.`field_videoSlideTitle`, `content`.`field_stretch`, `content`.`field_power`, `content`.`field_db`, `content`.`field_focusItemSubtitle`, `content`.`field_heroSubtitle`, `content`.`field_subtitle`, `content`.`field_bodyIntro`, `content`.`field_featureText`, `content`.`field_storyText`, `content`.`field_bodyTitle`, `content`.`field_featureTitle`, `content`.`field_focusItemTitle`, `content`.`field_focusTitle`, `content`.`field_heroTitle`, `content`.`field_personTitle`, `content`.`field_storyTitle`, `content`.`field_embed`, `content`.`field_videoUrl`, `content`.`field_volume`, `structureelements`.`root`, `structureelements`.`lft`, `structureelements`.`rgt`, `structureelements`.`level`, `structureelements`.`structureId`
FROM (SELECT `elements`.`id` AS `elementsId`, `elements_sites`.`id` AS `elementsSitesId`, `content`.`id` AS `contentId`, `structureelements`.`structureId`
FROM `elements` `elements`
INNER JOIN `entries` `entries` ON `entries`.`id` = `elements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `elements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `elements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `elements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `elements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
WHERE (`elements`.`archived`=FALSE) AND (`elements`.`dateDeleted` IS NULL) AND (`elements`.`draftId` IS NULL) AND (`elements`.`revisionId` IS NULL) AND (`elements_sites`.`id` = (SELECT `elements_sites`.`id`
FROM `elements` `subElements`
INNER JOIN `entries` `entries` ON `entries`.`id` = `subElements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `subElements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `subElements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subElements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `subElements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
WHERE (`subElements`.`archived`=FALSE) AND (`subElements`.`dateDeleted` IS NULL) AND (`subElements`.`draftId` IS NULL) AND (`subElements`.`revisionId` IS NULL) AND (`subElements`.`id` = `elements`.`id`)
ORDER BY case when `elements_sites`.`siteId` = 1 then 0 else 1 end, `elements_sites`.`id`
LIMIT 1))
ORDER BY `relations`.`sortOrder`
LIMIT 1) `subquery`
INNER JOIN `entries` `entries` ON `entries`.`id` = `subquery`.`elementsId`
INNER JOIN `elements` `elements` ON `elements`.`id` = `subquery`.`elementsId`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`id` = `subquery`.`elementsSitesId`
INNER JOIN `content` `content` ON `content`.`id` = `subquery`.`contentId`
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subquery`.`elementsId`) AND (`structureelements`.`structureId` = `subquery`.`structureId`)
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `elements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
ORDER BY `relations`.`sortOrder`
2019-08-12 03:00:19 [-][1][-][profile end][yii\db\Command::query] SELECT `elements`.`id`, `elements`.`fieldLayoutId`, `elements`.`uid`, `elements`.`enabled`, `elements`.`archived`, `elements`.`dateCreated`, `elements`.`dateUpdated`, `elements_sites`.`slug`, `elements_sites`.`siteId`, `elements_sites`.`uri`, `elements_sites`.`enabled` AS `enabledForSite`, `entries`.`sectionId`, `entries`.`typeId`, `entries`.`authorId`, `entries`.`postDate`, `entries`.`expiryDate`, `content`.`id` AS `contentId`, `content`.`title`, `content`.`field_acknowledgementsLink`, `content`.`field_nominalPressure`, `content`.`field_bodyText`, `content`.`field_button`, `content`.`field_cookiesLink`, `content`.`field_description`, `content`.`field_productDescription`, `content`.`field_personEmail`, `content`.`field_externalLink`, `content`.`field_dispersedAirVolume`, `content`.`field_cylinderVolume`, `content`.`field_groupListHeader`, `content`.`field_locationIntro`, `content`.`field_mainEmail`, `content`.`field_maxPressure`, `content`.`field_moreContactInfoLink`, `content`.`field_effect`, `content`.`field_locationName`, `content`.`field_personName`, `content`.`field_productName`, `content`.`field_openInNewWindow`, `content`.`field_overskrift`, `content`.`field_personPhone`, `content`.`field_buttonPrimary`, `content`.`field_relatedElementsHeader`, `content`.`field_relationTypes`, `content`.`field_seo`, `content`.`field_showRelatedElements`, `content`.`field_size`, `content`.`field_slideText`, `content`.`field_videoSlideText`, `content`.`field_slideTitle`, `content`.`field_videoSlideTitle`, `content`.`field_stretch`, `content`.`field_power`, `content`.`field_db`, `content`.`field_focusItemSubtitle`, `content`.`field_heroSubtitle`, `content`.`field_subtitle`, `content`.`field_bodyIntro`, `content`.`field_featureText`, `content`.`field_storyText`, `content`.`field_bodyTitle`, `content`.`field_featureTitle`, `content`.`field_focusItemTitle`, `content`.`field_focusTitle`, `content`.`field_heroTitle`, `content`.`field_personTitle`, `content`.`field_storyTitle`, `content`.`field_embed`, `content`.`field_videoUrl`, `content`.`field_volume`, `structureelements`.`root`, `structureelements`.`lft`, `structureelements`.`rgt`, `structureelements`.`level`, `structureelements`.`structureId`
FROM (SELECT `elements`.`id` AS `elementsId`, `elements_sites`.`id` AS `elementsSitesId`, `content`.`id` AS `contentId`, `structureelements`.`structureId`
FROM `elements` `elements`
INNER JOIN `entries` `entries` ON `entries`.`id` = `elements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `elements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `elements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `elements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `elements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
WHERE (`elements`.`archived`=FALSE) AND (`elements`.`dateDeleted` IS NULL) AND (`elements`.`draftId` IS NULL) AND (`elements`.`revisionId` IS NULL) AND (`elements_sites`.`id` = (SELECT `elements_sites`.`id`
FROM `elements` `subElements`
INNER JOIN `entries` `entries` ON `entries`.`id` = `subElements`.`id`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`elementId` = `subElements`.`id`
INNER JOIN `content` `content` ON (`content`.`elementId` = `subElements`.`id`) AND (`content`.`siteId` = `elements_sites`.`siteId`)
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subElements`.`id`) AND (EXISTS (SELECT *
FROM `structures`
WHERE (`id` = `structureelements`.`structureId`) AND (`dateDeleted` IS NULL)))
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `subElements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
WHERE (`subElements`.`archived`=FALSE) AND (`subElements`.`dateDeleted` IS NULL) AND (`subElements`.`draftId` IS NULL) AND (`subElements`.`revisionId` IS NULL) AND (`subElements`.`id` = `elements`.`id`)
ORDER BY case when `elements_sites`.`siteId` = 1 then 0 else 1 end, `elements_sites`.`id`
LIMIT 1))
ORDER BY `relations`.`sortOrder`
LIMIT 1) `subquery`
INNER JOIN `entries` `entries` ON `entries`.`id` = `subquery`.`elementsId`
INNER JOIN `elements` `elements` ON `elements`.`id` = `subquery`.`elementsId`
INNER JOIN `elements_sites` `elements_sites` ON `elements_sites`.`id` = `subquery`.`elementsSitesId`
INNER JOIN `content` `content` ON `content`.`id` = `subquery`.`contentId`
LEFT JOIN `structureelements` `structureelements` ON (`structureelements`.`elementId` = `subquery`.`elementsId`) AND (`structureelements`.`structureId` = `subquery`.`structureId`)
INNER JOIN `relations` `relations` ON (`relations`.`targetId` = `elements`.`id`) AND ((`relations`.`sourceId`='467') AND (`relations`.`fieldId`='56')) AND ((`relations`.`sourceSiteId` IS NULL) OR (`relations`.`sourceSiteId`='1'))
ORDER BY `relations`.`sortOrder`
2019-08-12 03:00:19 [-][1][-][error][yii\base\ErrorException:8] yii\base\ErrorException: Array to string conversion in C:\customer\customer_automasjon_craft_hyperlane\vendor\wrav\oembed\src\models\OembedModel.php:49
Stack trace:
#0 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\helpers\StringHelper.php(762): wrav\oembed\models\OembedModel->__toString()
#1 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\base\Field.php(378): craft\helpers\StringHelper::toString()
#2 C:\customer\customer_automasjon_craft_hyperlane\vendor\spicyweb\craft-neo\src\services\Blocks.php(67): wrav\oembed\fields\OembedField->getSearchKeywords()
#3 C:\customer\customer_automasjon_craft_hyperlane\vendor\spicyweb\craft-neo\src\Field.php(552): benf\neo\services\Blocks->getSearchKeywords()
#4 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\services\Search.php(134): benf\neo\Field->getSearchKeywords()
#5 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\queue\jobs\UpdateSearchIndex.php(55): craft\services\Search->indexElementAttributes()
#6 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2-queue\src\Queue.php(214): craft\queue\jobs\UpdateSearchIndex->execute()
#7 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2-queue\src\cli\Queue.php(147): craft\queue\Queue->handleMessage()
#8 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\queue\Queue.php(96): craft\queue\Queue->handleMessage()
#9 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\controllers\QueueController.php(86): craft\queue\Queue->run()
#10 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2\base\InlineAction.php(57): craft\controllers\QueueController->actionRun()
#11 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2\base\InlineAction.php(57): ::call_user_func_array:{C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2\base\InlineAction.php:57}()
#12 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2\base\Controller.php(157): yii\base\InlineAction->runWithParams()
#13 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\web\Controller.php(187): craft\controllers\QueueController->runAction()
#14 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2\base\Module.php(528): craft\controllers\QueueController->runAction()
#15 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\web\Application.php(299): craft\web\Application->runAction()
#16 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\web\Application.php(566): craft\web\Application->runAction()
#17 C:\customer\customer_automasjon_craft_hyperlane\vendor\craftcms\cms\src\web\Application.php(278): craft\web\Application->_processActionRequest()
#18 C:\customer\customer_automasjon_craft_hyperlane\vendor\yiisoft\yii2\base\Application.php(386): craft\web\Application->handleRequest()
#19 C:\customer\customer_automasjon_craft_hyperlane\web\index.php(21): craft\web\Application->run()

The entries of this section are propagated with the option "Save entries to all sites enabled for this section"

Craft CMS Version: 3.2.9
oEmbed Version: 1.1.6
Neo Version: 2.4.2
Multisite: Yes, four sites.

Undefined index: autoplay

After performing some routine CMS & plugin updates on Craft, Sentry has started reporting an error for the oembed plugin, happening from both editing an entry and in the templates on entries that are using the oembed field.

https://sentry.io/share/issue/c4683affddff40c3bdcaad1ce37dffd7/
https://sentry.io/share/issue/d67205af7c234e058c4672eaf199ecf8/

Plugins updated:

  • Craft (3.3.18.3)
  • Sentry (1.0.2)
  • Seomatic (3.2.37)
  • Freeform (3.5.8)

Craft Version: 3.3.18.3
oEmbed Version: 1.1.8

Upgrading to 1.2.0+ disables admin UI

Description

After upgrading to 1.2.0+ the admin UI is completely disabled for entries that contain an oEmbed field. This happens only after the entry is saved with a value for the field. Once the iframe preview is visible, the UI becomes unresponsive.

It seems as if javascript is completely disabled at this point. Image previews don't load, field tabs don't work, fields themselves are not clickable. The problem persists after reloading the page.

Environment

Screen Shot 2020-01-30 at 2 41 33 PM

Facebook video mute when playing

Is there a way to make Facebook embedded videos unmute when we click PLAY?
Because now the Facebook videos are MUTE after click on PLAY:
image

(is there also a way to remove the infos at top/left and the share link at top/right?)

Instagram not working on production

Hi there, I've been able to get Facebook and Instagram links working great locally. Just pushed an update to test live and Facebook works fine by Instagram does not. See screenshots below. Any ideas?

Local:
Screen Shot 2020-05-25 at 3 20 24 pm

Live:
Screen Shot 2020-05-25 at 3 19 25 pm

Add embed url or video id as one of the variables

In addition to these already available variables

entry.field.media.title
entry.field.media.description
entry.field.media.url
entry.field.media.type
entry.field.media.tags
entry.field.media.images
entry.field.media.image
entry.field.media.imageWidth
entry.field.media.imageHeight
entry.field.media.code
entry.field.media.width
entry.field.media.height
entry.field.media.aspectRatio
entry.field.media.authorName
entry.field.media.authorUrl
entry.field.media.providerName
entry.field.media.providerUrl
entry.field.media.providerIcons
entry.field.media.providerIcon
entry.field.media.publishedDate
entry.field.media.license
entry.field.media.linkedData
entry.field.media.feeds

Could you add:

entry.field.media.id
entry.field.media.embed_url

The reason I think it would be helpful is if someone wanted to build their own iframe element, they can build their own iframe tag and apply params like &rel=0 to it

Works on local but not production

Hi! So when I put a YouTube link in my local Homestead/Laravel environment, it works fine. When I push to our production, for whatever reason, it fails. Sometimes it resolves, but it's a little distressing as this is a public website i'm working on. Is there any explanation or solve for this?

Local is nginx. Staging and production is Apache (another company set it up). Don't know if this makes a difference. I keep getting "Please check your URL." I know the URLs are valid.

Please let me know any additional information. It's not the Twig code, so I'm at a loss and can't find any additional documentation that describes this exact issue. Thanks!

Preview failing for Libsyn oEmbed link

Hi!

The perfect plugin to help me move some of my entry content out into a proper field structure. :) I was going to use Libsyn's iframe, but oEmbed seems like a more sane, structured option to use if I can.

I installed the plugin, added a field, and tried entering the URL, but the Preview fails, saying "check your URL". I'm wondering if there's a bug, or Libsyn isn't doing its oEmbed thing right.

Here's the URL in question: https://oembed.libsyn.com/embed?item_id=8634992. I can drop it into a browser fine, and wget it. I even tried copying out the (ahem) embedded oEmbed link inside the payload and that didn't work either: https://oembed.libsyn.com?item_id=8634992. (I validated that the second link does return a JSON payload.)

I haven't yet tried to render the field, but I figure this is a bug either way even if it's just the preview.

Any ideas? Thanks for making this!

System info:

PHP version | 7.2.15
Linux 4.15.0-43-generic
MySQL 5.7.25
Imagick 3.4.3RC2 (ImageMagick 6.9.7-4)
Craft Solo 3.1.14
oEmbed 1.0.5

How to use options?

I have this working with YouTube, however the youtube embed is automatically setting the height and width attributes in the iframe tag. I'd like to be able to set those myself.

My current code is:

{% set options = {
  height: "405px",
  width: "720px"  
} %}

{{ craft.oembed.render(block.youtubeLink, options) }}

However the options don't appear to be doing anything.

Preview doesn't work everywhere

Thanks for your work! I'm running into an issue with the preview of embedded content...

The JavaScript and CSS responsible for the preview is only loaded on entry pages. However, due to how fields work in Craft the field can show up in various other places - such as assets, globals, categories, dashboard widgets etc.

Why did you change it so the resources are only loaded for pages under /admin/entries/? (commit 6cb0912)
And would you be willing to revert this change so the preview works across the whole control panel?

Craft 3.1 beta

Would be good to allow for Craft 3.1.beta.1 in the dependencies. At the moment this will block a 3.1 beta install.

PS D:\inet_craft\public> composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - wrav/oembed 1.0.3 requires craftcms/cms ~3.0.0-beta.23 -> satisfiable by craftcms/cms[3.0.0, 3.0.0-RC1, 3.0.0-RC10, 3.0.0-RC10.1, 3.0.0-RC11, 3.0.0-RC12, 3.0.0-RC13, 3.0.0-RC14, 3.0.0-RC15, 3.0.0-RC16, 3.0.0-RC16.1, 3.0.0-RC17, 3.0.0-RC17.1, 3.0.0-RC2, 3.0.0-RC3, 3.0.0-RC4, 3.0.0-RC5, 3.0.0-RC6, 3.0.0-RC7, 3.0.0-RC7.1, 3.0.0-RC8, 3.0.0-RC9, 3.0.0-beta.23, 3.0.0-beta.24, 3.0.0-beta.25, 3.0.0-beta.26, 3.0.0-beta.27, 3.0.0-beta.28, 3.0.0-beta.29, 3.0.0-beta.30, 3.0.0-beta.31, 3.0.0-beta.32, 3.0.0-beta.33, 3.0.0-beta.34, 3.0.0-beta.35, 3.0.0-beta.36, 3.0.0.1, 3.0.0.2, 3.0.1, 3.0.10, 3.0.10.1, 3.0.10.2, 3.0.10.3, 3.0.11, 3.0.12, 3.0.13, 3.0.13.1, 3.0.13.2, 3.0.14, 3.0.15, 3.0.16, 3.0.16.1, 3.0.17, 3.0.17.1, 3.0.18, 3.0.19, 3.0.2, 3.0.20, 3.0.21, 3.0.22, 3.0.23, 3.0.23.1, 3.0.24, 3.0.25, 3.0.26, 3.0.26.1, 3.0.27, 3.0.27.1, 3.0.28, 3.0.29, 3.0.3, 3.0.3.1, 3.0.30, 3.0.30.1, 3.0.30.2, 3.0.31, 3.0.32, 3.0.33, 3.0.34, 3.0.4, 3.0.5, 3.0.6, 3.0.7, 3.0.8, 3.0.9] but these conflict with your requirements or minimum-stability. 

rel:0 not being applied to iframe url param

I have an oEmbed field with a handle of: videoUrl

I pasted the youtube url for a video into the field: https://www.youtube.com/watch?v=BAtlRhAteY4

I then output the iframe using this snippet of code in my twig file:

{{ entry.videoUrl.render({ params: { rel: 0 } }) }}

I expect to see &rel=0 in the iframe markup, this is what I see when I inspect the page:

<iframe width="480" height="270" src="https://www.youtube.com/embed/BAtlRhAteY4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

There is no caching enabled on the site.

Support GDPR-friendly cookieless YouTube embeds

I realise this is a bit edge-case and perhaps out of the scope of this plugin, but I believe it brings value so bare with me!

In Europe we have the GDPR which sets rules to how you can use cookies on websites. Google have reacted to this by providing 'Privacy Enhanced mode' for embeds which doesn't drop any cookies into embeds - which is brilliant.

Users of the CMS, however, just want to hit 'Share' on YouTube, get a url like this:
https://youtu.be/l1W8bQ-O5Bs
…and paste that into the oembed field. It's a bit much to ask busy, non-technical users to manipulate that into a a url like this:
https://www.youtube-nocookie.com/embed/l1W8bQ-O5Bs
… which will work.

Do you think it'd be possible for this plugin to support such an option, where the work is done for them? I can't think of a way to do it without abandoning this plugin - which I don't want to do. I think overall, that this is a better way to embed YouTube videos.

Render method not working for Instagram

This works fine for Youtube and Twitter, but when I try an Instagram URL, the preview works but the render method does not. I could be doing something wrong but I've done fairly extensive testing.

Ideas?

Add ability to pull just the embed URL or just the video id itself

I have a page with lots of videos, and embedding all of them slows it to a crawl. I found this method to embed them without hurting performance:

https://css-tricks.com/lazy-load-embedded-youtube-videos/

This method requires me to be able to pull the embed URL or even just the video id (that seemingly random string unique to each YouTube video). I don't seem to be able to pull only that information - I get more than I want and I don't have an easy way to strip out the extra.

If something like {{ entry.field.media.videoid }} returned just that string, that could easily be inserted into any kind of unique embed.

Alternately, there is this method, but it also requires the video id:

https://github.com/paulirish/lite-youtube-embed

Finally, perhaps if you wanted to get fancy, you could implement either of the "lite youtube" methods above as an option in the plug-in.

JS file placement and console error in 1.0.2

I guess this is two things but related?

  1. the <script src='http://domain.com/cpresources/52b8ecf8/oembed.js?v=1544072154'></script> link appears outside the <html> tag, which I'm pretty sure is invalid HTML - is that to do with my front end?

  2. it also throws:

oembed.js?v=1544072154:18 Uncaught TypeError: Cannot read property 'addEventListener' of null
    at oembed.js?v=1544072154:18
    at Array.forEach (<anonymous>)
    at oembed.js?v=1544072154:17
(anonymous) @ oembed.js?v=1544072154:18
(anonymous) @ oembed.js?v=1544072154:17

in the console.

I can't help feeling that we should have an option to not include JS from cpresources too, and include it from the front end @webroot assets folder, even if it does then require an extra step?

FR: GraphQL Support?

Hi, unless I am missing something, it seems only the user input embed URL is exposed to graphql. Since gql support in Craft is now native, do you have plans to support this and expose all data?

Thanks

`Please check your URL` YouTube bug in production

Hi there! First, thanks so much for the wonderful oEmbed plugin. I'm seeing a current issue on my Laravel Forge / Digital Ocean production environment. It only happens with valid YouTube URLs:

image

The output is simply Please check your URL. Here is an example YouTube URL that I'm trying:

https://www.youtube.com/watch?v=zVi_9rlepbE

I tested it in my Laravel Valet local environment and I couldn't encounter the same issue. Thanks so much for your help!

Add support for title attribute

To improve accessibility for screen readers, it's desirable to have a title attribute on the rendered iframe.

Is there any chance support for this could be added? :)

Thanks 🙏

Vimeo not working in some environments

I have a local install with Craft 3.3.1 and a remote copy with the same. Both use the current (1.1.6) version of the plugin.

YouTube works fine, but Vimeo does not.

Screenshot 2019-09-03 at 10 55 26

On the front end, no video embed code is shown.

I think that this used to work. But no longer. I can't work out why it works in one place but not the other. What information can I provide you with to help fix this?

Get the width and height attribute from a direct vimeo link

How can I get the width and height from a direct vimeo url? The plugin fetches and returns the url but the media.width and media.height returns null. If the plugin doesn't do that, is it possible to get the preview image from the CP?

Preview Doesn't Appear Until Entry Saved

Howdy! Thanks for building this fantastic plugin.

I'm not sure whether this is a bug, feature request, or something altogether different.

When pasting a URL into an oEmbed field, I expect something to appear in the Preview field directly underneath. However, I can't get anything to appear until I've saved the entry and the page refreshes.

Is this intentional? It would be helpful for content creators on my site to be able preview their embed link, just to verify that they're pasting something that actually works.

❤️

Fetch thumbnail for CP

Hi, is there a solution to have the embedded media's thumbnail or image available when choosing columns in the CP's "Customize sources" table? Thx in advance.

Adding to querysting of media.url when using render method.

Been looking through the issues on this damn handy plugin and cannot find an equivalent issue.

Problem I have is when a video is paused or finished YouTube throws up related videos, nice if you're browsing but not nice if your company video is displaying your competing company video after viewing.

I've got around this in the past appending adding '&rel=0' to to the youTube url path as shown below using your embed code with rel=0 added. (rel=0 sets 'show related videos' to show related videos that are from the same channel as the video that was just played.)

<iframe width="770" height="433" src="https://www.youtube.com/embed/LXb3EKWsInQ?feature=oembed&rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Ideally we'd be able to add to the querystring using another param of the render method it looks like it's a passthru for $media->code.

Any pointers on how I best to do this with native oembed, tried without success so far.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.