1
votes

I wanted to create a plugin to batch manage posts' custom field data. I know I can add post meta by add a meta box in post edit screen and use add_action('save_post','function_to_update_meta') to trigger add meta functions.

But I don't know how to trigger the add_post_meta function in a admin menu page (such as a custom admin menu). How to do that?

Thank you in advance!

2

2 Answers

1
votes

The example given in Wordpress' codex is probably the best and most secure in the way of processing information:

Add Meta Box

Copy and paste it and then fiddle around with it to get a good idea on how to control your posts and pages.

The nice part is that you don't need to worry about checking if you need to Add vs Update a given Post Meta field. Using Update Post Meta will ensure that the proper action is taken for you, even if the field doesn't exist.

The same goes for Update Option if you want to add some global controls that your plugin/theme might use.

BREAKDOWN EXAMPLE:

add_action( 'add_meta_boxes', 'myplugin_add_custom_box' );
add_action( 'save_post', 'myplugin_save_postdata' );

These are the action hooks. The first one is executed when meta boxes are being populated within the post editor, and the second is executed when a post is added OR updated.

function myplugin_add_custom_box()
{
    add_meta_box( 
        'myplugin_sectionid',
        __( 'My Post Section Title', 'myplugin_textdomain' ),
        'myplugin_inner_custom_box',
        'post' 
    );
    add_meta_box(
        'myplugin_sectionid',
        __( 'My Post Section Title', 'myplugin_textdomain' ), 
        'myplugin_inner_custom_box',
        'page'
    );
}

This function is called by the 'add_meta_boxes' action hook. Notice the name of the function and the second argument of the action hook are exactly the same. This registers your meta boxes, which post types they're supposed to appear, and what callback is used to generate the form contained inside.

function myplugin_inner_custom_box( $post )
{
    wp_nonce_field( plugin_basename( __FILE__ ), 'myplugin_noncename' );

    $value = get_post_meta($post->ID, 'myplugin_new_field') ? get_post_meta($post->ID, 'myplugin_new_field') : 'New Field';

    echo '<label for="myplugin_new_field">';
    _e("Description for this field", 'myplugin_textdomain' );
    echo '</label> ';
    echo '<input type="text" id="myplugin_new_field" name="myplugin_new_field" value="'.$value.'" size="25" />';
}

This is the function that is called by the registered meta boxes to generate the form automatically. Notice how the function is called 'myplugin_inner_custom_box' and the 3rd argument in your meta box registration is also called 'myplugin_inner_custom_box'.

The wp_nonce_field() generates a hidden field in your form to verify that data being sent to the form actually came from Wordpress, and can also be used to end the function in case other plugins are using the 'save_post' action hook.

Notice also that the $post object is being passed in as an argument. This will allow you to use certain properties from the post object. I've taken the liberty of checking to see if there is get_post_meta() returns anything with the given post ID. If so, the field is filled with that value. If not, it is filled with 'New Field'.

function myplugin_save_postdata( $post_id )
{
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        return;
    if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename( __FILE__ ) ) )
        return;
    if ( 'page' == $_POST['post_type'] ) 
    {
        if ( !current_user_can( 'edit_page', $post_id ) )
        return;
    }
    else
    {
        if ( !current_user_can( 'edit_post', $post_id ) )
        return;
    }

    $mydata = $_POST['myplugin_new_field'];
    update_post_meta($post_id, 'myplugin_new_field', $mydata);
}

This is the function that is called by the 'save_post' action hook. Notice how the second argument of the second action hook and this function are both called 'myplugin_save_postdata'. First, there are a series of verifications our plugin must pass before it can actually save any data.

First, we don't want our meta boxes to update every time the given post is auto-updating. If the post is auto-updating, cancel the process.

Secondly, we want to make sure the nonce data is available and verify it. If no nonce data is available or is not verified, cancel the process.

Thirdly, we want to make sure the given user has the edit_page permission. The function first checks the post type, and then checks the appropriate permission. If the user does not have that permission, cancel the process.

Lastly, our plugin has finally been verified and we want to save the information. I took the liberty of adding in the final update_post_meta() line to show you how it all comes together.

Notice how $post_id was passed into the function as an argument. This is one of the pieces needed for the update_post_meta() function. The key was named 'myplugin_new_field' and the value of that metadata is now saved as whatever you input into that custom input field in your custom meta box.

That's about as easy as I can explain the whole process. Just study it, and get your hands dirty with code. The best way to learn is through application rather than theory.

0
votes

The answer was from the same question I asked somewhere else

And I created my version of example

I added some console.log function for testing, but this is basically doning the same thing as @Chris_() answer:

Menu callback function to generate menu content (PHP):

function ajax_menu_callback() {
?>
<div class="wrap">
    <div id="icon-themes" class="icon32"></div>
    <h2>Test</h2>
    <br />
    <form>
        <input id="meta" type ="text" name="1" value="<?php echo esc_html( get_post_meta( 1, 'your_key', true) ); ?>" />
        <?php submit_button(); ?>
    </form>
</div>
<?php
}

Then the javascript to print on the admin side (javascript, don't forget to include a jquery library):

jQuery(document).ready(function() {
    $("form").submit(function() {
        console.log('Submit Function');
        var postMeta = $('input[name="1"]').val();
        console.log(postMeta);
        var postID = 1;
        var button = $('input[type="submit"]');
        button.val('saving......');
        $.ajax({
            data: {action: "update_meta", post_id: postID, post_meta: postMeta, },
            type: 'POST',
            url: ajaxurl,
            success: function( response ) { console.log('Well Done and got this from sever: ' + response); }
        }); // end of ajax()
        return false;
    }); // end of document.ready
}); // end of form.submit

Then the PHP function handle update_post_meta (PHP):

add_action( 'wp_ajax_update_meta', 'my_ajax_callback' );
function my_ajax_callback() {
    $post_id = $_POST['post_id'];
    $post_meta = $_POST['post_meta'];
    update_post_meta( $post_id, 'your_key', $post_meta );
    echo 'Meta Updated';
    die();
} // end of my_ajax_callback()