This video is quick and dirty talk about the WPAlchemy_MediaAccess helper class which will help you integrate the WordPress Media Uploader with your custom meta boxes.
This video is quick and dirty talk about the WPAlchemy_MediaAccess helper class which will help you integrate the WordPress Media Uploader with your custom meta boxes. It’s hot off the code editor (alpha stage) but functions rather well. Please give me your initial impressions/feedback.
View the setup and install WPAlchemy video if you need a quick primer on getting it all setup properly.
file: functions.php
include_once 'metaboxes/setup.php'; include_once 'metaboxes/custom-spec.php';
file: metaboxes/setup.php
include_once WP_CONTENT_DIR . '/wpalchemy/MetaBox.php';
include_once WP_CONTENT_DIR . '/wpalchemy/MediaAccess.php';
// include css to help style our custom meta boxes
add_action( 'init', 'my_metabox_styles' );
function my_metabox_styles()
{
if ( is_admin() )
{
wp_enqueue_style( 'wpalchemy-metabox', get_stylesheet_directory_uri() . '/metaboxes/meta.css' );
}
}
$wpalchemy_media_access = new WPAlchemy_MediaAccess();
file: metaboxes/custom-spec.php
$custom_mb = new WPAlchemy_MetaBox(array ( 'id' => '_custom_meta', 'title' => 'My Custom Meta', 'template' => get_stylesheet_directory() . '/metaboxes/custom-meta.php', ));
file: metaboxes/custom-meta.php
<?php global $wpalchemy_media_access; ?>
<div class="my_meta_control metabox">
<?php $mb->the_field('imgurl'); ?>
<?php $wpalchemy_media_access->setGroupName('nn')->setInsertButtonLabel('Insert'); ?>
<p>
<?php echo $wpalchemy_media_access->getField(array('name' => $mb->get_the_name(), 'value' => $mb->get_the_value())); ?>
<?php echo $wpalchemy_media_access->getButton(); ?>
</p>
<?php $mb->the_field('imgurl2'); ?>
<?php $wpalchemy_media_access->setGroupName('nn2')->setInsertButtonLabel('Insert This')->setTab('gallery'); ?>
<p>
<?php echo $wpalchemy_media_access->getField(array('name' => $mb->get_the_name(), 'value' => $mb->get_the_value())); ?>
<?php echo $wpalchemy_media_access->getButton(array('label' => 'Add Image From Library')); ?>
</p>
</div>
Using MediaAccess Field/Button with MetaBox Repeating Fields Functionality
file: metaboxes/custom-meta.php (e.g. metaboxes/repeating_fields_meta.php)
<?php global $wpalchemy_media_access; ?>
<div class="my_meta_control">
<p><a href="#" class="dodelete-docs button">Remove All</a></p>
<?php while($mb->have_fields_and_multi('docs')): ?>
<?php $mb->the_group_open(); ?>
<a href="#" class="dodelete button">Remove</a>
<?php $mb->the_field('imgurl'); ?>
<?php $wpalchemy_media_access->setGroupName('img-n'. $mb->get_the_index())->setInsertButtonLabel('Insert'); ?>
<p>
<?php echo $wpalchemy_media_access->getField(array('name' => $mb->get_the_name(), 'value' => $mb->get_the_value())); ?>
<?php echo $wpalchemy_media_access->getButton(); ?>
</p>
<?php $mb->the_field('title'); ?>
<label for="<?php $mb->the_name(); ?>">Title</label>
<p><input type="text" id="<?php $mb->the_name(); ?>" name="<?php $mb->the_name(); ?>" value="<?php $mb->the_value(); ?>"/></p>
<?php $mb->the_group_close(); ?>
<?php endwhile; ?>
<p style="margin-bottom:15px; padding-top:5px;"><a href="#" class="docopy-docs button">Add</a></p>
</div>
You can get the code on github.

