Scroll to top
© 2018, Titus Kipruto

How to Add Medium-Like Select and Tweet to WordPress


admin - August 21, 2017 - 0 comments

In recent weeks, we’ve added the ability to select text on our blog and tweet it. If you haven’t stumbled across this feature already, give it a go right now. Cool, right? One of our front-end developers, Catalin Nita, put together this feature for our blog (thanks, Catalin!) and we thought we’d share it with you today so you can use it, too. So today I’m going to walk you through how to set it up and you can download the free plugin at the end of the post.

How it Works

If you read posts over at Medium, you would be familiar with this handy bit of functionality, which makes it easy for readers to highlight a string of words and share it immediately. Over at Medium, when you highlight text the page displays a toolbar that allows you to tweet or comment on the words you select.

The select and tweet feature provides a neat way for your readers to share your quotable quotes.
The select and tweet feature provides a neat way for your readers to share your quotable quotes.

The feature on our site works in a similar way. When you double-click a word or highlight a few words, a small Twitter icon is displayed. When you click the icon, a tweet modal will automatically launch, containing the text you selected along with a link to the post.

We’ve designed this feature so the icon is shown above the highlighted text, making is less obtrusive for readers. After all, we don’t want to block any text you want to read.

Adding “Select and Tweet” to Your WordPress Site

The easiest way to add it to your site is to scroll to the bottom of the article and download the plugin as-is. You can install it, activate it and get going right away. Note that the plugin uses standard WordPress classes and will only work on single post pages. Your theme should use standard class names but if it doesn’t, the plugin likely will not work. If you’d like to learn how to build this feature then read on, we’ll be coding the plugin from scratch in the rest of this tutorial.

Creating an Empty Plugin

Create a folder named “select-and-tweet” in your plugins folder and place an empty file in it named “select-and-tweet.php.” Within that file, paste the following content – feel free to tweak it to your needs.

