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.
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.
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
There are many ways you could use to reach your goal. Here's one...
Steps:
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.