I'd really love to be able to conditionally apply a CSS class to link elements of images embedded into posts, but I can't seem to figure this one out.

Basically what I'd like to achieve is to replace the default embedded image link that links the image to the full size version of itself to opening it in a colorbox.

I know I can achieve this with a bit of Javascript-trickery, but I'd love to figure out how to do this in the server side and then just attach the colorbox functionality in a straightforward manner.

So, is there a filter I should add or what's the route to take here. Ideally I'd love to be able to write the code so that if a user embeds an image, the link opens the full size version in a colorbox but if the user specifies a custom link, it'll work like a regular link. This shouldn't be that hard.

Thanks a lot for any help in advance!

  • 2
    Run a filter on image_send_to_editor? – t31os Mar 11 '11 at 9:05
  • I'll add it as answer in that case, so other users will be able to see you found a solution more easily, and happy to have helped.. ;) – t31os Mar 11 '11 at 11:52
  • Thanks for that, I also posted my complete solution to the problem, but couldn't have gotten there without your help. :) – Tommi Forsström Mar 11 '11 at 12:04
  • Sorry for this possibly being a stupid question, but: 1. Is the proposed idea in this thread "replacing the automatically generated classes by Wordpress? on every attachment?" 2. Am I adding this to the functions.php? 3. Can this be targeted only on <img> or some conditional for different class names? Thanks for putting up with me but still eager for your replies. – user15305 Apr 18 '12 at 0:31

You can run a filter on image_send_to_editor, the filter runs inside the get_image_send_to_editor function which is resposible for sending the link HTML that surrounds images sent to the editor.

The filter can be found in core, in wp-admin/includes/media and is linked below for quick reference.


Thanks a LOT to user t31os for the tip on where to find my solution!

Also thanks to user orionrush for pointing out a dumb mistake I had made! :)

Here's how I got what I wanted:

