Title: Image Captions &#8211; Simple Solution
Last modified: August 24, 2016

---

# Image Captions – Simple Solution

 *  [Gonçalo Peres](https://wordpress.org/support/users/gonperesgmailcom/)
 * (@gonperesgmailcom)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/image-captions-simple-solution/)
 * If you want to have different image captions for each language, but don’t need
   to have your database cluttered with duplicate posts and taxonomy relationships
   for each attachment, i found a simple way that works just fine.
 * Also, when you activate media translations in a existing site, all gallery images
   disappear from posts which are not in the same language. And you need to create
   new galleries, with the duplicated attachments (even though the image file is
   not duplicated). This is very difficult to manage.
 * This solution can be added to a theme “functions.php” and allows to edit the 
   gallery captions right from the “Edit Gallery” screen (also from the Media Library).
   Please note that it only deals with the caption. Attachment Title, Alternate 
   text and Description was left untranslated, because only Captions affect the 
   galleries in the different languages, in my case.
 * Maybe Chouby considers this in future Polylang versions, as the “Media Translation”
   option is far from perfect, compared to the rest of Polylang which works just
   great.
 *     ```
       if(is_admin()) {
   
       	/*
       	 * This filters enables us to add captions for each existing language to the attachment edit screens
       	 */
       	function my_theme_attachment_fields_to_edit( $form_fields, $post ) {
       		if( !defined('POLYLANG_VERSION') ) { return $form_fields; }
       		global $langs;
   
       		$langs = (empty($langs)) ? pll_languages_list() : $langs;
       		foreach ($langs as $lang) {
       			$key = 'caption_'.$lang;
       			$form_fields[$key] = array(
       					'value' => get_post_meta( $post->ID, $key, true ),
       					'label' => __( 'Caption' ).'-'.$lang,
       					'input' => 'textarea'
       			);
       		}
       		return $form_fields;
       	}
       	add_filter( 'attachment_fields_to_edit', 'my_theme_attachment_fields_to_edit', 10, 2 );
   
       	/*
       	 * In WordPress 4.1, image captions can be changed in two ways: either from Ajax requests (Media Library and Post Galleries)
       	 * or from the edit post (when editing more details from the Media Library). Basically we need to check the action and
       	 * the presence of the $_POST arguments and act accordingly
       	 * 1) $_POST['action'] = 'save-attachment',
       	 *		and only if !empty($_POST['changes']['caption']) && !empty($_POS['post_id'])
       	 *		if($_POS['post_id']) not set (when editing image from Media Library), then we
       	 *    don't know the language and don't to nothing.
       	 *    If $_POS['post_id'] is set (when editing images from a post),
       	 *    then we get the langguage from the post, and update
       	 *    the corresponding caption in the postmeta table.
       	 * 2) $_POST['action'] == 'save-attachment-compat' OR $_POST['action'] == 'editpost'),
       	 *    in which case the captions in the various languages set in the
       	 *    'attachment_fields_to_edit' filter are sent, and can be updated.
       	 */
         function my_theme_wp_insert_attachment_data($data, $postarr) {
       		if( !defined('POLYLANG_VERSION') ) { return $data; }
   
           if( !empty($_POST['changes']['caption']) && !empty($_POST['post_id']) ) {
             $lang = pll_get_post_language($_POST['post_id']);
             $key = 'caption_'.$lang;
             update_post_meta($postarr['ID'], $key, $_POST['changes']['caption']);
       			//keep the default legend if working in an alternate language
             if($lang != pll_default_language()) {
               unset($data['post_excerpt']);
             }
           }
           elseif( isset($_POST['action']) && ($_POST['action'] == 'save-attachment-compat' || $_POST['action'] == 'editpost')  ) {
             $langs = pll_languages_list();
             foreach ($langs as $lang) {
               $key = 'caption_'.$lang;
               if(isset($_POST['attachments'][$postarr['ID']][$key])) {
                 update_post_meta($postarr['ID'], $key, $_POST['attachments'][$postarr['ID']][$key]);
               }
             }
           }
           return $data;
       	}
       	add_filter( 'wp_insert_attachment_data', 'my_theme_wp_insert_attachment_data', 10, 2 );
   
       } // END if(is_admin()) {
   
       /*
        * we only want the filters to be active while running the gallery/attachment queries
        */
       function my_theme_post_gallery($output) {
       	if( !defined('POLYLANG_VERSION') ) { return $output; }
       	global $post;
       	if(is_object($post) ) {
       		$GLOBALS['pll_gallery'] = true;
       	}
       	return $output;
       }
       add_filter( 'post_gallery', 'my_theme_post_gallery', 10, 1);
   
       /*
        * By default, filters are suppressed for queries which are not the main query, so we need to activate them for the gallery/attachment queries
        */
       function my_theme_pre_get_posts($query) {
       	if( !defined('POLYLANG_VERSION') ) { return $str; }
       	global $post;
       	if( is_admin() && $_POST['action'] == 'query-attachments' ) {
       		$query->set('suppress_filters', false );
       		$query->pll_gallery_post_id = $_POST['post_id'];
       	}
       	if( is_object($post) && isset($GLOBALS['pll_gallery']) ) {
       		$query->set('suppress_filters', false );
       		$query->pll_gallery_post_id = $post->ID;
       	}
       }
       add_action('pre_get_posts','my_theme_pre_get_posts');
   
       /*
        * Here we substitute the default caption (post_excerpt) with the correct value from postmeta table, if it's not null or empty:
        * the FIELDS part
        */
       function my_theme_posts_field($str, $query) {
       	if( !defined('POLYLANG_VERSION') ) { return $str; }
       	if( isset($query->pll_gallery_post_id) ) {
       		global $wpdb;
       		//$lang = pll_get_post_language($post->ID);
       		$str .= ", IFNULL(pm.meta_value, $wpdb->posts.post_excerpt) AS post_excerpt";
       	}
         return $str;
       }
       add_filter('posts_fields', 'my_theme_posts_field', 10, 2);
   
       /*
        * Here we substitute the default caption (post_excerpt) with the correct value from postmeta table, if it's not null or empty:
        * the JOIN part
        */
       function my_theme_posts_join($str, $query) {
       	if( !defined('POLYLANG_VERSION') ) { return $str; }
       	global $wpdb;
       	if( isset($query->pll_gallery_post_id) ) {
       		$lang = pll_get_post_language($query->pll_gallery_post_id);
       		$str .= " LEFT JOIN $wpdb->postmeta AS pm ON ($wpdb->posts.ID = pm.post_id && pm.meta_key = 'caption_".$lang."')";
       	}
         return $str;
       }
       add_filter('posts_join', 'my_theme_posts_join', 10, 2);
   
       /*
        * This deactivates the filters, after the correct caption for galleries is shown, so other WP_Queries can run normal.
        */
       function my_theme_posts_request( $str, $query ) {
       	if( !defined('POLYLANG_VERSION') ) { return $str; }
       	if( isset($query->pll_gallery_post_id) ) {
       		$query->set('suppress_filters', true );
       		unset($query->pll_gallery_post_id, $GLOBALS['pll_gallery']);
       	}
         return $str;
       }
       add_filter( 'posts_request', 'my_theme_posts_request', 10, 2 );
       ```
   
 * [https://wordpress.org/plugins/polylang/](https://wordpress.org/plugins/polylang/)

Viewing 5 replies - 1 through 5 (of 5 total)

 *  Plugin Author [Chouby](https://wordpress.org/support/users/chouby/)
 * (@chouby)
 * [11 years, 2 months ago](https://wordpress.org/support/topic/image-captions-simple-solution/#post-5963523)
 * Hi!
 * Thanks for sharing. It may help other users.
    Just a quick fix as I got a notice
   when testing it. You should replace
 *     ```
       if( is_admin() && $_POST['action'] == 'query-attachments' ) {
       ```
   
 * by
 *     ```
       if( is_admin() && isset($_POST['action']) && $_POST['action'] == 'query-attachments' ) {
       ```
   
 * > Also, when you activate media translations in a existing site, all gallery 
   > images disappear from posts which are not in the same language
 * I must admit that the option was meant to be activated at the beginning of the
   life of a website.
 * At the moment, I don’t plan to add this to Polylang as other users may need to
   translate the title, the description and other contents too. But I am glad you
   shared! And I agree that I should think on how to improve the workflow to translate
   media.
 *  [tb.dev](https://wordpress.org/support/users/tbdl/)
 * (@tbdl)
 * [11 years ago](https://wordpress.org/support/topic/image-captions-simple-solution/#post-5963657)
 * I really like Polylang, but the way images are handled is really not best practice!
 * As long as you don’t have text in images that should be translated, why using
   multiple images in the media library, when you just need to change the caption
   or the title? Imagine this with 5 or more languages, this means there will be
   5 times the same image visible for just the caption… very uncomfortable!
 * So I also prefer Gonçalo Peres method.
 * I was just wondering if this could be done with titles too? Cause my Nivo Slider
   from Visual Composer uses only titles.. and I dont wanna core hack this 🙁
 *  [plugza](https://wordpress.org/support/users/plugza/)
 * (@plugza)
 * [10 years, 10 months ago](https://wordpress.org/support/topic/image-captions-simple-solution/#post-5963680)
 * how to get the output?
 *  [plugza](https://wordpress.org/support/users/plugza/)
 * (@plugza)
 * [10 years, 8 months ago](https://wordpress.org/support/topic/image-captions-simple-solution/#post-5963684)
 * No one answer my question.
    How to get the output? I use post_excerpt and nothing
   happens. it’s still use the default value.
 *  [d](https://wordpress.org/support/users/dnicinski/)
 * (@dnicinski)
 * [10 years, 7 months ago](https://wordpress.org/support/topic/image-captions-simple-solution/#post-5963689)
 * Hi Gonçalo & Chouby,
 * Outstanding! Works great. But… How can the same be done for Title, ALT Text and
   Description?
 * Can you point me in the right direction? I see caption is simple ‘caption’. Is
   that true for Title, ALT Text and Description?
 * Can I just replicate this code three more times for each field?
 * Thanks
    David

Viewing 5 replies - 1 through 5 (of 5 total)

The topic ‘Image Captions – Simple Solution’ is closed to new replies.

 * ![](https://ps.w.org/polylang/assets/icon-256x256.png?rev=3433336)
 * [Polylang](https://wordpress.org/plugins/polylang/)
 * [Frequently Asked Questions](https://wordpress.org/plugins/polylang/#faq)
 * [Support Threads](https://wordpress.org/support/plugin/polylang/)
 * [Active Topics](https://wordpress.org/support/plugin/polylang/active/)
 * [Unresolved Topics](https://wordpress.org/support/plugin/polylang/unresolved/)
 * [Reviews](https://wordpress.org/support/plugin/polylang/reviews/)

 * 5 replies
 * 5 participants
 * Last reply from: [d](https://wordpress.org/support/users/dnicinski/)
 * Last activity: [10 years, 7 months ago](https://wordpress.org/support/topic/image-captions-simple-solution/#post-5963689)
 * Status: not a support question