Click to Tweet

A click to tweet box with a quotable quote make a blog post zing far more than just text alone.

I’ve created a “click to tweet” block for my latest theme. This post is about how to create a simple plugin with a click to tweet Gutenberg block and shortcode- skip to the end if just want the plugin, it’ll cost you a $1.50, less than a cup of coffee.

WordPress Gutenberg blocks are JS based so the first thing you need to do is correctly enqueue your Javascript file that contains the block. That happens during the action “enqueue_block_editor_assets”

<?php

/*

Plugin Name: Quotable Quotes
Plugin URI: http://www.themoyles.co.uk/
Description: Provides a tweetable box for your quotable quotes
Version: 0.1
Author: Andy Moyle
Author URI:http://www.themoyles.co.uk

License:
----------------------------------------

    
Copyright (C) 2020 Andy Moyle
No rights reserved - use it wherever!

----------------------------------------
*/
/***********************************************
*
* Enqueue the block's assets for the editor.
*
************************************************/
add_action( 'enqueue_block_editor_assets', 'quotable_quotes_block_assets' );
function quotable_quotes_block_assets() {
	// Scripts.
	wp_enqueue_script(
		'church_admin_theme_block', // Handle.
		 plugins_url( '/block.js', __FILE__ ), // Block.js: We register the block here.
		array( 'wp-blocks', 'wp-editor', 'wp-element','wp-components'), // Dependencies, defined above.
		1 
	);
}

Next I want to enqueue some simple styling – in this case there is so little that I want to just put it inline, rather than slow the site down with yet another file. We need the styles both front end and in the admin area for when we are creating a post/page.

