Blog / WordPress/ Add Front-End Submission for Custom Post Type Taxonomies with Pure Code

Add Front-End Submission for Custom Post Type Taxonomies with Pure Code

WordPress 纯代码实现:为自定义文章类型分类法添加前端投稿功能

Many themes or plugins create custom post types (like 'Website', 'Product') and their associated taxonomies (like 'Website Category'). Sometimes, you need to allow front-end users to submit posts to these custom taxonomies, not just the default 'Post' type. This article explains how to implement this feature using pure code.

Core Implementation Principle

WordPress provides the powerful wp_insert_post() function to create posts of any type. The key is correctly setting its parameters, especially post_type and tax_input.

Key Code Example

The following code handles form submission, creates a pending custom post, and associates it with a specified term. Place it in your theme's functions.php or a custom plugin.

function handle_cpt_submission() {
    // 1. Security: verify nonce
    if ( ! isset( $_POST['submit_nonce'] ) || ! wp_verify_nonce( $_POST['submit_nonce'], 'cpt_submit_action' ) ) {
        wp_die( 'Security check failed.' );
    }

    // 2. Sanitize and validate data
    $post_title   = sanitize_text_field( $_POST['post_title'] ?? '' );
    $post_content = wp_kses_post( $_POST['post_content'] ?? '' );
    $term_id      = absint( $_POST['term_id'] ?? 0 );

    if ( empty( $post_title ) || empty( $post_content ) || $term_id <= 0 ) {
        wp_die( 'Please fill all required fields.' );
    }

    // 3. Assemble post data
    $new_post = array(
        'post_type'    => 'your_cpt', // Replace with your CPT name
        'post_title'   => $post_title,
        'post_content' => $post_content,
        'post_status'  => 'pending', // Set to 'pending' for moderation
        'tax_input'    => array(
            'your_taxonomy' => array( $term_id ), // Replace with your taxonomy name
        ),
    );

    // 4. Insert post
    $post_id = wp_insert_post( $new_post, true );

    // 5. Handle result
    if ( is_wp_error( $post_id ) ) {
        wp_die( 'Submission failed: ' . $post_id->get_error_message() );
    } else {
        wp_safe_redirect( home_url( '/thank-you/' ) );
        exit;
    }
}
add_action( 'admin_post_nopriv_cpt_submit', 'handle_cpt_submission' );
add_action( 'admin_post_cpt_submit', 'handle_cpt_submission' );

Front-End Form Essentials

Create a form whose action points to admin-post.php with a hidden action parameter matching the hook above.

<form method='post' action='<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>'>
    <?php wp_nonce_field( 'cpt_submit_action', 'submit_nonce' ); ?>
    <input type='hidden' name='action' value='cpt_submit'>

    <label for='post_title'>Title:</label>
    <input type='text' id='post_title' name='post_title' required>

    <label for='post_content'>Content:</label>
    <textarea id='post_content' name='post_content' required></textarea>

    <label for='term_id'>Select Category:</label>
    <?php
    wp_dropdown_categories( array(
        'taxonomy'         => 'your_taxonomy', // Replace
        'name'             => 'term_id',
        'show_option_none' => 'Select',
        'required'         => true,
        'value_field'      => 'term_id',
    ) );
    ?>

    <input type='submit' value='Submit'>
</form>

Important Notes & Security

  • Permission Control: The admin_post_* hooks are a standard, secure way to handle front-end forms.
  • Data Validation: Always sanitize user input with functions like sanitize_text_field(), wp_kses_post(), and absint() to prevent XSS and SQL injection.
  • Nonce Verification: wp_nonce_field() and wp_verify_nonce() prevent CSRF attacks.
  • Replace Names: Change your_cpt and your_taxonomy to your actual registered post type and taxonomy names.
  • Status Management: Setting post_status to pending allows admin moderation before publishing.

Following these steps, you can build a secure, reliable front-end submission system for custom post types and taxonomies.

Post a Comment

Your email will not be published. Required fields are marked with *.