Add several fields from different tables to post, fields per post are in same row of table

This soluton will create a metabox on your Edit Post screen and show you four additional form fields –

  • Name
  • Position
  • Publications
  • Freetext

It will then save the data in to a corrisponding DB table, with each field in it’s own column as you specified. As you have not provided a table name I have guessed at wp_additional_post_info, but you can change that if you like.

I haven’t provided you with any, but if you want to make the metabox look a bit better you can add some CSS if you wish.


DB Tabe

Here is the DB table wp_additional_post_info. It is set up so that when a post is deleted, related information in this table will also be removed from the DB.

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

CREATE TABLE IF NOT EXISTS `wp_additional_post_info` (
  `post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `name` text NOT NULL,
  `position` text NOT NULL,
  `publications` longtext NOT NULL,
  `freetext` longtext NOT NULL,
  PRIMARY KEY (`post_id`),
  UNIQUE KEY `post_id` (`post_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `wp_additional_post_info`
  ADD CONSTRAINT `Costrain additional post info` FOREIGN KEY (`post_id`) REFERENCES `fgw_2_posts` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION;

PHP

Place this in functions.php (or an external file that is included if you wish).

/**
 * Add a metaboxs
 */
add_action( 'add_meta_boxes', 'my_add_addition_post_info_meta_box' );
function my_add_addition_post_info_meta_box(){

    add_meta_box(
        'my_addition_post_info',                                // ID
        __('Additional Information', 'myplugin_textdomain'),    // Title
        'my_fill_addition_post_info_meta_box',                  // Callback
        'post'                                                  // Post type
    );
    
}

/**
 * Print metabox content
 * 
 * @param required WP_Post $post    The object for the current post/page
 */
function my_fill_addition_post_info_meta_box($post){

    /** Add a nonce field for security */
    wp_nonce_field( 'my_addition_post_info', 'my_addition_post_info_nonce' );
    
    /** Grab the additional info for this post */
    global $wpdb;
    $query = $wpdb->prepare('
        SELECT *
        FROM %1$s AS a
        WHERE a.post_id = %2$s',
        $wpdb->prefix . 'additional_post_info',
        $post->ID
    );
    $info = $wpdb->get_row($query);
    
    /**
     * Output your form fields
     */
    
    echo '<div class="additional-field">';
    echo '<label for="additional-name">Name</label>';
    printf(
        '<input type="text" id="additional-name" name="additional-name" value="%1$s" />',
        $info->name
    );
    echo '</div>';
    
    echo '<div class="additional-field">';
    echo '<label for="additional-position">Position</label>';
    printf(
        '<input type="text" id="additional-position" name="additional-position" value="%1$s" />',
        $info->position
    );
    echo '</div>';
    
    echo '<div class="additional-field">';
    echo '<label for="additional-publications">Publications</label>';
    echo '<textarea type="text" id="additional-publications" name="additional-publications">';
    echo $info->publications;
    echo '</textarea>';
    echo '</div>';
    
    echo '<div class="additional-field">';
    echo '<label for="additional-freetext">Freetext</label>';
    echo '<textarea type="text" id="additional-freetext" name="additional-freetext">';
    echo $info->freetext;
    echo '</textarea>';
    echo '</div>';
    
}

/**
 * Save metabox content
 *
 * @param required integer  $post_id The ID of the post being saved
 */
add_action( 'save_post', 'my_save_addition_post_info_meta_box' );
function my_save_addition_post_info_meta_box( $post_id ) {

    /** Check if the required nonce is set */
    if(!isset($_POST['my_addition_post_info_nonce']))
        return;
    
    /** Verify that the required nonce is valid */
    if (!wp_verify_nonce($_POST['my_addition_post_info_nonce'], 'my_addition_post_info'))
        return;
    
    /** Ensure that this is not an autosave */
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
        return;
    
    /** Ensure that the user has permission to be here */
    if(!current_user_can('edit_post', $post_id))
        return;
    
    /** Finally replace (or create) an entry for this post */
    global $wpdb;
    $table = $wpdb->prefix . 'additional_post_info';
    $data = array(
        'post_id'       => $post_id,
        'name'          => $_POST['additional-name'],
        'position'      => $_POST['additional-position'],
        'publications'  => $_POST['additional-publications'],
        'freetext'      => $_POST['additional-freetext']
    );
    $format = array('%d', '%s', '%s', '%s', '%s');
    $wpdb->replace($table, $data, $format);
    
}