Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save yaroslav-borodii/ba3b0065f48d561a5766ad52ca0ac40f to your computer and use it in GitHub Desktop.
Save yaroslav-borodii/ba3b0065f48d561a5766ad52ca0ac40f to your computer and use it in GitHub Desktop.
Add a link style to the WordPress link editor
<?php
/**
* Add a link style to the WordPress link editor
*
*/
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 select.
if ( tinymce.$('#link-options').length ) {
<?php
$acf_buttons = get_field( 'buttons', 'options' );
$button_styles = '<option value="default">Default</option>';
foreach ( $acf_buttons as $button ) {
$button_styles .= sprintf(
'<option value="%s">%s</option>',
sanitize_key( $button['name'] ),
$button['name']
);
}
?>
// Append our checkbox HTML to the #link-options div, which is already present in the DOM.
tinymce.$('#link-options').append(<?php echo wp_json_encode( '<div class="link-style"><label><span>Link Style</span> <select id="wp-link-style">' . $button_styles . '</select></label></div>' ); ?>);
// Clone the original wpLink object so we retain access to some functions.
originalWpLink = _.clone( wpLink );
wpLink.addStyle = tinymce.$('#wp-link-style');
// 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.class = `button--${wpLink.addStyle.find('option:selected')[0]?.value || 'default'}`;
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.class ) {
html += ` class="${attrs.class}"`;
}
return html + '>';
},
/**
* Set the value of our select option based on the presence
* of the selected option.
*
* 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.addStyle.removeAttr('class')?.addClass( `button--${wpLink.addStyle.find('option:selected')[0]?.value || 'default'}` );
}
}
}
});
}
}
</script>
<style>
#wp-link-style {
margin-top: 5px;
}
</style>
<?php
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment