Create a new book info field

⌘K
  1. Home
  2. Developers
  3. Tutorials
  4. Create a new book info field

Create a new book info field

There are four steps to creating a new custom book info field:

  1. Adding a new option in the “Book Layout” in Books > Settings > Book Layout. This is where you are able to add the new field to your template.
  2. Creating a new box on the Add/Edit Book page where you can enter the value.
  3. Saving that value to the database when saving the book.
  4. Displaying the value on the front-end.

This tutorial will walk you through all four steps. All our code will be stored in a new plugin. (If you just want to see the final code, you can find it  on GitHub.)

For this example, we’ll be creating a new text field for “Cover Artist”.

Create your plugin files.

Create a new folder for your plugin. I’ll be calling this one novelist-cover-artist. Then, inside that folder, create a new PHP file with the same name. Mine is called novelist-cover-artist.php. Inside that file, create your plugin header. Here’s mine:

<?php
/*
 * Plugin Name: Novelist Cover Artist
 * Plugin URI: https://novelistplugin.com
 * Description: Adds a new field in the Novelist plugin for Cover Artist.
 * Version: 1.0
 * Author: Nose Graze
 * Author URI: https://www.nosegraze.com
 * License: GPL2
 * 
 * @package novelist-cover-artist
 * @copyright Copyright (c) 2016, Nose Graze Ltd.
 * @license GPL2+
*/

Adding a new option in the book layout.

To add a new available field, we use the novelist/book/available-fields filter. Here’s how it looks:

/**
 * Add the "Cover Artist" field to the available book layout options.
 *
 * @param array $fields
 *
 * @return array
 */
function novelist_cover_artist_field( $fields ) {
	$fields['cover_artist'] = array(
		'name'        => __( 'Cover Artist', 'novelist-cover-artist' ),
		'placeholder' => '[cover_artist]',
		'label'       => sprintf( __( '<strong>Cover Artist:</strong> %s', 'novelist-cover-artist' ), '[cover_artist]' ),
		'linebreak'   => 'on'
	);

	return $fields;
}

add_filter( 'novelist/book/available-fields', 'novelist_cover_artist_field' );

There are four attributes to include (one is optional):

  1. name – The name of the field. Only used internally.
  2. placeholder – This is what the author will be using in the template as a placeholder for the value. Create your own shortcode that relates to the field.
  3. label – The default label. This can then be customized in the “Book Layout” settings area.
  4. linebreak – Set to ‘on’ if you want the line break checked on by default. Otherwise you can set it to false or omit the parameter completely.

Once this is added, your new field will become available in the “Book Layout” settings area.

Available book fields

Create input box in the Add/Edit Book page

Now we need to create a new text box on the Add/Edit Book page. We can do this with the novelist/meta-box/display-field-$key action, where $key is the array key you set in the previous step (see $fields['cover_artist'] – where cover_artist is the key).

Here’s how it looks:

/**
 * Render the admin area text box
 *
 * @param Novelist_Book $book     Book object.
 * @param WP_Post       $post     Current post object.
 * @param array         $settings Array of settings for this field. Includes the 'label' and 'linebreak'.
 *
 * @return void
 */
function novelist_cover_artist_text_box( $book, $post, $settings ) {
	?>
	<div class="novelist-box-row">
		<label for="novelist_cover_artist"><?php _e( 'Cover Artist', 'novelist' ); ?></label>
		<div class="novelist-input-wrapper">
			<input type="text" id="novelist_cover_artist" name="novelist_cover_artist" value="<?php echo esc_attr( $book->get_value( 'novelist_cover_artist' ) ); ?>">
		</div>
	</div>
	<?php
}

add_action( 'novelist/meta-box/display-field-cover_artist', 'novelist_cover_artist_text_box', 10, 3 );

This action takes in three attributes:

  1. $book – The Novelist_Book object for the current post.
  2. $post – The WP_Post object for the current post.
  3. $settings – The settings related for your field (includes the ‘label’ and ‘linebreak’ settings saved in the Book Layout page).

In this function you simply need to include any HTML you want for rendering the admin page. The above example is for a simple text field.

The most important things you need are:

  1. Some sort of input field with a “name” attribute. Mine is set to novelist_cover_artist. You’ll need this later when saving and displaying the value.
  2. You need to display the value. In an input field like above, this is done in the “value” attribute. You can either do this yourself using something like:

    $value = get_post_meta( $post->ID, 'novelist_cover_artist', true );

    Or you can use the $book object to help you out. This is just a wrapper for get_post_meta anyway. Example:

    $value = $book->get_value( 'novelist_cover_artist' );

    In both cases, you should pass in the same key used in the “name” attribute.

Book meta field

Save the value.

We have our text box, but now we need to save it. All we have to do is add our “name” attribute value to a list of fields to be saved:

/**
 * Add 'novelist_cover_artist' as a field to be saved.
 *
 * @param array $fields Array of name attributes to be located in $_POST and saved.
 *
 * @return array
 */
function novelist_add_cover_image_to_save( $fields ) {
	$fields[] = 'novelist_cover_artist';

	return $fields;
}

add_filter( 'novelist/book/meta-box/saved-fields', 'novelist_add_cover_image_to_save' );

This alone will save our field, but it won’t sanitize it. In order to make sure the value is safe, we need one more function for sanitization. Each value to be saved gets passed into a filter called novelist/book/meta-box/sanitize/$name where $name is the “name” attribute value (in our case, novelist_cover_artist). All you have to do is add your desired sanitization function to that filter like so:

/**
 * Sanitize our field with 'sanitize_text_field'.
 */
add_filter( 'novelist/book/meta-box/sanitize/novelist_cover_artist', 'sanitize_text_field' );

Display the value on the front-end

The final step is to get the associated label, replace the placeholder with the actual value, and display it all on the front-end. We simply need to populate the value with the novelist/book/pre-render/$key filter.

/**
 * Render Cover Artist
 *
 * @param string        $value          Current value for this field
 * @param string        $key            The key that is being filtered
 * @param array         $all_fields     All available book fields
 * @param array         $enabled_fields Array of the enabled book fields
 * @param Novelist_Book $book           Object for the current book
 *
 * return string
 */
function novelist_render_cover_artist( $value, $key, $all_fields, $enabled_fields, $book ) {

	$value = $book->get_value( 'novelist_cover_artist' );

	return $value;

}

add_filter( 'novelist/book/pre-render/cover_artist', 'novelist_render_cover_artist', 10, 5 );

All you need to do is retrieve the value of your field (the same way you retrieved it in the previous step) and return that. Novelist will automatically swap out the placeholder for this value and apply any line breaks if necessary.

Custom field display

View or download all the code

You can see the full code on GitHub:  https://gist.github.com/nosegraze/0536a269bdf90463ecd6f025f2ec2546

Feel free to use it as a starting point for creating your own fields.

Was this article helpful to you? No Yes

How can we help?