How to make a relationship between books and authors?

To build relationships, I know of two plugins, both very well coded and maintained:

  • Posts 2 Posts

    Efficient many-to-many connections between posts, pages, custom post types, users.

  • Advanced Custom Fields – this one would need the add-on Users Select, but as the plugin is being completely rewritten and will change the add-on management, it would be better to wait until version 4.0 is released.

    Fully customise WordPress edit screens with powerful fields. Boasting a professional interface and a powerfull API, it’s a must have for any web developer working with WordPress.


But I think a simple plugin can be built for that:

1. Add a Meta Box in the Posts screen to select an author to the book (not the post author).

/* Define the custom box */
add_action( 'add_meta_boxes', 'authors_meta_box_wpse_89134' );

/* Do something with the data entered */
add_action( 'save_post', 'save_postdata_wpse_89134', 10, 2 );

function authors_meta_box_wpse_89134() 
{
    add_meta_box(
        'sectionid_wpse_89134',
        __( 'Book authors' ), 
        'authors_box_wpse_89134',
        'post'
    );
}

function authors_box_wpse_89134() 
{
    global $post;

    $selected_user = get_post_meta( $post->ID, 'users_dropdown', true);
    $users_list = get_users();

    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'noncename_wpse_89134' );

    echo '<div class="element">
        <select name="users_dropdown" id="users_dropdown">
        <option value="">- Select -</option>';

    foreach( $users_list as $user ) {
          echo '<option value="'.$user->ID.'" ' . selected( $selected_user, $user->ID, false ) . '>'.$user->data->display_name.'</option>';
    }

    echo '</select></div>';
}

function save_postdata_wpse_89134( $post_id, $post_object ) 
{
    // verify if this is an auto save routine. 
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )  
        return;
        
    // verify this came from the our screen and with proper authorization,
    if ( !isset( $_POST['noncename_wpse_89134'] ) || !wp_verify_nonce( $_POST['noncename_wpse_89134'], plugin_basename( __FILE__ ) ) )
        return;

    // Correct post type
    if ( isset( $_POST['post_type'] ) && 'post' != $_POST['post_type'] ) 
        return;

    // OK, we're authenticated: we need to find and save the data
    
    //sanitize user input
    $u_id = ( isset( $_POST['users_dropdown'] ) ) ? intval( $_POST['users_dropdown'] ) : false;

    if( $u_id )
        update_post_meta( $post_id, 'users_dropdown', $_POST['users_dropdown'] );
    else
        delete_post_meta( $post_id, 'users_dropdown' );
}

2. Display the author’s book in the profile and edit user pages

add_action( 'show_user_profile', 'user_books_wpse_89134' );
add_action( 'edit_user_profile', 'user_books_wpse_89134' );

function user_books_wpse_89134( $user ) 
{
    $args = array(
        'post_type' => 'post',
        'meta_key'=>'users_dropdown',
        'meta_value'=>$user->ID,
        'meta_compare'=>'='
    );

    $the_query = new WP_Query( $args );
    
    echo '<h3>'. __('User books') .'</h3>';
    while ( $the_query->have_posts() ) :
        $the_query->the_post();
        echo '<li>' . get_the_title() . '</li>';
    endwhile;
}

Leave a Comment