Add class to Wordpress image anchor elements

2020-07-18 07:29发布

问题:

I need to style the element that goes around images embedded in a post that don't have captions, but as far as I can tell there is no way to automatically add a class to it or target <a>s with an <img> inside only without using jQuery or something.

This is how they come out by default:

<a href="sample.jpg"><img class="alignnone size-full wp-image-20" src="sample.jpg" alt="Sample Image" width="1280" height="914"></a>

Is there a simple wordpress PHP method with which I can just set a simple ".img" class on all those elements by default?

Confused how this is not standard functionality in Wordpress, lots of people complaining about it but no actual solutions as far as I can see.

To clarify, this should work on existing images in posts, not just on future posts I make!

回答1:

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

<article>
    <a href="an_image.jpg">
        <img src="an_image.jpg">
    </a>
    <a class="media-img" href="another_image.jpg">
        <img src="another_image.jpg">
    </a>
    <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>
    <a foo="bar" class="big" href="fourth_image.jpg">
        <img src="fourth_image.jpg">
    </a>
</article>

will become

<article>
    <a class="media-img" href="an_image.jpg">
        <img src="an_image.jpg">
    </a>
    <a class="media-img media-img" href="another_image.jpg">
        <img src="another_image.jpg">
    </a>
    <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>
    <a foo="bar" class="media-img big" href="fourth_image.jpg">
        <img src="fourth_image.jpg">
    </a>
</article>


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 has no existing classes
    $replacements[0] = '<a\1 class="' . $classes . '"><img\2></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', 10, 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 are 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.)


回答2:

If you have the ability to edit your functions.php file, then add this code. It is tested and proven:

/**
 * Attach a class to linked images' parent anchors
 * Works for existing content
 */
function give_linked_images_class($content) {

  $classes = 'img'; // separate classes by spaces - 'img image-link'

  // check if there are already a class property assigned to the anchor
  if ( preg_match('/<a.*? class=".*?"><img/', $content) ) {
    // If there is, simply add the class
    $content = preg_replace('/(<a.*? class=".*?)(".*?><img)/', '$1 ' . $classes . '$2', $content);
  } else {
    // If there is not an existing class, create a class property
    $content = preg_replace('/(<a.*?)><img/', '$1 class="' . $classes . '" ><img', $content);
  }
  return $content;
}

add_filter('the_content','give_linked_images_class');


回答3:

My friend had the same problem when trying to add prettyPhoto rel's on his image, there are 1000's of links for this.

Try adding this into your functions.php file within your theme. Please also remember NEVER to edit the core files, no matter what anyone says.

This was originally for adding rel="prettyPhoto" within the <a> tags, try it now and remember to change class="newClassHere" to your class.

add_filter('wp_get_attachment_link', 'rc_add_rel_attribute');
function rc_add_rel_attribute($link) {
    global $post;
    return str_replace('<a href', '<a class="newClassHere" href', $link);
}


回答4:

Just put this in your functions.php

function give_linked_images_class($html, $id, $caption, $title, $align, $url, $size, $alt = '' ){
  $classes = 'img'; // separated by spaces, e.g. 'img image-link'

  // check if there are already classes assigned to the anchor
  if ( preg_match('/<a.*? class=".*?">/', $html) ) {
    $html = preg_replace('/(<a.*? class=".*?)(".*?>)/', '$1 ' . $classes . '$2', $html);
  } else {
    $html = preg_replace('/(<a.*?)>/', '$1 class="' . $classes . '" >', $html);
  }
  return $html;
}
add_filter('the_content','give_linked_images_class');