wordpresscustom-post-typemeta-boxes

How can I save a custom post type with metaboxes from front end


I have registered a custom post type named fav_songs in functions.php. It has three metaboxes defined - Artist, Genre and Year of Release. I am able to save data from admin interface. Now I want to do the similar thing from front end.

For this I first created the following template file:

<?php
/* Template Name: Song Entry Form */
get_header();
?>

<form id="song-entry" name="song-entry" method="post" action="">
    <p>
        <label>Title</label><br />
        <input type="text" id="song_title" name="song_title" />
    </p>
    <p>
        <label>Description</label><br />
        <input type="text" id="song_desc" name="song_desc" />
    </p>
    <p>
        <label>Artist</label><br />
        <input type="text" id="song_artist" name="song_artist" />
        <input type="hidden" name="post_type" id="post_type" value="post" />
        <input type="hidden" name="action" value="post" />
    </p>
    <p>
        <input type="submit" value="Submit" />
    </p>
    <?php wp_nonce_field( 'new_song_nonce' ); ?>
</form>

<?php
    function save_song()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && !empty($_POST['action'])) {
            if (!isset($_POST['new_song_nonce'])) {
                return;
            }
            if (!isset($_POST['song_title'])) {
                return;
            }
            if (!isset($_POST['song_desc'])) {
                return;
            }

            $post = array(
                'post_title' => $_POST['song_title'],
                'post_content' => $_POST['song_desc'],
                'post_type' => 'fav_songs'
            );

            wp_insert_post($post);
            update_post_meta($post->ID, '_song_artist_name', $_POST['song_artist']);
        }
    }
?>

<?php
get_footer();
?>

In my functions.php I hooked save_post action for save_song.

add_action('save_post', 'save_song');

then I added a page in admin and used the above template file. When the page renders the all fields are coming up. But when I hit submit nothing gets saved in wp_posts and wp_postmeta. For now I only want to store title and description in wp_posts table and meta data artist in wp_postmeta table.

Something must have gone wrong in my above approach but I don't know what! I have started learning WordPress recently. What can I try next?

Update

Modified template page code:

<?php
/* Template Name: Song Entry Form */
get_header();

if($_POST['post_submit'] == 'Submit') {
    $args = array(
        'post_title' => $_POST['post_title'],
        'post_content' => $_POST['post_desc'],
        'post_type' => 'fav_songs',
        'post_status' => 'publish',
        'comment_status' => 'closed',
        'ping_status' => 'closed'
    );

    $pid = wp_insert_post($args);
    add_post_meta($pid, "_song_artist", $_POST['post_artist']);
}

?>

<form id="post_entry" name="post_entry" method="post" action="<?php echo get_page_link('354') ?>">
    <p>
        <label>Title</label><br />
        <input type="text" id="post_title" name="post_title" />
    </p>
    <p>
        <label>Description</label><br />
        <input type="text" id="post_desc" name="post_desc" />
    </p>
    <p>
        <label>Artist</label><br />
        <input type="text" id="post_artist" name="post_artist" />
        <input type="hidden" name="post_type" id="post_type" value="fav_songs" />
        <input type="hidden" id="post_action" name="post_action" value="post" />
    </p>
    <p>
        <input type="submit" name="post_submit" value="Submit" />
    </p>
    <?php wp_nonce_field( 'new_song_nonce' ); ?>
</form>

<?php
get_footer();
?>

I checked View Source. The form now renders as:

<form id="post-entry" name="post-entry" method="post" action="http://local.tourplanner.com/add-song/">...</form>

Even with the action set to a specific page why I am jumping back to homepage without saving any data?


Solution

  • All form elements should always be prefixed with something unique to prevent clashes. In your form we put common prefix 'post_' and it is working:

    Try below code:

    On same page you can get form field and insert into db:

    you can further use generated post id for save custom meta.

    if($_POST['post_submit']=='Submit'){
            ;
     $id = wp_insert_post(array('post_title'=>$_POST['post_title'], 'post_type'=>'fav_songs', 'post_content'=>$_POST['post_desc'],'post_status' => 'publish','comment_status' => 'closed','ping_status' => 'closed'));
            }
    
    
    
    <form id="song-entry" name="post_entry" method="post" action="<?php echo get_page_link('your template id') ?>">
    <p>
        <label>Title</label><br />
        <input type="text" id="post_title" name="post_title" />
    </p>
    <p>
        <label>Description</label><br />
        <input type="text" id="post_desc" name="post_desc" />
    </p>
     <p>
        <label>Artist</label><br />
        <input type="text" id="post_artist" name="post_artist" />
        <input type="hidden" name="post_type" id="post_type" value="post_type" />
        <input type="hidden" name="post_action" id="post_action" value="post_action" />
    </p>
    <p>
        <input type="submit" name="post_submit" value="Submit" />
    </p>
    <?php wp_nonce_field( 'new_song_nonce' ); ?>