0

I have the following function within a simple plugin:

<?php
/**
 * Social buttons
 */
function zss_social_buttons() {
?>
    <div class="zss">
        <!-- Facebook -->
        <div id="fb-root"></div>
        <script>
            (function(d, s, id) {
                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id)) return;
                js = d.createElement(s); js.id = id;
                js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.0";
                fjs.parentNode.insertBefore(js, fjs);
            }
            (document, 'script', 'facebook-jssdk'));
        </script>
        <div class="fb-share-button" data-href="<?php the_permalink(); ?>" data-layout="button_count" data-lazy="true">
        </div>
        <!-- Twitter -->
        <a href="https://twitter.com/share?url=<?php the_permalink(); ?>&amp;text=<?php echo urlencode( get_the_title() ); ?>" title="Share on Twitter" target="_blank" rel="nofollow noopener noreferrer" class="zss-button zss-button--twitter">Twitter</a>
        <!-- LinkedIn -->
        <a class="zss-button zss-button--linkedin" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=<?php the_permalink(); ?>" title="Share on LinkedIn" target="_blank" rel="nofollow noopener noreferrer">LinkedIn</a>
        <!-- E-Mail -->
        <a class="zss-button zss-button--email" href="mailto:?subject=<?php the_title(); ?>&amp;body=<?php the_permalink(); ?>" title="Share by Email" target="_blank" rel="noopener">Email</a>
    </div>
<?php }

I'd like my social share buttons to appear underneath the_content() via each single post. To achieve this, I've built the following filter hook in the same plugin:

<?php
/**
 * Insert share button
 */ 
function zss_insert_share_buttons( $content ) {
    if ( is_singular() && in_the_loop() && is_main_query() ) {
        $social_share_buttons = zss_social_buttons();
        $content .= $social_share_buttons;
        return $content;
    }
    else {
        return $content;
    }
}
add_filter( 'the_content', 'zss_insert_share_buttons' );

For some reason, the zss_social_buttons() function loads before the_content();. What have I done wrong here?

2
  • 1
    zss_social_buttons() echo the output instead of returning it, hence it's not actually added to $content and instead the output is displayed immediately.
    – Sally CJ
    Apr 19, 2021 at 18:02
  • 1
    Thanks, @SallyCJ. Can you demonstrate this in an answer?
    – Sam
    Apr 19, 2021 at 19:55

1 Answer 1

1

The main issue in your code is caused by the call to zss_social_buttons() in your filter function:

// In zss_insert_share_buttons():

$social_share_buttons = zss_social_buttons(); // NULL
$content .= $social_share_buttons;

And the problem there is that zss_social_buttons() is echoing the sharing links/buttons instead of returning them, so they're not actually added to the $content variable. Instead, they're sent to the browser (or displayed) immediately when the function runs.

So that explains why the buttons appear before the post content. ( That's what you meant by "the zss_social_buttons() function loads before the_content();", right? )

Additionally, the Facebook script and including the <div id="fb-root"></div> should be added only once and not every time the filter the_content is applied. So for example, you can use the wp_body_open (action) hook to add the script right after the <body> tag:

add_action( 'wp_body_open', 'my_wp_body_open' );
function my_wp_body_open() {
    ?>
        <!-- Load Facebook SDK for JavaScript -->
        <div id="fb-root"></div>
        <script>put the script code here</script>
    <?php
}

And then, to fix the main issue, you can either:

  • Make the zss_social_buttons() function returns the output and not echoing it. Simplified example:

    <?php
    function zss_social_buttons() {
        return '<div class="zss">
            <!-- Facebook -->
            <div class="fb-share-button" data-href="' . esc_url( get_the_permalink() ) . '"' .
                ' data-layout="button_count" data-lazy="true"></div>
    
            ... your other buttons.
        </div>';
    }
    
  • Or you can use output buffering in the zss_insert_share_buttons() function:

    <?php
    function zss_social_buttons() {
        ?>
            <div class="zss">
                <!-- Facebook -->
                <div class="fb-share-button" data-href="<?php the_permalink(); ?>"
                    data-layout="button_count" data-lazy="true"></div>
    
                ... your other buttons.
            </div>
        <?php
    }
    
    function zss_insert_share_buttons( $content ) {
        if ( is_singular() && in_the_loop() && is_main_query() ) {
            ob_start();
    
            zss_social_buttons(); // echo the output, but send it to the buffer and
                                  // not the browser
    
            $content .= ob_get_clean(); // and then append the buffer to $content
        }
    
        return $content;
    }
    
1
  • 1
    Not only did you offer an excellent answer, but you improved my code. You're awesome, thank you.
    – Sam
    Apr 20, 2021 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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