function add_colorbox_class_to_image_links($html, $attachment_id, $attachment) {
    $linkptrn = "/<a[^>]*>/";
    $found = preg_match($linkptrn, $html, $a_elem);

    // If no link, do nothing
    if($found <= 0) return $html;

    $a_elem = $a_elem[0];

    // Check to see if the link is to an uploaded image
    $is_attachment_link = strstr($a_elem, "wp-content/uploads/");

    // If link is to external resource, do nothing
    if($is_attachment_link === FALSE) return $html;

    if(strstr($a_elem, "class=\"") !== FALSE){ // If link already has class defined inject it to attribute
        $a_elem_new = str_replace("class=\"", "class=\"colorbox ", $a_elem);
        $html = str_replace($a_elem, $a_elem_new, $html);
    }else{ // If no class defined, just add class attribute
        $html = str_replace("<a ", "<a class=\"colorbox\" ", $html);

    return $html;

add_filter('image_send_to_editor', 'add_colorbox_class_to_image_links', 10, 3);
  • 3
    For others using this solution, be aware that this as this filter runs at the time you add an image. This won't retroactively add your class to images in posts you've already created. Hat-tip @Baltar - wordpress.stackexchange.com/questions/112308/… – Jay Neely Nov 17 '14 at 20:47

(Posting this answer because this question shows up on Google and I couldn't find what I wanted through Google.)

Brief Explanation and Example

After retrieving the post from the data base, this will put all of the specified classes into the anchor tag whenever there is an anchor tag with only an image tag inside of it.

It works with many image tags in one post, as well as a variety of other weird possibilities. For instance, something like this

    <a href="an_image.jpg">
        <img src="an_image.jpg">
    <a class="media-img" href="another_image.jpg">
        <img src="another_image.jpg">
    <p>Text with a <a href="google.com">link</a></p>
    <a class="big gray ugly" href="third_image.jpg">
        <img src="third_image.jpg">
    <a foo="bar" class="big" href="fourth_image.jpg">
        <img src="fourth_image.jpg">

will become

    <a class="media-img" href="an_image.jpg">
        <img src="an_image.jpg">
    <a class="media-img media-img" href="another_image.jpg">
        <img src="another_image.jpg">
    <p>Text with a <a href="google.com">link</a></p>
    <a class="media-img big gray ugly" href="third_image.jpg">
        <img src="third_image.jpg">
    <a foo="bar" class="media-img big" href="fourth_image.jpg">
        <img src="fourth_image.jpg">

Code (for functions.php)

function add_classes_to_linked_images($html) {
    $classes = 'media-img'; // can do multiple classes, separate with space

    $patterns = array();
    $replacements = array();

    $patterns[0] = '/<a(?![^>]*class)([^>]*)>\s*<img([^>]*)>\s*<\/a>/'; // matches img tag wrapped in anchor tag where anchor tag where anchor has no existing classes
    $replacements[0] = '<a\1 class="' . $classes . '"><img\3></a>';

    $patterns[1] = '/<a([^>]*)class="([^"]*)"([^>]*)>\s*<img([^>]*)>\s*<\/a>/'; // matches img tag wrapped in anchor tag where anchor has existing classes contained in double quotes
    $replacements[1] = '<a\1class="' . $classes . ' \2"\3><img\4></a>';

    $patterns[2] = '/<a([^>]*)class=\'([^\']*)\'([^>]*)>\s*<img([^>]*)>\s*<\/a>/'; // matches img tag wrapped in anchor tag where anchor has existing classes contained in single quotes
    $replacements[2] = '<a\1class="' . $classes . ' \2"\3><img\4></a>';

    $html = preg_replace($patterns, $replacements, $html);

    return $html;

add_filter('the_content', 'add_classes_to_linked_images', 100, 1);

Other Notes

  • In the first regular expression pattern, (?![^>]*class) is a negative lookahead so that the first regex replace rule only affects <a href...><img></a>, not <a class... href...><img></a>. (Read more on lookarounds.)
  • In regular expressions for this, I think [^>]* is better than .*. [^>]* means zero or more characters that are not a >. Without [^>]*, I think there could be problems if there are multiple > characters on one line or in other weird situations.
  • In the regular expressions, the backslash followed by a number in the replacements such as in '<a\1 class="' . $classes . '"><img\3></a>' refers to the stuff inside corresponding parenthetical block in the corresponding pattern. In other words, \1 means "put the stuff that matches what's inside the first set of parentheses".
  • In the line add_filter('the_content', 'add_classes_to_linked_images', 100, 1);, the first parameter is the filter for getting the content of a post from the database, the second parameter is the name of the function we want to use, the third parameter is the priority of the filter (higher numbers get executed later), and the fourth parameter is the number of arguments for the filter.
  • Assuming your anchor and image combination already has the class you want to add, this function will cause it to show up twice in the source code of your page. (Don't worry, it will only show up twice at most and it won't cause any issues. See example above.)

Someone correct me if im wrong here, but the above gives me warnings on $astart - I believe these lines:

   if(strstr($astart, "class=\"") !== FALSE){ // If link already has class defined inject it to attribute
    $a_elem_new = str_replace("class=\"", "class=\"colorbox ", $astart);

should be:

if(strstr($a_elem, "class=\"") !== FALSE){ // If link already has class defined inject it to attribute
    $a_elem_new = str_replace("class=\"", "class=\"colorbox ", $a_elem);

but I may not be reading it correctly. . .

also we could dynamically add the uploads folder rather then hardcode it:

    $uploads = wp_upload_dir();
$upload_path = basename($uploads['baseurl']); // dosen't account for multi site - not sure how to do that. . .
$is_attachment_link = strstr($a_elem, $upload_path);

could probably substitute wp_basename but not sure of the advantages...

  • 1
    You're absolutely right. Don't know what sort of brainfreeze caused me to do that. I'll edit my answer and upvoted your answer. – Tommi Forsström Apr 4 '12 at 14:53
  • Brilliant - I've been working on this for a few hours now trying to deconstruct what you've done. – orionrush Apr 4 '12 at 15:30
  • added an idea to the uploads folder. . . – orionrush Apr 4 '12 at 15:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.