Custom Admin Fields

Input fields on WordPress add/edit admin screens are called custom fields. Custom field data is called metadata.

Custom fields are displayed inside meta boxes, containers which can be placed on WP add/edit admin screens. When a post is updated, all custom field data is sent along with the post data to be processed server-side.


More Resources


Custom field values stored in the database are called metadata. Metadata are key-value pairs of data that are attached to WordPress object types (posts, comments, users, terms, etc). Each object type instance is stored respectively as a row in it’s own database table wp_posts, wp_comments, wp_users, etc. Metadata for object types are also stored respectively in their own tables wp_postmeta, wp_commentmeta, wp_usermeta, etc. The only object type in WordPress which does not have metadata is the link.

Metadata tables all have a meta_key and meta_value column as well as a {obj type}_id column to key the metadata entry to the parent post, and an auto-incrementing id column.

Read and Write

The get_post_meta() and update_post_meta() WP functions are used to read and write metadata to the database. Both functions take the parent post ID, the key, and the value as parameters.

NOTE: WordPress has some peculiar behavior around metadata keys. Multiple metadata keys for a post can have the same name.



Param Type Req Notes
$post_id int required The Post ID.
$key string optional The name of the meta key to retrieve. By default, returns data for all keys associated to the post. Meta keys are case-sensitive.
Default value: ”
$single bool optional Whether to return a single value.
Default value: false
returns mixed Will be an array of meta key-value pairs if $single is false. Will be the value of the meta data field if $single is true.

Add a Meta Box

To create custom fields a meta box must first be created by calling the add_meta_box() function and defining the post type(s) it should belong to.

The following code can be added to the functions.php file of a theme to create a Settings meta box which will display on the add/edit screens for the post post-type:

 * Add the new `settings` meta box to the 'post' post-type.
function prefix_add_settings_meta_box()
        'prefix_post_settings_meta_box', // $id Unique ID of the meta box.
        'Settings', // $title Title of the meta box.
        'prefix_display_post_settings_fields', // $callback Name of the function which displays the meta box fields.
        'post', // $screen Post-type this meta box is assigned-to.
        'normal', // $context
        'high' // $priority
add_action('add_meta_boxes', 'prefix_add_settings_meta_box');

// Display the `settings` meta box content.
function prefix_display_post_settings_fields($post, $args)
    echo 'Hello!';



Param Type Req Notes
$id string yes The unique ID for the meta box. (used in the ‘id’ attribute for the meta box).
$title string yes The display title of the meta box. This value can/should be internationalized.
$callback callable yes Name of the function which defines the meta box content. The function should echo its output.
$screen string/array no The post-type ID(s) of the page(s) where the meta box will be displayed. This value can be a single post-type ID, page (screen) ID, WP_Screen object, or an array of IDs.
Default value: null
$context string no Defines the section of the page where the meta box should be placed (normal, advanced, or side). Other contexts vary from screen to screen. Comments screen contexts include ‘normal’ and ‘side’. Menus meta boxes (accordion sections) all use the ‘side’ context.
Default value: ‘advanced’
$priority string no Specifies the order within the section where the meta box will be placed (high, core, default, or low).
Default value: ‘default’
$callback_args array no An array of arguments ($args) that can be passed to the callback function.
Default value: null

Add Fields

The name of a callback function is passed to the add_meta_box() method. The callback function prints the HTML content of the meta box.

 * Prints the `settings` meta box content.
 * @param object $post The current WP post object. Basically the values
 *                     of the `wp_posts` DB table row for the post.
 * @param array  $args Info about the parent meta box as well as any
 *                     callback args passed to the WP `add_meta_box`
 *                     function.
 * @return void
function prefix_display_post_settings_fields($post, $args)
    // Get field data from the DB.
    $meta = get_post_meta($post->ID, 'prefix_post_settings_fields', true);

    // Begin the HTML output.
    $html = array();
    // Create a hidden nonce field for added security.
    $html[] = '<input type="hidden" name="post_settings_meta_box_nonce" value="' . wp_create_nonce(basename(__FILE__)) . '">';
    // Create the label and input field for the `prefix_first_name` field.
    $html[] = '<label for="prefix_post_settings_fields[first_name]">First Name</label>';
    $html[] = '<input type="text" name="prefix_post_settings_fields[first_name]" id="prefix_post_settings_fields[first_name]" class="regular-text" value="' . $this->meta_key($meta, 'first_name') . '">';
    // Create the label and input field for the `prefix_last_name` field.
    $html[] = '<label for="prefix_post_settings_fields[last_name]">Last Name</label>';
    $html[] = '<input type="text" name="prefix_post_settings_fields[last_name]" id="prefix_post_settings_fields[last_name]" class="regular-text" value="' . $this->meta_key($meta, 'last_name') . '">';
    echo '<pre>';
    echo '</pre>';
    // Print the HTML to the screen.
    return print implode("\n", $html);