How do I change the description of the same image which is to be found in multiple instances?

We have the site from http://asceticexperience.com/

Feel free to dig the site in order to understand our question below.

Of course, any feedback appreciated 🙂 but my main question is the following:

We have a photo multiple times on site (in blog, portfolio, and in slide-shows from the menus Body, Mind, Heart).

The description of the photos is taken from ‘Description’ field from Media Gallery. (As you know the field is filled from photo’s EXIF).

Because each time when I attach a photo to a page/post, WordPress copies the photo, we need a plugin/solution/whatever to allow us to change simultaneously the description of all the instances for the eg. myPhoto.jpg.

Now when we want to change/update a caption, we need to go to all instances and manually edit them.

Does someone knows a solution for this problem?

Solutions Collecting From Web of "How do I change the description of the same image which is to be found in multiple instances?"

Plugin idea #1

When we insert an image into the editor, the plugin automatically modifies the caption and the alt attribute to:

[caption id="attachment_729" align="alignnone" width="300"]
  <a href="http://img.mywordpresstips.com/plugins/wordpress.jpg">
      <img src="http://img.mywordpresstips.com/plugins/wordpress-300x284.jpg" 
          alt="###ALT###" 
          width="300" 
          height="284" 
          class="size-medium wp-image-729" />
  </a> 
  ###CAPTION###
[/caption]

Then on the front-end the image caption is fetched for the corresponding image attachment, based on the attachment_729 string and replaces the ###ALT### and ###CAPTION### dummy values.

So when we want to modify the captions for all the image copies, we only have to do it once in the Media Manager.

Here’s our Dynamic Image Caption plugin that should support this feature (PHP 5.4+):

<?php
/**
 * Plugin Name:   Dynamic Image Caption #1
 * Description:   We only want to modify the image captions in the Media Manager 
 * Plugin URI:    http://wordpress.stackexchange.com/a/179689/26350
 * Plugin Author: Birgir Erlendsson (birgire)
 * Version:       0.0.1
 */

namespace birgire\wpse;

add_action( 'init', function()
{
    $o = new DynamicImageCaption;
    $o->activate();
});

class DynamicImageCaption
{
    private $caption_dummy = '###CAPTION###';
    private $alt_dummy     = '###ALT###';

    public function activate()
    {
        add_shortcode( 
            'caption', 
             [ $this, 'caption_shortcode' ] 
        );

        add_filter( 
            'image_add_caption_text', 
            [ $this, 'add_caption_text' ], 
            10, 
            2 
        );

        add_filter( 
            'image_send_to_editor',  
            [ $this, 'send_to_editor' ],
            10, 
            8 
        );
    }

    public function caption_shortcode( $attr = [], $content = '' )
    {
        if( isset( $attr['id'] ) 
            && ( 
                false !== strpos( $content, $this->caption_dummy ) 
                ||
                false !== strpos( $content, $this->alt_dummy ) 
           )
        )
        {
            $caption = $this->get_caption( 
                $attr['id'], 
                str_replace( 'attachment_', '', $attr['id'] ) 
            );

            $content = str_replace(
                [ $this->caption_dummy, $this->alt_dummy ],
                [ $caption, esc_attr( $caption ) ],
                $content
            );
        }
        return img_caption_shortcode( $attr, $content );
    }

    private function get_caption( $caption, $id )
    {
        $caption = '';

        $attachments = get_posts( 
            [ 
                'p'           =>  $id, 
                'post_type'   => 'attachment', 
                'post_status' => 'inherit' 
            ] 
        );

        if( isset( $attachments[0] ) 
            && $attachments[0] instanceof \WP_Post  
        )
            $caption =  $attachments[0]->post_excerpt;

        return $caption;
    }

    public function send_to_editor( $html, $id, $caption, $title, $align, $url, $size, $alt )
    {
        if( $alt )
        {
            $html = str_replace(
                'alt="' . esc_attr( $alt ),
                'alt="' . $this->alt_dummy,
                $html
            );
        }
        return $html;
    }

} // end class

