0

Goal: convert Facebook url itself (without full code snippet) into Facebook post on website front-end

Problem: The experimental o2 / p2 / breathe theme, by default, converts a full Facebook code snippet in the editor to a full Facebook post on the front-end. Example snippet:

<div class="fb-post" data-href="https://www.facebook.com/WordPresscom/posts/10154113693553980" max-width="90%">

I would like to instead just be able to post ONLY the url into the editor and have the url wrapped with <div class="fb-post" data-href=" ... " max-width="90%"> in the source-code.

I assume I would need to do this through functions.php?

2

Note that Facebook is a registered oEmbed provider in the WordPress core.

You could e.g. use the pre_oembed_result filter, before the HTTP request is made, to cancel it and override it to your needs.

Here's an example for Facebook posts:

add_filter( 'pre_oembed_result', function ( $result, $url, $args )
{ 
    // override the HTML result for Facebook posts, that will be saved into postmeta table
    if( preg_match( '#https?://www\.facebook\.com/.*/posts/.*#i', $url ) )
        $result = sprintf( 
            '<div class="fb-post" data-href="%s">%s</div>',
            esc_url( $url ), 
            esc_url( $url ) 
        );

    return $result;

}, 10, 3 );

When you paste a Facebook post url, into the post content editor, it will also show the modified oEmbed result, with our snippet.

The oEmbed results are cached by default in the postmeta table, for DAY_IN_SECONDS (24 hours).

We can play with the oembed_ttl filter, like here, but in the meanwhile we can also filter the cached output with the embed_oembed_html filter.

Here's an example:

add_filter( 'embed_oembed_html', function( $cache, $url, $attr, $post_id )
{
    // override the cached HTML result for Facebook posts
    if( preg_match( '#https?://www\.facebook\.com/.*/posts/.*#i', $url ) )
        $cache = sprintf( 
            '<div class="fb-post" data-href="%s">%s</div>',
            esc_url( $url ), 
            esc_url( $url ) 
        );

    return $cache;

}, 10, 4 );
  • I input this into functions.php and result is unchanged. I have multiple Facebook posts on the page and only the one with the snippet I manually entered displays. The other where I posted just the link still does not display. I don't see more than one instance of data-href. No errors in console either. I may try submitting as bug to theme developer. – Adam Jan 21 '17 at 14:13
  • The oEmbeds are cached for 24 hours, so that's expected. I updated the answer. @Adam – birgire Jan 21 '17 at 15:37
  • Here is the live site (which I'm taking out of maintenance mode temporarily): beertournament.com/ I've inputted the new code into functions.php but still same result. I've tried creating new posts with new Facebook links & still same behavior. Could be a theme bug; I have added a comment to the Automattic o2 Github. – Adam Jan 21 '17 at 16:11
  • Some posts now appear to convert but some don't. Hmm.. – Adam Jan 21 '17 at 16:20
  • I tested, with this FB post that you posted, on TwentySeventeen theme and it seems to work. Note that I only match FB posts here not FB photos, FB videos, FB comments etc. Play with the snippets to understand how they work and keep in mind the oEmbed cache per url per blog post. If you think it's the theme that's interfering (doubt it though), try the default themes (remember to backup your db before switching themes or just create a new seperate test install). – birgire Jan 21 '17 at 16:23
0

You need to use the php preg_replacefunction in order to transform your url into an snippet.

Please keep in mind:

  • The URLs must be started with http://facebook.com/ or https://facebook.com/ for the function to work.
  • If you someday try to add a link without turning into an snippet, you will face problems since this function will turn any facebook link into an snippet.
  • I haven't tested the code myself, you can check this link and modify the rules to achieve the best results.

Add the following code to you function.php file:

    add_filter( 'the_content', 'the_facebook_filter', 20 );
    function the_facebook_filter( $content ) {
        $fb_links = wp_extract_urls( $content );
        $string = preg_replace('#http://facebook.com/(.*?)#i', '<div class="fb-post" data-href="\1" max-width="90%"></div>', $fb_links[0]);
        $string = preg_replace('#https://facebook.com/(.*?)#i', '<div class="fb-post" data-href="\1" max-width="90%"></div>', $fb_links[0]);
    return $string;
}
  • Note that wp_extract_urls() returns an array of urls, Also this snippet overrides the whole post content $content. – birgire Jan 21 '17 at 10:25
  • Thanks for the tip, i edited the code. Based on our conversation in chat i assumed that his posts are only containing a facebook url. – Jack Johansson Jan 21 '17 at 11:24
  • Tested this. Each link now displays in every post as a printed link instead of an embed whether it is facebook.com or twitter.com etc. Screenshot: awesomescreenshot.com/01c687fkcd – Adam Jan 21 '17 at 14:01

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.