@melinda – do you mean show the thumbnail as the preview? i’m not sure that is possible unless you select the thumbnail as the size you want to “insert into post”… or i think i’ve hacked it so that the button says “use this image”. the whole thing works by picking up the html that is sent via the “send to editor” function. there is no way to server-side take that image and go get the corresponding thumb.
all that said, you’ll note in my code that i’ve got a hidden form called image_id. this saves the attachment ID.. which you can then use to produce any version of that image you’d like. say on refresh you can load the thumbnail, or on the front-end you can load the medium size, etc.
@kathy – i did notice the hidden form called image_id and tried adding it to mt metabox template but it doesn’t seem to be saving a value. am i missing something that makes this work? i tried putting get_the_value(‘image_id’)){$mb->the_value(‘image_id’);}?> in my template to see if it would print the attachmen id but nothing is printed.
@melinda- the only real “trick” to making it work isn’t really a trick so much as just ensuring that the markup of your mb template matches mine exactly. this is b/c my jquery isn’t universal, but rather, depends heavily on tranversing the DOM as i have set it up. sort of like if i told you to take 2 lefts and then a right you’d end up in a different place if you started from a different place and in a different direction. maybe one day dimas, or myself, or maybe you can come up w/ a better way. that’s just what worked for me at my then-current level of jquery… ie blue belt, but not a ninja. i’ve promoted myself to brown belt now so if i ever have spare time, i’m thinking using IDs and string/preg matching against part of the ID name might work and make it less fragile in this regard.
sidenote- it only gets IDs for images that you add to the WP database. (ie via uploader) so externally hosted images don’t have IDs. don’t know if you’re running into that or not, but figured i’d mention that is an obvious limitation. i think i have it fall back to using the URL if ID is empty, but i haven’t tested that too robustly.
Quick question Dimas,
Does the user have to have the upload_files capability to implement? The problem I’m having is that I have a custom user role that only sees a custom post type in the backend (does not see posts). I’d like for that user to not see Media either. I’d like to completely isolate them to the post type but still be able to upload and manage their own media.
If your app does not do this by default, do you have any suggestions of where to look?
Not sure if you would consider this a bug or expected behavior, and it is kind of an edge case, but I thought it might help you or someone else to mention this…
Creating a few custom post types for a plugin. One of the posttypes has:
'supports' => array( 'title','revisions' )I’m not using the editor with this cpt.
When I use the Media Access meta box with this cpt, clicking the button to launch the media uploader opens it as a new page. I figured out that, because the editor is not invoked, the styles and scripts for the media uploader are not loaded.
Fixing it was easy — I added to my plugin:
function my_admin_styles() {
wp_enqueue_style('thickbox');
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
}
add_action( 'admin_print_styles', 'my_admin_styles' );
Now, the admin page has the styles and scripts it needs to launch the media uploader appropriately.
One more fix, also related to disabling the editor for a custom post type: the media uploader doesn’t believe it is actually allowed to insert a file so the insert button is missing.
This fixed it:
function allow_file_insertion($vars) {
$vars['send'] = true; // 'send' as in "Send to Editor"
return($vars);
}
add_filter( 'get_media_item_args', 'allow_file_insertion' );
Source
Ought to apply the filter only if the custom post type is what’s being edited, but it was a quick fix for now.
Thanks for this library. It’s awesome.
Okay, one more comment:
Is there a method you would recommend for a Javascript function callback once the user picks the file? I wanted to show an icon next to the field once it’s populated. I ultimately had to make a change to the class on line 344:
wpalchemy_mediafield.val(url);Becomes
wpalchemy_mediafield.val(url).change();Then I was able to bind to that change:
$('input.mediafield').bind('change', function(event) {// awesomeness ensues
}
It works, but it seems like a hack to me. Is there a better way?
Hi Dimas,
At first I’d like to say WPAlchemy is amazing. The logic is great
Just follow the video above, I try to make save_action for repetitive fields and display separated meta_key and meta_value pair for every fields.
Unfortunately, the results is empty string on meta_value.
the scenario :
custom-spec.php
'_custom_meta', //make sure it different with other(s) aka spesific 'title' => 'My Custom Spec Meta', 'template' => get_stylesheet_directory() . '/custom/custom_meta.php', 'mode' => WPALCHEMY_MODE_EXTRACT, 'prefix' => '_test_', 'save_action' => 'my_save_action_function', // defaults to NULL )); function my_save_action_function ( $meta, $post_id ) { update_post_meta ($post_id, '_test_img_url', $meta['imgurl']); update_post_meta ($post_id, '_test_img_title', $meta['title']); } ?>and on custom-meta.php
<a href="#" rel="nofollow">Remove All</a> have_fields_and_multi('docs')): ?> the_group_open(); ?> <a href="#" rel="nofollow">Remove</a> the_field('imgurl'); ?> setGroupName('img-n'. $mb->get_the_index())->setInsertButtonLabel('Insert'); ?> getField(array('name' => $mb->get_the_name(), 'value' => $mb->get_the_value())); ?> getButton(); ?> the_field('title'); ?> <label for="the_name(); ?>">Title <input type="text" id="the_name(); ?>" name="the_name(); ?>" value="the_value(); ?>"/> the_group_close(); ?> <a href="#" rel="nofollow">Add More Media</a>Thank you before and after. I keep trying how to make it solved, and any solutions and clue is very appreciate.
hope you can understand my friendly english (my term for “english for non native english”
)
@riesurya, glade wpalchemy is working for you (kinda) … please do me a favor and repost your code using http://gist.github.com and then just post a link here (I’ll replace your code above with the link, makes it easier for me and others to follow along) …
I believe your problem is: because it is a repeating field the repeating field data itself is an array, so you can not access its data at the first level of the
$metaarray, try something like this:function my_save_action_function ( $meta, $post_id ) { // use this to view the array structure // print_r( $meta ); exit; // delete old data delete_post_meta( $post_id, '_test_img_url' ); delete_post_meta( $post_id, '_test_img_title' ); foreach ( $meta['docs'] as $doc ) { add_post_meta( $post_id, '_test_img_url', $doc['imgurl'] ); add_post_meta( $post_id, '_test_img_title', $doc['title'] ); // do not use update_user_meta because when adding another meta/value of the same key $prev_value must be different from $meta_value // see http://codex.wordpress.org/Function_Reference/update_user_meta //update_post_meta( $post_id, '_test_img_url', $doc['imgurl'] ); //update_post_meta( $post_id, '_test_img_title', $doc['title'] ); } }@Arlo, I will incorporate something similar to the class itself. Thanks for the tip/code.
@Dimas Thank you so much for this plugin! It is so exactly what i need and i found it through a blog post on smashing magazine (someone commented about your plugin) that was posted on the exact day i need it (today). Love those coincidences.
So i followed the instructions to set up WPAlchemy and get it running and it works fine, but when i try to implement the example above I always get the following error:
Fatal error: Call to a member function setGroupName() on a non-object in /home/seltzde1/public_html/athena/wp-content/themes/yoko/metaboxes/custom-meta.php on line 5
I have checked many times over and am copy and pasting everything from your examples into the right files. I get the same error for the 1st and 2nd example. Thats where i am stuck right now. Im sure its just something small, but everything seems exactly like you have it. Help is much appreciated! Thanks.
@Armin, that error is usually caused because of scope, be sure you have the following:
@Dimas
Ok i should have watched the video straight away. In the video you mention the importance of this part:
$wpalchemy_media_access = NEW WPAlchemy_MediaAccess();But this is not found in the code boxes you give above, which I used to copy and paste from. I now put it at the end of setup.php and voila it works. Maybe you should include it there, so it doesnt happen to others who are as impatient as me and dont watch the video first
So now for the real fun part.. Im sure ill have a few more questions soon.
Hello Dimas.
Great work man!
Thank you very much. Really.
I have a problem. Is it possible to nest two the_group_open()?
I need to create a repeatable set of fields which in turn contain another set of repeatable media upload fields. What do you think?
Thanks in advance.
You’ve launched WordPress to the next level!
( I have you in my donations Christmas list
@Gonzalo, at the moment it is not possible, I’ve heard a few requests for this, I’ll give it a go and see what I come up with (just need to find some free time).
ok, try another solution.
For example, a “title” field accompanied by a fixed number of fields for images, and the entire block is repeatable.
Not the most elegant solution but it would work. While we await the release of the next version of WPAlchemy!
Another question friend. What is the way to store the attachment_id instead of the image path? Or both
I ask the question directly instead of filling the post with the adventures I’ve tried to get the ettacment_id (unsuccessfully).
Dameian said something about this in one comment (April 12, 2011) but I can not find the solution that way.
thanks for sharing,its much easier to add on my wp site.thanks
Hey Dimas, thanks for all of your work!
I’d suggest including this into boxes above (also had the issue but found solution in comments):
// the name of the instantiated class object
global $wpalchemy_media_access;
Thanks,
Nick
Sorry, meant this one:
$wpalchemy_media_access = NEW WPAlchemy_MediaAccess();
Hi Dimas, I did everything you recommend above and what I have are just Remove and Remove All buttons. What did I do wrong ? I am using the last version of WPAlchemy…
Thanks for your help
Hi,
great work so far! I tried the “Repeating Fields Functionality” but for some reason the mentioned Version 1.4.5 of the MetaBox.php is missing at GitHub. Is there a chance to receive this one?
Best Regards
Matthew
Ciao Dimas,
I am trying to use the media uploader with PDF files. The problem I have is the url to the PDF is not placed into the text input. It is working perfectly with image files, but with PDF is a no go.
Can you give me some suggestions ? I am looking in the source, but I am not much of a programmer.
Thanks a lot.
Is it normal that when I insert my picture using the Media Upload box, it get inserted into the normal wordpress editor box? I can’t get it to work…
I’d like to make the images links (via the Link URL field in the uploader). Is there a way to do this using the MediaAccess helper you’ve created?
Hallo Dimas,
I’ve just upgraded one of my sites to WP3.3, which uses MediaAccess. It seems it works fine, and is much the same as before (with the caveat of this being a specific situation and only one test).
Tested with 0.2.1.
Frances