Front end form to create a custom post with preview

admin2025-06-03  2

how can i achieve a front end form with preview option to create custom post based on the input? I want it done without any plugin. A simple example will help a lot.


This is not a ACF question but ACF is having a front end form functionality but does not have preview function.

Is it possible to get the id for form being filled so that it can be passed to

get_preview_post_link( int|WP_Post $post = null, array $query_args = array(), string $preview_link = '' ) 

It tried get the get_the_ID() but it add's the id of page where form is placed. Also the id of the page get generated after form field is generated.

The form is for registered and logged in users. May be if i am able to get a solution to get the id of the post that form generates i will be good position to go further.But the problem is that form generates ID after submission so i can't pass to get_preview_post_link()

Thanks

how can i achieve a front end form with preview option to create custom post based on the input? I want it done without any plugin. A simple example will help a lot.


This is not a ACF question but ACF is having a front end form functionality but does not have preview function.

Is it possible to get the id for form being filled so that it can be passed to

get_preview_post_link( int|WP_Post $post = null, array $query_args = array(), string $preview_link = '' ) 

It tried get the get_the_ID() but it add's the id of page where form is placed. Also the id of the page get generated after form field is generated.

The form is for registered and logged in users. May be if i am able to get a solution to get the id of the post that form generates i will be good position to go further.But the problem is that form generates ID after submission so i can't pass to get_preview_post_link()

Thanks