@font-face {
font-family: “t”;
src:url(“fonts/t.eot”);
src:url(“fonts/t.eot?#iefix”) format(“embedded-opentype”),
url(“fonts/t.woff”) format(“woff”),
url(“fonts/t.ttf”) format(“truetype”),
url(“fonts/t.svg#t”) format(“svg”);
font-weight: normal;
font-style: normal;

}

[data-icon]:before {
font-family: “t” !important;
content: attr(data-icon);
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

[class^=”icon-“]:before,
[class*=” icon-“]:before {
font-family: “t” !important;
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-social-twitter:before {
content: “t”;
}

@keyframes twtfade {
0% { @include opacity(0); }
100% { @include opacity(100); }
}
@-webkit-keyframes twtfade {
0% { @include opacity(0); }
100% { @include opacity(100); }
}

/* button body */
.twtshare {
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
margin-left: -35px;
background: #14485f;
color: #FFF;
width: 70px;
height: 35px;
display: block;
-webkit-animation-name: twtfade;
animation-name: twtfade;
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
cursor: pointer;
text-decoration: none;
}

/* button bottom arrow */
.twtshare:after {
margin-top: 0;
margin-left: -7px;
left: 50%;
position: absolute;
content: ”;
width: 0;
height: 0;
border-style: solid;
border-width: 8px 7.5px 0 7.5px;
border-color: #14485f transparent transparent transparent;
-moz-transition: border-color 0.3s;
-webkit-transition: border-color 0.3s;
-o-transition: border-color 0.3s;
-ms-transition: border-color 0.3s;
transition: border-color 0.3s;
}

/* button icon */
.twtshare:before {
display: block;
width: 70px;
height: 35px;
line-height: 39px;
font-size: 18px;
text-align: center;
}

view rawstyles.css hosted with ❤ by GitHub

Adding Our Assets

All we really need to do is enqueue a few assets in our main PHP file. We’ll be using a font face for the Twitter icon, a CSS file and a Javascript file. Create the following files in your plugin’s directory:

  • select-and-tweet.css
  • select-and-tweet.js

Once done, download this file and extract it within your plugin’s directory. This should result in a fonts directory with four files in it. Before we add any content to our CSS and JS files let’s enqueue them. In the select-and-tweet.php file paste the following code:

function sat_enqueue_assets() {
if ( is_single() ) {
wp_enqueue_style( ‘select-and-tweet’, plugins_url( ‘/select-and-tweet.css’, __FILE__ ) );
wp_enqueue_script( ‘select-and-tweet’, plugins_url( ‘/select-and-tweet.js’, __FILE__ ), array( ‘jquery’ ), ‘1.0’, true );
}
}

add_action( ‘wp_enqueue_scripts’, ‘sat_enqueue_assets’ );

view rawenqueues.php hosted with ❤ by GitHub

Note that since our JavaScript will use jQuery, I’ve made sure it will be loaded by adding it to the third parameter. I’ve also added true as the fifth parameter to make sure the script is loaded in the footer (it isn’t needed before that).

Figuring Out the Javascript

Essentially, we want to show a button – positioned correctly – when the user selects some text. A select process starts with a mousedown event (the user presses down on the mouse button) and ends with a mouseup event (the user releases the button). We want to make sure it wasn’t a right-click – in which case the default browser menu should be shown – and that at least three characters are selected. This prevents accidental slow double clicks or small selections. First, let’s write two helper functions we’ll rely on. One is for detecting if a click was a right-click, the other will return the selected text.

Here’s the full code for both, in addition to wrapping it all in a document ready call. All the Javascript code should be placed within:

jQuery(document).ready(function($) {function getRightClick(e) {
var rightclick;
if (!e) var e = window.event;
if (e.which) rightclick = (e.which == 3);
else if (e.button) rightclick = (e.button == 2);
return rightclick; // true or false
}

function getSelectionText() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return text;
}

});

view rawfunctions.js hosted with ❤ by GitHub

With that all done, it’s time to add some things to our two events: the mouseup and mousedown. Here’s the full code, including the excellent inline documentation added by Catalin:

// actions when the user starts the selection $('.entry-content').mousedown(function (event) { // take the position of the mouse where the user starts the selection // we need this for showing the share button in the middle of the selection $('body').attr('mouse-top',event.clientY+window.pageYOffset); //-> sets up the top value as attribute on body tag. $('body').attr('mouse-left',event.clientX); //-> sets up the left value as attribute on body tag.// remove share button and the old selection - ! Just if the user clicks the left button of the mouse. For right click we must show the genuine browser menu.
if(!getRightClick(event) && getSelectionText().length > 0) {
$('.twtshare').remove(); //-> remove share button
document.getSelection().removeAllRanges(); //-> remove old selection
}
});

// actions when the user ends the selection
$('.entry-content').mouseup(function (event) {

var t = $(event.target);
var st = getSelectionText();

// go further just if user click is left mouse click and the selection length is grater than 3 characters
if(st.length > 3 && !getRightClick(event)) {

// get the mouse top position when the selection ends
mts = $('body').attr('mouse-top');
mte = event.clientY+window.pageYOffset;
if(parseInt(mts) < parseInt(mte)) mt = mts;
else mt = mte;

// get left mouse position when the selection ends
mlp = $('body').attr('mouse-left');
mrp = event.clientX;
ml = parseInt(mlp)+(parseInt(mrp)-parseInt(mlp))/2;

// create the sharing link parameter that will be pass to twitter
sl = window.location.href.split('?')[0];

// cut the selection to a maximum of 107 - twitter accepts ~120 chars but we have some other info to display, like the account name
maxl = 107;
st = st.substring(0,maxl);

// create the sharing button
$('body').append("");

// show link on calculated position (top of selection and middle of it horizontaly)
$('.twtshare').css({
position: 'absolute',
top: parseInt(mt)-60,
left: parseInt(ml)
});
}
});

view rawactions.js hosted with ❤ by GitHub

Note that both events are tied to the .entry-content class. The idea is that users will share from our post, not from the sidebar, header and other places since it would just be confusing. This keeps everything within the post area.

The mousedown event is more straightforward. The first two lines serve to finds the position of the start of the selection. This value will be used to position the button later on. The second but within this action is to remove the share button, which uses the twtshare class.

The main part of the mouseup event is skipped if the length of the selected text is less than or equal to 3 characters (or if we detected a right-click). If all goes well, we grab the top and left position of the end of the selection. Based on this information, together with the position of the starting point, we can calculate the centered position of the button.

The next step is to grab the URL we’ll pass to Twitter. By adding .split[0] at the end we remove all query strings as these are usually unwanted. If you want to keep them or add your own tracking parameters you could do so here.

Next, the string shared is cut down to a maximum of 107 characters. You’ll likely want to add some other text like an account name at the end and of course the link. If you want to add your account then add something like st = st + ' @danielpataki'; after the string has been shortened to 107 characters.

The sharing button is created (appended to the body) using a simple link with the class .twtshare. Finally, it is positioned using the values we figured out before.

Styling the Button

The stylesheet is short and sweet and contains the font face declaration, some rules for handling the icon, the basic styles for the .twtshare class and a few lines for the animation. It is very much self-explanatory. Here’s the full code:

@charset "UTF-8";@font-face {
font-family: "t";
src:url("fonts/t.eot");
src:url("fonts/t.eot?#iefix") format("embedded-opentype"),
url("fonts/t.woff") format("woff"),
url("fonts/t.ttf") format("truetype"),
url("fonts/t.svg#t") format("svg");
font-weight: normal;
font-style: normal;

}

[data-icon]:before {
font-family: "t" !important;
content: attr(data-icon);
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

[class^="icon-"]:before,
[class*=" icon-"]:before {
font-family: "t" !important;
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-social-twitter:before {
content: "t";
}

@keyframes twtfade {
0% { @include opacity(0); }
100% { @include opacity(100); }
}
@-webkit-keyframes twtfade {
0% { @include opacity(0); }
100% { @include opacity(100); }
}

/* button body */
.twtshare {
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
margin-left: -35px;
background: #14485f;
color: #FFF;
width: 70px;
height: 35px;
display: block;
-webkit-animation-name: twtfade;
animation-name: twtfade;
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
cursor: pointer;
text-decoration: none;
}

/* button bottom arrow */
.twtshare:after {
margin-top: 0;
margin-left: -7px;
left: 50%;
position: absolute;
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 8px 7.5px 0 7.5px;
border-color: #14485f transparent transparent transparent;
-moz-transition: border-color 0.3s;
-webkit-transition: border-color 0.3s;
-o-transition: border-color 0.3s;
-ms-transition: border-color 0.3s;
transition: border-color 0.3s;
}

/* button icon */
.twtshare:before {
display: block;
width: 70px;
height: 35px;
line-height: 39px;
font-size: 18px;
text-align: center;
}

view rawstyles.css hosted with ❤ by GitHub

Download the Free Select and Tweet Plugin

That’s it! You should have the button working on your website. As you can see, implementing something useful doesn’t have to be over complicated. A few simple JavaScript lines and a dash of CSS is all you need to create something great.

If you’d like to try the plugin without writing all that code yourself, here’s the plugin zip file for you to install and activate.

Happy selecting and tweeting to all of you, and thanks again to Catalin for creating this awesome feature!

Post a Comment

Your email address will not be published. Required fields are marked *