Copy this into the file:

/wp-content/plugins/dynamic-image-caption/dynamic-image-caption.php

and activate the plugin.

Note that here I use the caption also as the alt attribute for convenience. You should test this further and modify to your needs.

Ps: My first idea was to add extra shortcodes within the [caption] shortcode, like:

[dynamic_caption id="729"] 

and

[dynamic_alt id="729"] 

This works, but I wanted to find another way that only fetches the corresponding attachment once, without using these kind of shortcodes.

Plugin idea #2

Here’s another idea to modify the existing image captions and alt attributes. This plugin doesn’t modify the code in the post editor, like the previous plugin did, only it’s output.

<?php
/**
 * Plugin Name:   Dynamic Image Caption And Alt #2
 * Description:   We only want to modify the image caption and alt in the Media Manager. 
 * Plugin URI:    http://wordpress.stackexchange.com/a/179689/26350
 * Plugin Author: Birgir Erlendsson (birgire)
 * Version:       0.0.1
 */

namespace birgire\wpse;

add_action( 'init', function()
{
    $o = new DynamicImageCaptionAlt;
    $o->activate();
});

class DynamicImageCaptionAlt
{
    public function activate()
    {
        add_shortcode( 
            'caption', 
             [ $this, 'caption_shortcode' ] 
        );
    }

    public function caption_shortcode( $attr = [], $content = '' )
    {
        if( isset( $attr['id'] ) )
        {
            $id = str_replace( 'attachment_', '', $attr['id'] );

            // Fetch the caption and the alt attribute:
            $caption = $this->get_caption( $id );
            $alt     = esc_attr( $this->get_alt( $id ) );

            // Use caption as alt, if alt is empty:
            if( ! $alt )
                $alt = esc_attr( $caption );

            // Modify the caption:
            $content .= '###END###';
            $content = str_replace( 
                strip_tags( $content ), 
                $caption, 
                $content 
            );

            // Modify the alt attribute:
            $content = preg_replace( 
                '#alt="[^"]*"#', 
                sprintf( 'alt="%s"', $alt ), 
                $content 
            );
        }
        return img_caption_shortcode( $attr, $content );
    }

    private function get_caption( $id )
    {
        global $wpdb;
        $sql = $wpdb->prepare( 
            "SELECT post_excerpt 
             FROM {$wpdb->posts} 
             WHERE ID = %d AND post_type = 'attachment' ", 
            $id 
        );
        return $wpdb->get_var( $sql );
    }

    private function get_alt( $id )
    {
       return get_post_meta( $id, '_wp_attachment_image_alt', true );
    }

} // end class

Note that this will add extra database queries to your site, as expected.

I’m guessing you’re referring to images which have been placed into WordPress’ post content editor, right?

For example, you clicked “Add Media” and then uploaded a photo and inserted it into your post. What’s hard to know is whether you’re actually referring to a “Description” or if you mean the “Alt Text”, “Caption” or “Title” fields. I have never seen the actual “Description” field get filled by default, from EXIF or otherwise, though I have seen the “Title” field get auto-populated.

Either way, if you’re referring to images you’ve placed directly into your post’s content, you can’t easily edit this information. It’s more or less hard-coded HTML in the post and updating any of the “Title”, “Caption”, “Alt Text” or “Description” fields in the Media Editor will not update this in post content editors.

However, there are a couple of solutions available to you.

If you can login to PHPMyAdmin, you can do a global search and replace. As with anything “messing with your database” related, make a backup first!

  1. In PHPMyAdmin, select the database you want to work with from the list on the left
  2. Click on “SQL” in the list of tabs at the top.
  3. Enter the following query

    UPDATE `wp_posts` SET `post_content` = replace(`post_content`, 'this is your original description1234567890', 'this is the new one')

  4. Click Go

I just tested this and had no issue with my site, but for real for reals, do the whole backup thing first.

There’s also this plugin but it’s not done all that well for me in the past: https://wordpress.org/plugins/search-and-replace/