This recipe uses the WordPress built-in meta box system to create a clean interface that will allow users to manage fields specific to custom post types without having to use the cumbersome default Custom Fields editor. As we saw in Chapter 3, User Settings and Administration Pages, custom meta boxes can be created using the add_meta_box function. In addition to declaring the meta box and associating it with the custom post type, add_meta_box defines a callback that is responsible for rendering the contents of the box.
The next section of the recipe implements the function that renders the meta box content. As we can see, this box receives an object variable that contains information about the Book Review that is being displayed in the post editor. Using this object, our code retrieves the post ID and uses it to query the site database for a book author and rating associated with the entry. Once the custom field data has been retrieved from the database, it can be used to render the author and rating fields onscreen. When new Book Reviews are created, both calls to get_post_meta will return an empty string, resulting in the display of an empty text field and the last entry in the drop-down list.
The get_post_meta function is used to retrieve data that was stored in the custom fields section of the post editor and has three parameters:
get_post_meta( $post_id, $field_name, $single );
The first parameter is the post ID, which can easily be retrieved using the get_the_ID() template function. This ID is used to identify the post to which the custom information is associated. The second argument is the custom field name, which should match the name specified when it is created in the post editor. The third and final argument indicates whether the return value should be a single value or an array of values. If set to false, it will produce an array containing a single element even if the custom field only contains a single value. In most cases, it should be set to true to receive a single value that can be accessed directly.
The last steps of this recipe take care of registering a function that will be called when posts of all types are saved or deleted by the site administrator. Since it will deal with all types of data, the saving callback must first check the type of the received post data. If it's a Book Review, the code proceeds to check if the received data is valid and stores the information in the post meta data table. In this recipe, the parameters for the update_post_meta function are similar to the get_post_meta function, except for the third argument, which is used to specify the data to be stored.
One last detail that should be mentioned about this recipe is the use of the fourth parameter of the add_action function when associating a callback to the save_post action hook. This argument indicates that two arguments will be received by the registered callback. If this argument is not set, the callback function will never receive that second piece of data.