5

I'm writing the below pieces of code in "Text" mode of the posts editor.

Does work:

http://www.youtube.com/watch?v=xxxxxxxxxxx

Does work:

<p>test
http://www.youtube.com/watch?v=xxxxxxxxxxx
test</p>

Doesn't work:

<p>http://www.youtube.com/watch?v=xxxxxxxxxxx</p>

The last link isn't converted to the YouTube video. I'm wondering if anyone noticed that too and if there's any known fix to that?

6

The reason why this is happening, seems to be found in the file wp-includes/class-wp-embed.php in the autoembed call-back method:

/**
 * Passes any unlinked URLs that are on their own line to {@link WP_Embed::shortcode()} for potential embedding.
 *
 * @uses WP_Embed::autoembed_callback()
 *
 * @param string $content The content to be searched.
 * @return string Potentially modified $content.
 */
function autoembed( $content ) {
    return preg_replace_callback( '|^\s*(https?://[^\s"]+)\s*$|im', array( $this, 'autoembed_callback' ), $content );
}

where

// Attempts to embed all URLs in a post
add_filter( 'the_content', array( $this, 'autoembed' ), 8 );

As I understand it, the matching lines have to contain only a link, which could be wrapped by any number of whitespace characters before and after the link itself.

So this pattern would exclude this line:

<p>http://www.youtube.com/watch?v=xxxxxxxxxxx</p>

You could try to add your own the_content filter that adds a new line before and after your links inside the paragraph tags around your link. This should be done before the autoembed filter is executed, so it should have priority under 8.

Filter Example:

One can play with the regular expressions in this great online tool:

http://regexr.com?36eat

where I've inserted the pattern:

^<p>\s*(https?://[^\s"]+)\s*</p>$

with the replacement:

<p>\n$1\n</p>

You can adjust this to your needs.

Here is one idea for such a custom filter:

add_filter( 'the_content', 'my_autoembed_adjustments', 7 );

/**
 * Add a new line around paragraph links
 * @param string $content
 * @return string $content
 */
function my_autoembed_adjustments( $content ){

    $pattern = '|<p>\s*(https?://[^\s"]+)\s*</p>|im';    // your own pattern
    $to      = "<p>\n$1\n</p>";                          // your own pattern
    $content = preg_replace( $pattern, $to, $content );

    return $content;

}
  • Thanks! However, I have WARNING: PREG_REPLACE(): UNKNOWN MODIFIER '/' error when I try the above code. So, WordPress did this intentionally and it's going to stay this way for some reason? – Paul Sep 23 '13 at 12:02
  • I could finally test it, and this pattern seems to work '|<p>\s*(https?://[^\s"]+)</p>\s*|im' where I replaced / with | and got rid of the g flag. So one has to keep in mind that there is not a 100% 1-to-1 correspondance between the parameters of the regexp test tool and preg_replace() ;-) – birgire Sep 23 '13 at 13:01
  • Thank you for reviewing it! In a situation like: <p>Test.</p><p>http://www.youtube.com/watch?v=xxxxxxxxx</p><p>Test.</p> it doesn't work. I think I'll have to play with that regular expression or leave it with default WordPress's behavior if it turns out to have too many conditions to consider. Thank you again! – Paul Sep 23 '13 at 15:50
  • You should remove the ^ and $ parts from the pattern to have a more aggressive inline replacement. This pattern: '|<p>\s*(https?://[^\s"]+)\s*</p>|im' should work on your example. – birgire Sep 23 '13 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.