Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

How to Add Captions to Image Upload Field in Meta Box WordPress

  • REFUNDED

I'm using [[LINK href="http://www.deluxeblogtips.com/2011/03/meta-box-script-update-v30.html"]]this meta box script[[/LINK]] on my wordpress.

And I'd like to add a caption field next to the image upload field, where I can define a caption for each image uploaded.

I tried hacking the image upload function but no luck. Obviously following snippet that is a part of meta box class of this script only gets and uploads the file itself and nothing else:


function save_field_file($post_id, $field, $old, $new) {
$name = $field['id'];
if (empty($_FILES[$name])) return;

$this->fix_file_array($_FILES[$name]);

foreach ($_FILES[$name] as $position => $fileitem) {
$file = wp_handle_upload($fileitem, array('test_form' => false));

if (empty($file['file'])) continue;
$filename = $file['file'];

$attachment = array(
'post_mime_type' => $file['type'],
'guid' => $file['url'],
'post_parent' => $post_id,
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => ''
);
$id = wp_insert_attachment($attachment, $filename, $post_id);
if (!is_wp_error($id)) {
wp_update_attachment_metadata($id, wp_generate_attachment_metadata($id, $filename));
add_post_meta($post_id, $name, $file['url'], false); // save file's url in meta fields
}
}
}

// Save images, call save_field_file, cause they use the same mechanism
function save_field_image($post_id, $field, $old, $new) {
$this->save_field_file($post_id, $field, $old, $new);
}


What I need is add one more field next to the file/image upload field and save field to be the caption of the file/image.

As you can see it's saving the uploaded item as an attachment where hypothetically I can save that caption value into excerpt or post_content but I lack of enough knowledge to successfully hack this through.

Help appreciated.

Thanks,

Onur

Answers (2)

2011-04-25

David Navarrete answers:

try with this


add_post_meta($post_id, $field, $file['url'], false);


Onur Oztaskiran comments:

I'm confused. Exactly which part of the code I use this?

Thanks


David Navarrete comments:

find
if (!is_wp_error($id)) {

wp_update_attachment_metadata($id, wp_generate_attachment_metadata($id, $filename));

add_post_meta($post_id, $name, $file['url'], false); // save file's url in meta fields

}


the var $name doesn't exists in the script. or find $name and replace with $field


Onur Oztaskiran comments:

I tried but that $name is actually used to get the uploaded file's name and it also queries the uploaded file with it.