Share Improve this question edited Aug 18, 2018 at 10:16 asked Aug 15, 2018 at 22:39 user145078user145078 4
  • 1 worddpress do not have front end forms (well, except for comment) so not sure what are you referring to – Mark Kaplun Commented Aug 18, 2018 at 8:15
  • @MarkKaplun sorry i entered the details incorrectly. i want a form which creates custom post based on entries. – user145078 Commented Aug 18, 2018 at 8:51
  • that sounds more wordpress-y but in that case what is the actual problem you are facing? I assume it is not writing the logic of form itself. So where is the issue here, is it in how to give preview access to unpublished content or something else? Maybe some additional context is also missing (who is using that form, users or anonymous people... what is the context in which the preview should be displayed... whatever you think is applicable and relevant. The more data there is the more likely people can suggest other paths than you thought of. – Mark Kaplun Commented Aug 18, 2018 at 9:10
  • @MarkKaplun The form is for registered and logged in users. May be if i am able to get a solution to get the id of the post that form generates i will be good position to go further.But the problem is that form generates ID after submission so i can't pass to get_preview_post_link() – user145078 Commented Aug 18, 2018 at 10:16
Add a comment  | 

4 Answers 4

Reset to default 4 +50

There are many ways you could use to reach your goal. Here's one...

Steps:

  1. Create a shortcode that renders the form.
  2. Create and enqueue a JavaScript file that handles the form submission.
  3. Create PHP function for creating/updating Post/Custom Post.

In your functions.php:

/**
 * @return  string  $html   HTML form.
 */
function shortcode__new_post_form() {
    /**
     * @var     WP_User $current_user
     */
    $current_user = $GLOBALS['current_user'];

    ob_start(); ?>
    <form action="" id="form-new-post">
        <fieldset>
            <legend>NEW AWESOME POST</legend>
            <div class="form-group">
                <input type="text" class="form-control" name="post_title" required/>
            </div>
            <input type="hidden" name="ID" value=""/>
            <input type="hidden" name="post_author" value="<?php echo $current_user->ID; ?>"/>
            <button type="submit"
                    class="submit"
                    data-is-updated="false"
                    data-is-update-text="UPDATE">CREATE
            </button>
        </fieldset>
        <a href=""
           class="preview-link"
           target="_blank"
           style="display: none;"
           rel="nofollow">Preview Link</a>
    </form>
    <?php
    $html = ob_get_clean();

    return $html;
}

function script__new_post_form() {
    wp_enqueue_script(
        'new-post-form',
        // Insert here your JavaScript file URL,
        array( 'jquery' ),
        '1.0.0',
        true
    );

    wp_localize_script(
        'new-post-form',
        'localized_new_post_form',
        array(
            'admin_ajax_url' => admin_url( 'admin-ajax.php' ),
        )
    );
}

function maybe_insert_new_post() {
    /**
     * @var     array $r Initialize response variable.
     */
    $r = array(
        'error'        => '', // Error message.
        'html'         => '', // Any message/HTML you want to output to the logged in user.
        'preview_link' => '', // Preview link URL.
        'post'         => '' // The created/updated post.
    );

    /**
     * @link    https://developer.wordpress/reference/functions/wp_insert_post/
     */
    $postarr = array(
        'ID'          => '', // If ID stays empty the post will be created.
        'post_author' => '',
        'post_title'  => 'My name is Optimus Prime',
        'post_status' => 'draft',
        'post_type'   => 'post',
        'meta_input'  => array( // Delete this line if you won't use it!
            'your_NON_acf_meta_field_key' => 'your_NON_acf_meta_field_value'
        )
    );

    parse_str( $_POST['form_data'], $form_data );

    $postarr = array_merge( $postarr, $form_data );

    /**
     * wp_insert_post can either create posts or update existing ones, if ID is passed!
     *
     * @link    https://developer.wordpress/reference/functions/wp_insert_post/
     *
     * @param   array $postarr An array of elements that make up a post to update or insert.
     * @param   bool $wp_error Whether to return a WP_Error on failure.
     *
     * @return  int|WP_Error    The post ID on success. The value 0 or WP_Error on failure.
     */
    $new_post = wp_insert_post(
        $postarr,
        true
    );

    // Post was not created/updated, so let's output the error message.
    if ( is_wp_error( $new_post ) ) {
        $r['error'] = $new_post->get_error_message();

        echo json_encode( $r );

        exit;
    }

    $post_id = $new_post; // Just for reference.

    /**
     * To save ACF fields use update_field() function. It doesn't matter if it's text field, repeater field, etc.
     * Make sure the field exists in admin area.
     * Use update_field() as many times as you want.
     *
     * @link    https://www.advancedcustomfields/resources/update_field/
     */
    update_field( 'your_acf_meta_key', 'field_value', $post_id );
//  update_field( 'your_acf_meta_key', 'field_value', $post_id );
//  update_field( 'your_acf_meta_key', 'field_value', $post_id );

    /**
     * @link    https://developer.wordpress/reference/functions/get_preview_post_link/
     */
    $preview_link = get_preview_post_link( $post_id );

    if ( $preview_link ) {
        $r['preview_link'] = $preview_link;
    }

    // Gets post info in array format as it's easier to debug via console if needed.
    $post_array = get_post( $post_id, ARRAY_A );

    if ( $post_array ) {
        $r['post'] = $post_array;
    }

    echo json_encode( $r );

    exit;
}

// Ads shortcode so you can use the form anywhere you want.
add_shortcode( 'new_post_form', 'shortcode__new_post_form' );

// Use wp_enqueue_scripts action hook so you can correctly localize the script with admin ajax URL.
add_action( 'wp_enqueue_scripts', 'script__new_post_form' );

// Prefix 'wp_ajax_' is mandatory.
add_action( 'wp_ajax_new_post', 'maybe_insert_new_post' );

Create a JavaScript file and write in it (don't forget to put its URL in your functions.php):

(function ($) {

    var el_form = $('#form-new-post'),
        el_form_submit = $('.submit', el_form);

    // Fires when the form is submitted.
    el_form.on('submit', function (e) {
        e.preventDefault();

        el_form_submit.attr('disabled', 'disabled');

        new_post();
    });

    // Ajax request.
    function new_post() {
        $.ajax({
            url: localized_new_post_form.admin_ajax_url,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'new_post', // Set action without prefix 'wp_ajax_'.
                form_data: el_form.serialize()
            },
            cache: false
        }).done(function (r) {
            if (r.post !== '' && r.preview_link !== '') {
                $('[name="ID"]', el_form).attr('value', r.post.ID);
                $('.preview-link', el_form)
                    .attr('href', r.preview_link)
                    .show();
                el_form_submit.attr('data-is-updated', 'true');
                el_form_submit.text(el_form_submit.data('is-update-text'));
            }

            el_form_submit.removeAttr('disabled');
        });
    }

    // Used to trigger/simulate post submission without user action.
    function trigger_new_post() {
        el_form.trigger('submit');
    }

    // Sets interval so the post the can be updated automatically provided that it was already created.
    setInterval(function () {
        if (el_form_submit.attr('data-is-updated') === 'false') {
            return false;
        }

        trigger_new_post();
    }, 5000); // Set to 5 seconds.

})(jQuery);

Now, create a new page and insert the shortcode [new_post_form] in it. Open the page and test your form.

If it works for you, please accept my answer as your solution.

how can i achieve a front end form with preview option to create custom post based on the input? I want it done without any plugin.

without a plugin its not possible unless you're going to do a lot of custom coding which is equivalent to getting a plugin.

The only way you can achieve this without using a plugin is to use the post creation/preview mechanism already available in WP, that is the admin Dashboard. Use a plugin such as Adminimize to fine tune your user's privileges or make a new custom role for them, allowing them to create new posts and review them from the backend dashboard but limiting/removing other dashboard menu items so they only have access to what they need.

You need to create post as draft for preview. You can use this form, function and ajax script for this.

First standart form for new post;

<form method="post" id="new_post_form">
    <input type="text" name="post_title" id="title" />
    <?php
    /**
     * Simple editor for test reasons
     */ 
        wp_editor( '', 'post_content' );
    ?>
    <input type="hidden" name="author_id" value="<?php echo get_current_user_id(); ?>" />
    <input type="text" name="security" value="<?php echo wp_create_nonce( "ajax_securiy_nonce" ); ?>">
    <input type="hidden" name="action" value="post_new_thing">
    <input type="submit" id="submit_preview" value="Submit & Preview" />
</form>

We will use ajax for posting. So you need an ajax PHP function for this. You can use this function in your functions.php

function add_header_ajax_url(){
    echo '<script type="text/javascript">var ajaxurl = "<?php echo admin_url("admin-ajax.php"); ?>";</script>';
}

add_action( 'wp_head', 'add_header_ajax_url');

add_action( 'wp_ajax_post_new_thing', 'post_new_thing' );

function post_new_thing() {
    /**
     * Post new for post type
     */
    check_ajax_referer( 'ajax_securiy_nonce', 'security' );

    $title     = sanitize_text_field( $_POST['post_title'] );
    $content   = sanitize_text_field( $_POST['post_content'] );
    $author_id = sanitize_text_field( $_POST['author_id'] );

    $args = array(
        'post_title'   => $title,
        'post_content' => $content,
        'post_type'    => 'post',
        'author'       => $author_id,
        'post_status'  => 'draft',
    );

    $posts = wp_insert_post( $args );


    if( is_wp_error( $posts ) ){
        echo json_encode( $posts->get_error_messages() );
    } else {
        if ( !function_exists( 'get_preview_post_link' ) ) { 
            require_once ABSPATH . WPINC . '/link-template.php'; 
        } 
        $post_preview = get_preview_post_link($posts);
        echo $post_preview;
    }
    wp_die();
}

This function returns preview link. Also create a post with status as draft. We will force return function to open preview in new tab. Use functions where you want (probably in footer).

<script type="text/javascript">
    jQuery(document).ready(function($){
        $('#submit_preview').submit(function(e){
            $.ajax({
                type: 'post',
                url : ajaxurl,
                data : $('#new_post_form').serialize(),
                success : function(data){
                    window.open(data,'_blank');
                }
            });
            e.preventDefault();
        });
    });
</script>

This codes should work as expected. Comment me if code works or not.

Choose what you think is ideal for the form your after first. Then create it using the the Plugin API of WordPress, or learn the language of those available. Doing a search fo WordPress Forms on Google can be helpful if trying to decide on an API.

There are many, so decide for yourself which is meant for you.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1748955078a315129.html

最新回复(0)