Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Youtube Iframe filter dont work at custom field #2804

Closed
majestica opened this issue Jul 14, 2019 · 11 comments
Closed

Youtube Iframe filter dont work at custom field #2804

majestica opened this issue Jul 14, 2019 · 11 comments
Labels
Support Help with setup, implementation, or "How do I?" questions.

Comments

@majestica
Copy link

majestica commented Jul 14, 2019

Hi, please tell me, I encountered such a problem:
I keep in my custom field links to YouTube in the format
<iframe width = "1226" height = "480" src = "https://www.youtube.com/embed/nBpNfZkWurQ" frameborder = "0" allow = "autoplay ; encrypted-media "allowfullscreen> </ iframe>
In the normal version of the post, if the custom field with the video is filled instead of the picture, I’m showing the video (for example URL , in the amp version before the video was not shown, then the google console started sending errors that the content in the normal version and amp is different, after which I slightly changed the template output amp version to

	<div class="amp-wp-article-content">
<?php
global $post;
$meta = get_post_meta($post->ID, "_mvp_video_embed", true);
?>
<?php 
    if (get_post_meta($post->ID, "_mvp_video_embed", true)) {
     echo $meta; 
}
?>
		<?php echo $this->get( 'post_amp_content' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
	</div>

Result URL

But now the problem is that Google sends errors that they say YouTube does not match the amp format, please tell me, can I do something?

P.S
Ideally, of course, I would like to see in the amp version, if the custom video field is filled show iframe instead of a featured image as it happens in the regular post, but unfortunately I haven’t really figured out how to do it, I will be grateful for any help

@swissspidy swissspidy added the Support Help with setup, implementation, or "How do I?" questions. label Jul 15, 2019
@swissspidy
Copy link
Collaborator

Until #2202 gets implemented, which would automatically convert the iframe code into a proper amp-youtube tag, you'd have to do this yourself I think.

I'm sure @westonruter knows how to best do this in an automated way using the existing sanitizers.

@majestica
Copy link
Author

@westonruter please tell me how to be =)

@jamesozzie
Copy link
Collaborator

jamesozzie commented Jul 15, 2019

@majestica Are you using Advanced custom fields? As you are using AMP in Reader mode you could do the following, which will result in the videos playing in AMP only (and if the video field is left blank the featured image will appear in its place).

  1. Create a new custom field, of the standard "text" type, calling it 'youtubehandle' or something similar. In that field YouTube references for each post, ie "lBTCB7yLs8Y", not the full URL.

  2. Enqueue the AMP YouTube complement in your functions.php file:

add_action( 'amp_post_template_head', 'amp_add_youtube' );
function amp_add_youtube( $amp_template ) {
	$post_id = $amp_template->get( 'post_id' );
	?>
<script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script>
	<?php
}
  1. In your single.php AMP template replace the following.:
    <?php $this->load_parts( array( 'featured-image' ) ); ?>
    With the following:
<?php $youtubehandle= get_field( "youtubehandle" );
if( $youtubehandle) {
	?>
	<amp-youtube width="480"
	height="270"
	layout="responsive"
	data-videoid="<?php echo $youtubehandle; ?>">
  </amp-youtube>
  <?php
} else {
  $this->load_parts( array( 'featured-image' ) ); 
} ?> 

That worked for me anyway, although I am sure Weston might have a better solution

@westonruter
Copy link
Member

2. Enqueue the AMP YouTube complement in your functions.php file:

@jamesozzie There's a better way to do this in a way that doesn't result in duplicate scripts. Namely:

add_filter(
	'amp_post_template_data',
	function( $data ) {
		$data['amp_component_scripts'] = array_merge(
			$data['amp_component_scripts'],
			array(
				'amp-youtube' => true,
			)
		);
		return $data;
	}
);

@majestica
Copy link
Author

@majestica Are you using Advanced custom fields? As you are using AMP in Reader mode you could do the following, which will result in the videos playing in AMP only (and if the video field is left blank the featured image will appear in its place).

  1. Create a new custom field, of the standard "text" type, calling it 'youtubehandle' or something similar. In that field YouTube references for each post, ie "lBTCB7yLs8Y", not the full URL.
  2. Enqueue the AMP YouTube complement in your functions.php file:
add_action( 'amp_post_template_head', 'amp_add_youtube' );
function amp_add_youtube( $amp_template ) {
	$post_id = $amp_template->get( 'post_id' );
	?>
<script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script>
	<?php
}
  1. In your single.php AMP template replace the following.:
    <?php $this->load_parts( array( 'featured-image' ) ); ?>
    With the following:
<?php $youtubehandle= get_field( "youtubehandle" );
if( $youtubehandle) {
	?>
	<amp-youtube width="480"
	height="270"
	layout="responsive"
	data-videoid="<?php echo $youtubehandle; ?>">
  </amp-youtube>
  <?php
} else {
  $this->load_parts( array( 'featured-image' ) ); 
} ?> 

That worked for me anyway, although I am sure Weston might have a better solution

@jamesozzie Thanks, "Are you using Advanced custom fields?" No, i use wordpress default meta field, and i have more thank 5000 post with full iframe link, i cant use only video ID(((

@majestica
Copy link
Author

@westonruter I need your advice if it possible

@westonruter
Copy link
Member

So what is the contents of an example _mvp_video_embed postmeta? Is it the iframe HTML code?

@majestica
Copy link
Author

So what is the contents of an example _mvp_video_embed postmeta? Is it the iframe HTML code?

Yes, for example in postmeta _mvp_video_embed
Youtube iframe
<iframe width = "1226" height = "480" src = "https://www.youtube.com/embed/nBpNfZkWurQ" frameborder = "0" allow = "autoplay ; encrypted-media "allowfullscreen> </ iframe>
or Facebook iframe
<iframe src="https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fgleb.makkey%2Fvideos%2F1428330193988044%2F&show_text=0&width=560" width="560" height="315" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true" allowFullScreen="true"></iframe>

when I use everything inside the context, it works fine, the problem is only with the post-meta, it does not convert these i-frames into the amp format

@westonruter
Copy link
Member

@majestica The best way to do this would be to prepend your content with the meta. Try this:

add_filter(
	'the_content',
	function( $content ) {
		$meta = get_post_meta( get_the_ID(), '_mvp_video_embed', true );
		if ( $meta && function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && ! current_theme_supports( 'amp' ) ) {
			$content = "$meta\n\n$content";
		}
		return $content;
	},
	0
);

This will prepend the iframe code to your content in AMP responses if you are using the Reader mode templates.

@majestica
Copy link
Author

@majestica The best way to do this would be to prepend your content with the meta. Try this:

add_filter(
	'the_content',
	function( $content ) {
		$meta = get_post_meta( get_the_ID(), '_mvp_video_embed', true );
		if ( $meta && function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && ! current_theme_supports( 'amp' ) ) {
			$content = "$meta\n\n$content";
		}
		return $content;
	},
	0
);

This will prepend the iframe code to your content in AMP responses if you are using the Reader mode templates.

@westonruter
Thank you so much, your solution works fine. One more small question, is it possible to add amp iframes, This will help solve the problem with unresponsive frames.? layout="responsive"
Thank you

I found this in official docs

<amp-iframe width=300 height=300
    layout="responsive"
    sandbox="allow-scripts allow-same-origin"
    resizable
    src="https://foo.com/iframe">
  <div overflow tabindex=0 role=button aria-label="Read more">Read more!</div>
</amp-iframe>

@westonruter
Copy link
Member

Sure, you can just inject the layout=response attribute into the iframe element, for example:

add_filter(
	'the_content',
	function( $content ) {
		$meta = get_post_meta( get_the_ID(), '_mvp_video_embed', true );
		if ( $meta && function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && ! current_theme_supports( 'amp' ) ) {
			$meta = str_replace( '<iframe', '<iframe layout=responsive ', $meta );
			$content = "$meta\n\n$content";
		}
		return $content;
	},
	0
);

However, it is better if you would use an amp-youtube element from the start. For that, you really should not be hard-coding the <iframe> element itself. You should rather just put the plain URL to the YouTube video in the content and let WordPress's oEmbed handling convert it into a full video embed. For that, you can use this:

add_filter(
	'the_content',
	function( $content ) {
		$meta = get_post_meta( get_the_ID(), '_mvp_video_embed', true );
		if ( $meta && function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && ! current_theme_supports( 'amp' ) && preg_match( '#<iframe.+?https://www\.youtube\.com/embed/([a-zA-Z0-9_-]+)#si', $meta, $matches ) ) {
			$videoid = $matches[1];
			$url     = "https://www.youtube.com/watch?v=$videoid";
			$content = "$url\n\n$content";
		}
		return $content;
	},
	0
);

This will also be responsive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Support Help with setup, implementation, or "How do I?" questions.
Projects
None yet
Development

No branches or pull requests

4 participants