function save_field_file($post_id, $field, $old, $new) {
$name = $field['id'];
if (empty($_FILES[$name])) return;

$this->fix_file_array($_FILES[$name]);

foreach ($_FILES[$name] as $position => $fileitem) {
$file = wp_handle_upload($fileitem, array('test_form' => false));


As you see, this function only passes the uploaded file details. I need to get the additional field value (caption text field) related to this file when saving it.


Onur Oztaskiran comments:

Please see here what I'm trying to do: http://cl.ly/6F7N

I need those caption values imprinted into the attachment upload as let's say post_excerpt or post_content.

Does that help identify my problem better?:)

Thanks,
Onur


David Navarrete comments:


function save_field_file($post_id, $field, $old, $new) {

$name = $field['id'];

if (empty($_FILES[$name])) return;



$this->fix_file_array($_FILES[$name]);



foreach ($_FILES[$name] as $position => $fileitem) {

$file = wp_handle_upload($fileitem, array('test_form' => false));



if (empty($file['file'])) continue;

$filename = $file['file'];



$attachment = array(

'post_mime_type' => $file['type'],

'guid' => $file['url'],

'post_parent' => $post_id,

'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),

'post_content' => ''

);

$id = wp_insert_attachment($attachment, $filename, $post_id);

if (!is_wp_error($id)) {

wp_update_attachment_metadata($id, wp_generate_attachment_metadata($id, $filename));

add_post_meta($post_id, $field, $file['url'], false); // save file's url in meta fields

}

}

}



// Save images, call save_field_file, cause they use the same mechanism

function save_field_image($post_id, $field, $old, $new) {

$this->save_field_file($post_id, $field, $old, $new);

}



here's the code, replace it.

tell me if work.


Onur Oztaskiran comments:

That breaks the code and file upload doesn't work this way. And the reason it breaks the code is


add_post_meta($post_id, $name, $file['url'], false); // save file's url in meta fields


it uses the $name to get the uploaded file not url. so when we try changing that $name into $field, file upload won't work anymore.

There has to be an another way.


Onur Oztaskiran comments:

No luck.

I somehow need to get the caption-ipro_gal_folio_images value for the meta_id in the post_id.

Now that's a b*tch ha :)

2011-04-25

AdamGold answers:

As I can see in the tutorial you've linked to, there's this code:
class RW_Meta_Box_New extends RW_Meta_Box {

// show uploaded images in 1 cell, overwrite original method
function show_field_image($field, $meta) {
global $post;

echo "<td colspan='2'>{$field['name']}<br />";

// show attached images
$attachs = get_posts(array(
'numberposts' => -1,
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image', // get attached images only
'output' => ARRAY_A
));
if (!empty($attachs)) {
$nonce = wp_create_nonce('rw_ajax_delete_file');

echo '<div style="margin-bottom: 10px"><strong>' . _('Images attached to this post') . '</strong></div>';
foreach ($attachs as $att) {
$src = wp_get_attachment_image_src($att->ID, 'thumbnail');
$src = $src[0];
echo "<div style='margin: 0 10px 10px 0; float: left'><img width='150' src='$src' /><br />
<a class='rw-delete-file' href='javascript:void(0)' rel='{$att->ID}-{$nonce}'>Delete</a>
</div>";
}
}

// show form upload
echo "<div style='clear: both'><strong>" . _('Upload new images') . "</strong></div>
<div class='new-files'>
<div class='file-input'><input type='file' name='{$field['id']}[]' /></div>
<a class='rw-add-file' href='javascript:void(0)'>" . _('Add more image') . "</a>
</div>
</td>";
}


You need to replace it with:
class RW_Meta_Box_New extends RW_Meta_Box {

// show uploaded images in 1 cell, overwrite original method
function show_field_image($field, $meta) {
global $post;

echo "<td colspan='2'>{$field['name']}<br />";

// show attached images
$attachs = get_posts(array(
'numberposts' => -1,
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image', // get attached images only
'output' => ARRAY_A
));
if (!empty($attachs)) {
$nonce = wp_create_nonce('rw_ajax_delete_file');

echo '<div style="margin-bottom: 10px"><strong>' . _('Images attached to this post') . '</strong></div>';
foreach ($attachs as $att) {
$src = wp_get_attachment_image_src($att->ID, 'thumbnail');
$src = $src[0];
echo "<div style='margin: 0 10px 10px 0; float: left'><img width='150' src='$src' /><br />
<a class='rw-delete-file' href='javascript:void(0)' rel='{$att->ID}-{$nonce}'>Delete</a>
</div>";
}
}

// show form upload
echo "<div style='clear: both'><strong>" . _('Upload new images') . "</strong></div>
<div class='new-files'>
<div class='file-input' style='float: left'><input type='file' name='{$field['id']}[]' /></div>
<div style='float:right'>Caption: <input type='text' name='caption_{$field['id']}' /></div>
<div style='clear: both'></div>
<a class='rw-add-file' href='javascript:void(0)'>" . _('Add more image') . "</a>
</div>
</td>";
}


Now, to save it, add the following block of code:

add_post_meta($post_id, 'caption_' . $name, 'caption_' . $name, false);

Below:
add_post_meta($post_id, $name, $file['url'], false);

To echo the caption you will need to get the image ID, and then caption_IMAGEID.

Good luck!


Onur Oztaskiran comments:

Hi Adam,

That feels closer. However this didn't return the value but the field id:

http://cl.ly/6F6a


AdamGold comments:

Yup, my mistake. I suppose your form uses POST method, so:

add_post_meta($post_id, 'caption_' . $name, $_POST[ 'caption_' . $name ], false);


Onur Oztaskiran comments:

Great, thanks :)

http://cl.ly/6FBF

Almost there I guess. Only issue is not sure how to best retrieve that value for each image uploaded.


foreach ($attachs as $att) {
$thumbr = wp_get_attachment_image( $att->ID, 'thumbnail', false );
$src = wp_get_attachment_image_src($att->ID, 'full');
$src = $src[0];

echo "<div style='margin: 0 10px 10px 0; float: left' class='thumbr'><a href='$src' title='' rel='prettyPhoto[pp_gal]'>$thumbr</a><br />
<a class='rw-delete-file' href='javascript:void(0)' rel='{$post->ID}!{$field['id']}!{$att->ID}!{$src}!{$nonce}'>Delete</a>
</div>";
}


This is how I try to retrieve the image. But how to retrieve the caption into here?

Thanks,

Onur


AdamGold comments:

Not sure right here, try something like this:
echo get_post_meta( $post->ID, 'caption_' . $att->ID, true);


Onur Oztaskiran comments:

No luck.

This one would normally return "caption-12345" while the record in the db is caption-ipro_gal_folio_images belonging to 12345, under 6789 post id.

I somehow need to get the caption-ipro_gal_folio_images value for the meta_id in the post_id.

Now that's a b*tch ha :)


AdamGold comments:

I need to see the whole code, it could be anything.

try
echo get_post_meta( $post->ID, 'caption_' . $att->title, true);


AdamGold comments:

or
echo get_post_meta( $post->ID, 'caption_' . $att->post_title, true);


Onur Oztaskiran comments:

This also wouldn't work. Let me clearify:

There's a field called "ipro_gal_folio_images" which is a file as input type and saves to meta db with its name,id and url, while at the same time so far we managed to save the "caption-ipro_gal_folio_images" belonging to the id of that uploaded image.

The problem remains is retrieving the "caption-ipro_gal_folio_images" post_meta value.


echo get_post_meta( $post->ID, 'caption_' . $att->FIELDNAME, $att->ID, true);


If there were to be such a thing, I think that would be the logic but there's not so what else can it be, I'm not sure.

I'm about to give up :)


AdamGold comments:

It's very simple, I just need the whole code.


AdamGold comments:

I need the value of $attachs:
$attachs =


Onur Oztaskiran comments:

http://cl.ly/6Dyo this is my version of the script


AdamGold comments:

I am not talking about the script, you posted this code here:

foreach ($attachs as $att) {

Above it, search for $attachs value:
$attachs =

And paste the whole line here.


AdamGold comments:

Oh, I think it's not a dynamic name so just use:
echo get_post_meta( $post->ID, 'caption-ipro_gal_folio_images', true);


Onur Oztaskiran comments:

I've done that Adam :)

2 problems with that:
1) This one gets all the "caption-ipro_gal_folio_images" values in that post and can not determine what those values belong to.
2) That name actually needs to be dynamic because it's part of the meta box constructor script.





if (!empty($meta)) {
// show attached images
$attachs = get_posts(array(
'numberposts' => -1,
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image', // get attached images only
'output' => ARRAY_A
));

$nonce = wp_create_nonce('rw_ajax_delete_file');

echo '<div style="margin-bottom: 10px"><strong>' . _('Uploaded images') . '</strong></div>';
foreach ($attachs as $att) {
$thumbr = wp_get_attachment_image( $att->ID, 'thumbnail', false );
$src = wp_get_attachment_image_src($att->ID, 'full');
$src = $src[0];

echo get_post_meta( $post->ID, 'caption-' . $att->title, true);

echo "<div style='margin: 0 10px 10px 0; float: left' class='thumbr'><a href='$src' title='' rel='prettyPhoto[pp_gal]'>$thumbr</a><br />
<a class='rw-delete-file' href='javascript:void(0)' rel='{$post->ID}!{$field['id']}!{$att->ID}!{$src}!{$nonce}'>Delete</a>
</div>";
}
}