Cleanest way to code “Custom Write Panels/Meta Boxes”?

As with anything in WordPress it seems there are 20 way to do something, but after several weeks of extensive searching I really haven’t found more then a couple tutorials floating around that really mirror each other in writing conventions which always makes me a little uneasy when this is the way I learn so I wanted to make a post and ask you guys, the community, what you think?….

Even if you just have a favorite resource such as a tutorial on the web, that would be very useful. I feel Like Ive combed over them all, but often it seems like asking a specific group of experienced people typically renders better results so here I am.

Read More

*PS – Ive tried DeluxeBlogs class, and it worked fine, but at the moment what Im really trying to do is learn the most “correct” way to go about writing my own meta boxes from scratch.

Thanks,
SB

—– EDIT 1 : Example of one of my current meta boxes —–

<?php
// Register Custom Post Type Meta Boxes -- Description Field
add_action( 'add_meta_boxes', 'store_description_meta_box_add' );
function store_description_meta_box_add()
{
    add_meta_box( 'epr_store_description_meta_id', 'Product Description', 'store_description_meta_box_cb', 'epr_store', 'normal', 'high' );
}

function store_description_meta_box_cb( $post )
{
    $values = get_post_custom( $post->ID );
    $textbox = isset( $values['meta_box_description_text'] ) ? esc_attr( $values['meta_box_description_text'][0] ) : '';
    wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );
    ?>
        <textarea name="meta_box_description_text" id="meta_box_description_text" style="width:100%; height:100px;text-align:left;">
            <?php echo $textbox; ?>
        </textarea>
    <?php   
}

add_action( 'save_post', 'epr_description_meta_box_save' );
function epr_description_meta_box_save( $post_id )
{
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
    if( !current_user_can( 'edit_post' ) ) return;

    $allowed = array( 
        'a' => array( 
            'href' => array() 
        )
    );

    if( isset( $_POST['meta_box_description_text'] ) )
        update_post_meta( $post_id, 'meta_box_description_text', wp_kses( $_POST['meta_box_description_text'], $allowed ) );
}
?>

—– EDIT 2 : Example of how to remove indentation after saving w/ Chris’ help —–

<?php
// Register Custom Post Type Meta Boxes -- Description Field
add_action( 'add_meta_boxes', 'store_description_meta_box_add' );
function store_description_meta_box_add()
{
    add_meta_box( 'epr_store_description_meta_id', 'Product Description', 'store_description_meta_box_cb', 'epr_store', 'normal', 'high' );
}

function store_description_meta_box_cb( $post )
{
    $values = get_post_custom( $post->ID );
    $textbox = isset( $values['meta_box_description_text'] ) ? esc_attr( $values['meta_box_description_text'][0] ) : '';
    wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );
    ?>
        <textarea name="meta_box_description_text" id="meta_box_description_text" style="width:100%; height:100px;text-align:left;"><?php echo esc_attr($textbox); ?></textarea>
    <?php   
}

add_action( 'save_post', 'epr_description_meta_box_save' );
function epr_description_meta_box_save( $post_id )
{
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
    if( !current_user_can( 'edit_post' ) ) return;

    $allowed = array( 
        'a' => array( 
            'href' => array() 
        )
    );

    if( isset( $_POST['meta_box_description_text'] ) )
        update_post_meta( $post_id, 'meta_box_description_text', wp_kses( $_POST['meta_box_description_text'], $allowed ) );
}
?>

Related posts

Leave a Reply

2 comments

  1. I have a sort of “plugin library” that contains a base class for meta boxes. Basically all it contains are a bunch of methods that generate form fields and some tabbed navigation stuff that I do for meta boxes that contain a lot of stuff. This just let’s me more rapidly develop the meta box without having to worry about coding form fields for hours.

    I’ll use that as a parent class for a class that actually adds the meta boxes. That class would look something like this:

    <?php
    class wpseMetaBox extends davispressMetaBoxTools
    {
        function __construct()
        {
            add_action( 'add_meta_boxes', array( &$this, 'add_meta_box' ) );
            add_action( 'save_post', array( &$this, 'save' ), 10, 1 );
            add_action( 'load-edit.php', array( &$this, 'add_styles_scripts' ) );
            add_action( 'load-post-new.php', array( &$this, 'add_styles_scripts' ) );
        }
    
        function add_meta_box()
        {
            add_meta_box( 'some-metabox', 'Meta Box Title', array( &$this, 'meta_box_cb' ), 'post' );
        }
    
        function meta_box_cb( $post )
        {
            wp_nonce_field( 'wpse_nonce', 'wpse_nonce' );
            // add fields here
            $o = $this->textinput( '_some_id', 'Some Label', $post->ID );
            echo $this->form_table( $o );
            // etc.
        }
    
        function save( $post_id )
        {
            // verify we can do this
            if( ! isset( $_REQUEST['wpse_nonce'] ) || ! wp_verify_nonce( $_REQUEST['wpse_nonce'], 'wpse_nonce' ) ) return;
            if( ! current_user_can( 'edit_post' ) ) return;
    
            // save data
            if( isset( $_REQUEST['_some_id'] ) )
                update_post_meta( $post_id, '_some_id', esc_attr( $_REQUEST['_some_id'] ) );
        }
    
        function add_styles_scripts()
        {
            // check and see if we're on the post type with the meta box
            if( ( isset( $_REQUEST['post'] ) && 'post' == get_post_type( $_REQUEST['post'] ) ) || ( isset( $_REQUEST['post_type'] ) && 'post' == $_REQUEST['post_type'] ) ) 
            {
                add_action( 'admin_print_scripts', array( &$this, 'scripts' ) );
                add_action( 'admin_print_styles', array( &$this, 'styles' ) );
            }
        }
    
        function scripts()
        {
            // wp_enqueue_script here
        }
    
        function styles()
        {
            // wp_enqueue_style here
        }
    }
    

    The most painful part of creating a meta box is writing the actual meta box call back function that outputs all the contents. It takes the longest, and it seemed like that was the thing that could most easily be more abstracted. So that’s what I did. Other people will probably have much different opinions.

    All that said: sometimes meta boxes (and any other part of a plugin/theme) don’t fit into the mold. You have to know when to abandon the stuff that makes it easy in favor of what the situation demands. Don’t get locked into your tools just because you created them.

    This tutorial might interest you as well. It doesn’t have anything like the above, just a basic how to.

  2. I’m not big on plugins when editing the theme function file is an option, but the More Fields plugin saves so much time, that I use that instead. It’s quick, easy, and gives me a lot of options in creating different types of fields grouped in metaboxes that can be assigned to specific post types.