divyenduz divyenduz - 1 month ago 10x
PHP Question

WordPress hook / filter to process link inside a post

Is there a hook / filter to process the link being added into a WordPress post ?

My aim is to pre-process the link inserted in a post using the following button and shorten it using a third party API like bit.ly

I want to do this for both internal / external links.

TinyMCE add link button

One solution that I an think of is to add an extra button to my editor that does this but I would prefer a hook / filter that does the job, that way it would be more clean and I will convert that into a custom plugin for my website (there by allowing my WordPress to be up-gradable).

I went through the WordPress docs and skimmed through the following hooks / filters which were of no use to me

  1. https://developer.wordpress.org/reference/hooks/add_link/

  2. https://developer.wordpress.org/reference/hooks/post_link/

  3. And most of the ones listed here


Update 1: As far as I know, external URLs are inserted into post content by TinyMCE editor link plugin, PHP do nothing.

In WordPress, there're two plugins which located at wp-includes/js/wplink.js and wp-includes/js/tinymce/plugins/wplink/plugin.js. Note that if you're not in SCRIPT_DEBUG mode, they have .min suffix.

  1. wp-includes/js/wplink.js handles this dialog:

wplink dialog box 1

To filter URLs which are inserted via this dialog box, we must override wpLink.getAttrs method. For example, to add so39115564 string to every URLs:

jQuery(document).ready(function($) {
  wpLink.getAttrs = function() {
    return {
      href: $.trim( $("#wp-link-url").val() + "so39115564" ),
      target: $("#wp-link-target").prop("checked") ? "_blank" : ""

You should take a look at the wp-includes/js/wplink.js for more info. It may be too long to explain in detail here.

And let say the above script is mylink.js, here is how we should enqueue it:

add_filter('admin_enqueue_scripts', function()
  // { Maybe some conditions for a valid screen here. }

  wp_enqueue_script('mylink', 'link/to/the/mylink.js', ['link'], '1.0', true);
}, 0, 0);
  1. wp-includes/js/tinymce/plugins/wplink/plugin.js handles this dialog:

wplink dialog 2

This time, we also have to override setURL method of tinymce.ui.WPLinkPreview. But, it's almost impossible, unless you deregister this script and register a modified version. Then manage that script yourself with unpredictable changes inside WordPress.

Now, choose it wisely! Shorten any external URLs before pasting them into your posts or mess up with WordPress TinyMCE plugins or use dialog box of wp-includes/js/wplink.js plugin.

Yes! WordPress inserts inline links via wp_link_ajax action which is executed by wp_ajax_wp_link_ajax() function.

As you can see in source code of that function, $results is retrieved by _WP_Editors::wp_link_query. Check out this method, you will meet wp_link_query filter. This filter accept two arguments: $results and $query. $results will be what we need to filter.

For example, we need to append so39115564 to the queried link:

add_filter('wp_link_query', function(array $results, array $query)
  $results[0]['permalink'] = $results[0]['permalink'] . 'so39115564';

  return $results;
}, PHP_INT_MAX, 2);

Now, you should know how to do it. Make sure to take a look at _WP_Editors::wp_link_query to filter the $results more efficient.