Skip to content

Instantly share code, notes, and snippets.

@danielbachhuber
Created February 13, 2017 17:06
  • Star 10 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save danielbachhuber/4c5e0ce7b5ab6475a27e5389c93716ac to your computer and use it in GitHub Desktop.
Add a 'Add rel="nofollow" to link' checkbox to the WordPress link editor
<?php
/**
* Add a 'Add rel="nofollow" to link' checkbox to the WordPress link editor
*
* @see https://danielbachhuber.com/tip/rel-nofollow-link-modal/
*/
add_action( 'after_wp_tiny_mce', function(){
?>
<script>
var originalWpLink;
// Ensure both TinyMCE, underscores and wpLink are initialized
if ( typeof tinymce !== 'undefined' && typeof _ !== 'undefined' && typeof wpLink !== 'undefined' ) {
// Ensure the #link-options div is present, because it's where we're appending our checkbox.
if ( tinymce.$('#link-options').length ) {
// Append our checkbox HTML to the #link-options div, which is already present in the DOM.
tinymce.$('#link-options').append(<?php echo json_encode( '<div class="link-nofollow"><label><span></span><input type="checkbox" id="wp-link-nofollow" /> Add rel="nofollow" to link</label></div>' ); ?>);
// Clone the original wpLink object so we retain access to some functions.
originalWpLink = _.clone( wpLink );
wpLink.addRelNofollow = tinymce.$('#wp-link-nofollow');
// Override the original wpLink object to include our custom functions.
wpLink = _.extend( wpLink, {
/**
* Fetch attributes for the generated link based on
* the link editor form properties.
*
* In this case, we're calling the original getAttrs()
* function, and then including our own behavior.
*/
getAttrs: function() {
var attrs = originalWpLink.getAttrs();
attrs.rel = wpLink.addRelNofollow.prop( 'checked' ) ? 'nofollow' : false;
return attrs;
},
/**
* Build the link's HTML based on attrs when inserting
* into the text editor.
*
* In this case, we're completely overriding the existing
* function.
*/
buildHtml: function( attrs ) {
var html = '<a href="' + attrs.href + '"';
if ( attrs.target ) {
html += ' target="' + attrs.target + '"';
}
if ( attrs.rel ) {
html += ' rel="' + attrs.rel + '"';
}
return html + '>';
},
/**
* Set the value of our checkbox based on the presence
* of the rel='nofollow' link attribute.
*
* In this case, we're calling the original mceRefresh()
* function, then including our own behavior
*/
mceRefresh: function( searchStr, text ) {
originalWpLink.mceRefresh( searchStr, text );
var editor = window.tinymce.get( window.wpActiveEditor )
if ( typeof editor !== 'undefined' && ! editor.isHidden() ) {
var linkNode = editor.dom.getParent( editor.selection.getNode(), 'a[href]' );
if ( linkNode ) {
wpLink.addRelNofollow.prop( 'checked', 'nofollow' === editor.dom.getAttrib( linkNode, 'rel' ) );
}
}
}
});
}
}
</script>
<style>
#wp-link #link-options .link-nofollow {
padding: 3px 0 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#wp-link #link-options .link-nofollow label span {
width: 83px;
}
.has-text-field #wp-link .query-results {
top: 223px;
}
</style>
<?php
});
@runofthemill
Copy link

this is great! quick question - do you know of any documentation available for wplink.js, or did you just figure out how to use those methods by looking through the code?

@lgt
Copy link

lgt commented May 21, 2019

may I suggest to change https://gist.github.com/danielbachhuber/4c5e0ce7b5ab6475a27e5389c93716ac#file-add-rel-nofollow-checkbox-php-L32 to attrs.rel = wpLink.addRelNofollow.prop( 'checked' ) ? 'nofollow' : null;.
In that case you will not face the problem that on each link update not selecting nofollow to true would cause rel="false"

@jeanox
Copy link

jeanox commented Mar 22, 2021

Suggestion: https://gist.github.com/danielbachhuber/4c5e0ce7b5ab6475a27e5389c93716ac#file-add-rel-nofollow-checkbox-php-L66

Replace with
wpLink.addRelNofollow.prop( 'checked', editor.dom.getAttrib( linkNode, 'rel' ).includes('nofollow') );
to allow for the existence of other rel attributes (noopener).

@escael
Copy link

escael commented Jul 8, 2021

Hi,
could you also add the option of rel="sponsored"?
So that it results in something like this:
rel="nofollow sponsored"

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment