How can I avoid re-inventing the Custom Fields wheel in my Plugin’s Metabox?

Here’s the scenario:

In my plugin, I want to have a metabox show up on the post / page editor.

Read More

I want the metabox to be -exactly- like WordPress’ ‘Custom Fields’ metabox, ( Add another, delete, update, auto-populated dropdown, Enter new link, AJAX magic, etc ); with a couple minor differences:

  • Instead of just ‘Name’ and ‘Value’, I want ‘Target’, ‘Name’ and ‘Value’

  • Instead of saving them all as ‘public’ custom fields that automatically appear inside the WP Custom Fields metabox, I want them all stored as a single multidimensional array inside a ‘private’, namespaced, field…i.e., _myplugin_custom_fields = array( 1 => array( 'target' => 'mytarget1', 'name' => 'myname1', 'value' => 'myvalue1' ), 2 => array( 'target' => 'mytarget2', 'name' => 'myname2', 'value' => 'myvalue2' ) )

I’ve spent all day digging through the tangled web of WP Core, and have not been able to find a straightforward way to pull this off. If I move forward based on my current understanding, I’ll end up duplicating hundreds of lines of core code from numerous php and js files.

Can anyone here in WordPress Answers-land help point me in the right direction? I have plenty of experience in adding and leveraging metaboxes within themes and plugins, but this one has me totally stumped.

Please speak up if I’m being unclear.

Thanks in advance to all who reply!

Related posts

Leave a Reply

3 comments

  1. The short answer is that there isn’t any straightforward way to do this, since the custom field metabox was not written with extensibility in mind.

    You could add the additional field using JavaScript and hijack the Add button to send the data to your custom AJAX handler that would store them as you want.

  2. I’m saving my custom fields with the name _meta_whatever. Starting the name with an underscore, stops WordPress showing up the custom fields in the dropdown-box in the normal posts.

    For saving in an array I’m using HTML-code like this.

    ...
    <input type="text" class="short" name="_events_meta[startDate]" id="_events_meta[startDate]" value="<?php if(!empty($meta['startDate'])) echo $meta['startDate']; ?>"/>
    <input type="text" class="extrashort" name="_events_meta[startTime]" id="_events_meta[startTime]" value="<?php if(!empty($meta['startTime'])) echo $meta['startTime']; ?>"/>
    ...
    

    For retrieving the meta-values, this is my code I’m using

    ...
    $meta = get_post_meta($post->ID,'_events_meta',TRUE);
    ...
    

    Now I have an assoziative array $meta where the key name is given in the brackets in the id-Attribute of the input-Element.

    For saving I’m using code like this

    ...
    $new_data = $_POST['_events_meta'];
    ...
    add_post_meta($post_id,'_events_meta',$new_data,TRUE);
    ...
    

    So it is saved as one record in wp_postsmeta

    Hope this helps and is clearly expressed from my side?