add_action('wp_head', 'quotable_quotes_style', 100);
add_action('admin_head', 'quotable_quotes_style', 100);
function quotable_quotes_style()
{                           
    echo'<style>/***  Quotable Quote  ****/
.click-to-tweet,.wp-block-quotable-quote-click-to-tweet{position:relative;padding:40px!important;margin:1.25rem;border:1px solid #ccc;border-radius:.25rem;font-style:italic;background:#f5f8fa}.click-to-tweet-link a,.wp-block-quotable-quote-click-to-tweet-link a{color:#657786!important}.click-to-tweet-link span,.wp-block-quotable-quote-click-to-tweet-link span{color:#657786!important}.click-to-tweet-link,.wp-block-quotable-quote-click-to-tweet-link{display:block;position:absolute;right:10px;bottom:10px;font-size:smaller}a.img{color:#1da1f2}/***  End Quotable Quote  ****/</style>';
} 

The actual markup for the click to tweet block is super simple

<div class="wp-block-church-admin-theme-click-to-tweet"><a href="https://twitter.com/intent/tweet?text=A%20click%20to%20tweet%20box%20with%20a%20quotable%20quote%20make%20a%20blog%20post%20zing%20far%20more%20than%20just%20text%20alone.&amp;url=https%3A%2F%2Fwww.churchadminplugin.com&amp;via=TheMoyle">A click to tweet box with a quotable quote make a blog post zing far more than just text alone.</a><a class="wp-block-church-admin-theme-click-to-tweet-link" href="https://twitter.com/intent/tweet?text=A%20click%20to%20tweet%20box%20with%20a%20quotable%20quote%20make%20a%20blog%20post%20zing%20far%20more%20than%20just%20text%20alone.&amp;url=https%3A%2F%2Fwww.churchadminplugin.com&amp;via=TheMoyle"><span>Click to Tweet</span><i class="fab fa-twitter"></i></a></div>

We will need to be able to change the quote, the twitter handle and add the URL of the page/post where the click to tweet box is located. So firstly we will create a shortcode [quotable-quote quote=”” handle=”” url==””] If the url is omitted it will just pick up the permalink.

/***********************************************
*
* Shortcode
*
************************************************/
add_shortcode('quotable-quote','quotable_quotes_shortcode');
function quotable_quotes_shortcode()
{
    extract(shortcode_atts(array('quote'=>'Quote me','handle'=>'','url'=>get_permalink())));
    $link='https://twitter.com/intent/tweet?text='.urlencode($quote).'%2F%3Futm_source%3Dtwitter%26utm_medium%3Dwebsite%26utm_campaign%3Dclick-to-tweet&amp;url='.urlencode($url).'&amp;via='.$handle;
    $out='<div class="click-to-tweet"><a href="'.$link.'">'.$quote.'</a><a href="'.$link.'" class="click-to-tweet-link"><span>Click to Tweet</span> <img alt="Tweet" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMzUgMjc2IiBmaWxsPSIjM2JhOWVlIj4KICA8cGF0aCBkPSJtMzAyIDcwYTE5NSAxOTUgMCAwIDEgLTI5OSAxNzUgMTQyIDE0MiAwIDAgMCA5NyAtMzAgNzAgNzAgMCAwIDEgLTU4IC00NyA3MCA3MCAwIDAgMCAzMSAtMiA3MCA3MCAwIDAgMSAtNTcgLTY2IDcwIDcwIDAgMCAwIDI4IDUgNzAgNzAgMCAwIDEgLTE4IC05MCAxOTUgMTk1IDAgMCAwIDE0MSA3MiA2NyA2NyAwIDAgMSAxMTYgLTYyIDExNyAxMTcgMCAwIDAgNDMgLTE3IDY1IDY1IDAgMCAxIC0zMSAzOCAxMTcgMTE3IDAgMCAwIDM5IC0xMSA2NSA2NSAwIDAgMSAtMzIgMzUiLz4KPC9zdmc+Cg==" /></a></div>';
    return $out;
}

Next we need to create our block.js file.

( function( blocks, editor, element , components) {

	const el = element.createElement;
    
	//const { RichText } = editor;
	const { registerBlockType } = blocks;
   	const { TextControl, ToggleControl, Panel, PanelBody, PanelRow } = components;

	
    

	registerBlockType( 'quotable-quote/click-to-tweet', {
		title: 'Quotable Quote',
		icon: 'twitter',
		category: 'widgets',
		keywords: [ 'tweet', 'twitter' ],
        attributes:{
                quote:{
                    type:'string',
                        default:'Quote me'
                },
                handle:{
                    type:'string',
                        default:''
                }
            },
		// The edit function is what displays the block and sidebar in the admin area when add/editing a post or page 
		
 
        edit: function( props ) {

        return (
            el( Fragment, {},
                el( InspectorControls, {},
                    el( PanelBody, { title: 'Click to Tweet', initialOpen: true },

                        /* Text Field */
                        el( PanelRow, {},
                            el( TextControl,
                                {
                                    label: 'Quote',
                                    onChange: ( value ) => {
                                        props.setAttributes( { quote: value } );
                                    },
                                    value: props.attributes.quote
                                }
                            )
                        ),
                        /* Text Field */
                        el( PanelRow, {},
                            el( TextControl,
                                {
                                    label: 'Twitter handle',
                                    onChange: ( value ) => {
                                        props.setAttributes( { handle: value } );
                                    },
                                    value: props.attributes.handle
                                }
                            )
                        ),
                       

                    ),

                ),

                /*  
                 * Here will be your block markup 
                 */
               
            el( 'div', { className: props.className },
                    el(
                        'a',
                        {href:'https://twitter.com/intent/tweet?text=' + encodeURIComponent(props.attributes.quote)+'&url='+encodeURIComponent(props.attributes.tweetedurl)+'&via='+encodeURIComponent(props.attributes.handle)},
                        props.attributes.quote
                    ),
                    el('a',
                       {className:'wp-block-church-admin-theme-click-to-tweet-link',href:'https://twitter.com/intent/tweet?text=' + encodeURIComponent(props.attributes.quote)+'&url='+encodeURIComponent(props.attributes.tweetedurl)+'&via='+encodeURIComponent(props.attributes.handle)},
                        [   el('span',{},'Click to Tweet '),
                            el('img',{src:'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMzUgMjc2IiBmaWxsPSIjM2JhOWVlIj4KICA8cGF0aCBkPSJtMzAyIDcwYTE5NSAxOTUgMCAwIDEgLTI5OSAxNzUgMTQyIDE0MiAwIDAgMCA5NyAtMzAgNzAgNzAgMCAwIDEgLTU4IC00NyA3MCA3MCAwIDAgMCAzMSAtMiA3MCA3MCAwIDAgMSAtNTcgLTY2IDcwIDcwIDAgMCAwIDI4IDUgNzAgNzAgMCAwIDEgLTE4IC05MCAxOTUgMTk1IDAgMCAwIDE0MSA3MiA2NyA2NyAwIDAgMSAxMTYgLTYyIDExNyAxMTcgMCAwIDAgNDMgLTE3IDY1IDY1IDAgMCAxIC0zMSAzOCAxMTcgMTE3IDAgMCAwIDM5IC0xMSA2NSA2NSAwIDAgMSAtMzIgMzUiLz4KPC9zdmc+Cg==',width:20,height:20})
                        ]
                      )
                )
            ) 
        )

    },

		save: function( props ) {
            
            return (
                
                el( 'div', { className: props.className },
                    el(
                        'a',
                        {href:'https://twitter.com/intent/tweet?text=' + encodeURIComponent(props.attributes.quote)+'&url='+encodeURIComponent(wp.data.select('core/editor').getPermalink())+'&via='+encodeURIComponent(props.attributes.handle)},
                        props.attributes.quote
                    ),
                    el('a',
                       {className:'wp-block-church-admin-theme-click-to-tweet-link',href:'https://twitter.com/intent/tweet?text=' + encodeURIComponent(props.attributes.quote)+'&url='+encodeURIComponent(wp.data.select('core/editor').getPermalink())+'&via='+encodeURIComponent(props.attributes.handle)},
                        [   el('span',{},'Click to Tweet'),
                            el('i',{className:'fab fa-twitter'},'')
                        ]
                      )
                )
           );
        }
    })
})(
	window.wp.blocks,
    window.wp.editor,
	window.wp.element,
    window.wp.components
);

The bit that took me longest to work out was automatically adding the permalink of the post or page, which is accessed from wp.data.select(‘core/editor’).getPermalink()

Rather neatly it starts as a domain/?p=# link to the post and then one saving or publishing uses the nice permalink. Impressive!