Automattic / liveblog

Liveblogging done right. Using WordPress.
https://wordpress.org/plugins/liveblog/
308 stars 122 forks source link

Social sharing of individual updates #387

Open paulschreiber opened 6 years ago

paulschreiber commented 6 years ago

See related #386.

We would like to have social sharing work for individual updates. To make this work, you need several components:

paulschreiber commented 6 years ago

Button markup is shown in #386.

Here's some JavaScript to trigger the buttons. Once titles/headlines are added (#375), this should be reworked. Similarly, when updates are rewritten to use WP posts instead of comments (#377), it can be reworked.

This code does not attempt to fetch an image. Strategy: parse it out of the HTML on the server side and story the image URL in a data attribute.

jQuery( document ).ready( function( $ ) {
    'use strict';

    // method to determine if this page has a live blog on it
    if ( 1 !== $( '.fte_liveblog-template-default' ).length ) {
        return;
    }

    $( document ).on( 'click', '.share-facebook', function( event ) {
        var story = event.currentTarget.parentElement.parentElement,
            postLink = story.querySelector( '.liveblog-meta-time' ).getAttribute( 'href' ),
            postId = event.currentTarget.parentElement.getAttribute( 'id' ),
            updateId = event.currentTarget.parentElement.getAttribute( 'data-update-id' ),
            left = ( screen.width / 2 ) - 300,
            top = ( screen.height / 2 ) - 175,
            options = 'width=600,height=350,location=yes,status=yes,top=' + top + ', left=' + left,
            description = story.querySelector( '.liveblog-entry-content' ).innerText.trim(),
            shareUrl;

        event.preventDefault();

        postLink = postLink.replace( '#', '?lbup=' + updateId + '#' );
        shareUrl = 'https://www.facebook.com/sharer.php?u=' + encodeURIComponent( postLink );

        window.open( shareUrl, postId, options );

        return false;
    });

    $( document ).on( 'click', '.share-twitter', function( event ) {
        var story = event.currentTarget.parentElement.parentElement,
            postLink = story.querySelector( '.liveblog-meta-time' ).getAttribute( 'href' ),
            postId = event.currentTarget.parentElement.getAttribute( 'id' ),
            left = ( screen.width / 2 ) - 300,
            top = ( screen.height / 2 ) - 175,
            options = 'width=600,height=350,location=yes,status=yes,top=' + top + ', left=' + left,
            description = story.querySelector( '.liveblog-entry-content' ).innerText.trim(),
            shareUrl;

        event.preventDefault();

        // truncate post
        if ( description.length > ( 280 - postLink.length - 2 ) ) {
            description = description.substr( 0, 280 - postLink.length - 3 ) + '…';
        }

        shareUrl = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent( description + ' ' + postLink );

        window.open( shareUrl, postId, options );

        return false;
    });

});
paulschreiber commented 6 years ago

Here is code to add an endpoint for the Facebook crawler:

add_action( 'template_redirect', [ __CLASS__, 'liveblog_facebook_share' ] );
add_filter( 'query_vars', [ __CLASS__, 'liveblog_query_vars' ] );
/**
 * Allow lbup as a query variable
 *
 * @param $query_vars array
 * @return array
 */
public static function liveblog_query_vars( $query_vars ) {
    $query_vars[] = 'lbup';
    return $query_vars;
}

public static function liveblog_facebook_share() {
    global $wp_query;
    if ( ! WPCOM_Liveblog::is_liveblog_post() || ! isset( $wp_query->query['lbup'] ) ) {
        return;
    }

    $update_id = intval( $wp_query->query['lbup'] );
    if ( ! $update_id ) {
        return;
    }

    // TODO: ensure $update_id is a valid comment ID before proceeding

    set_query_var( 'update_id', $update_id );
    get_template_part( 'template-parts/liveblog-share-facebook' );
    exit();
}
<?php
the_post();
$comment_text = wp_strip_all_tags( get_comment_text( $update_id ) );
$description = substr( $comment_text, 155 );
$title = get_the_title();
$url = get_the_permalink();
$fb_app_id = 12345;
$image_url = get_the_post_thumbnail_url( null, 'full' );

?>
<!DOCTYPE html>
<html>
<head prefix="og: http://ogp.me/ns#">
<link rel="canonical" href="<?php echo esc_url( $url ); ?>">
<title><?php echo esc_html( $title ); ?></title>
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="<?php echo esc_attr( $title ); ?>" />
<meta name="twitter:description" content="<?php echo esc_attr( $description ); ?>" />
<meta name="twitter:image" content="<?php echo esc_url( $image_url ); ?>" />
<meta name="twitter:url" content="<?php echo esc_url( $url ); ?>" />
<meta property="og:title" content="<?php echo esc_attr( $title ); ?>" />
<meta property="og:type" content="article" />
<meta property="og:url" content="<?php echo esc_url( $url ); ?>" />
<meta property="og:image" content="<?php echo esc_url( $image_url ); ?>" />
<meta property="og:site_name" content="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" />
<meta property="og:description" content="<?php echo esc_attr( $description ); ?>" />
<meta property="fb:app_id" content="<?php echo esc_attr( $fb_app_id ); ?>" />
<meta http-equiv="refresh" content="<?php echo esc_url( '2;URL=' . $url ); ?>">
<script type="text/javascript">window.location.replace('<?php echo esc_url( $url ); ?>');</script>
</head>
    <body>
        <p><?php echo wp_kses_post( $description ); ?></p>
    </body>
</html>

As with the above, it doesn't attempt to fetch an image from the update, and instead uses the main post's featured image.

cain commented 6 years ago

Thoughts on just adding social sharing to the core plugin?