Using acf_form to create a new post

Overview

This article will cover how to create a form on the front end of your website to add new content.

Getting started

If you have not already, please familiarize yourself with the acf form functions. Two functions are available to create a working form in a template file.

Name Description
acf_form_head() This function is placed at the top of a template file and will register the necessary assets (CSS/JS), process the saved data, and redirect the url. This function does not accepts any parameters
acf_form() This function is placed within a template file and will create the form’s HTML. This function accepts an array of settings to customize the form

Settings

The acf_form() parameter contains two settings called post_id and field_groups. By using these settings correctly, a new post an be created using the form data.

The post_id setting  is used to edit an existing post, but when set to ‘new_post’, it is possible to create a new post object via the ‘acf/pre_save_post’ filter. The ‘acf/pre_save_post’ filter is run prior to saving any of the custom field data. The filter allows modification to the $post_id parameter and can be used to insert a new post and return the new post’s ID.

The field_groups setting is used to specify which field groups to show in the form. Because the post_id does not target an actual post, this setting is required to tell ACF which groups to show. Please note that in ACF v5, this setting is not required, and new_post can be used to provide new post settings.

Examples

Basic

This form will create a new post.

page-new-post.php

<?php 

acf_form_head();

get_header();

?>
<div id="content">
	
	<?php
	
	acf_form(array(
		'post_id'		=> 'new_post',
		'field_groups'	=> array( 123 )
	));
	
	?>
	
</div>

<?php get_footer(); ?>

functions.php

<?php 

add_filter('acf/pre_save_post' , 'my_pre_save_post' );

function my_pre_save_post( $post_id ) {
	
	// bail early if not a new post
	if( $post_id !== 'new_post' ) {
		 
		return $post_id;
		
	}
	
	
	// vars
	$title = $_POST['fields']['field_123456'];
	
	
	// Create a new post
	$post = array(
		'post_status'	=> 'draft',
		'post_type'		=> 'post',
		'post_title'	=> $title,
	);	
	
	
	// insert the post
	$post_id = wp_insert_post( $post ); 

	
	// return the new ID
	return $post_id;
	
}

?>

Contact form

This example will make a basic contact form, send an email, and redirect the user to a thank-you page.

page-contact.php

<?php 

acf_form_head();

get_header();

?>
<div id="content">
	
	<?php
	
	acf_form(array(
		'post_id'		=> 'new_post',
		'field_groups'	=> array( 456 )
	));
	
	?>
	
</div>

<?php get_footer(); ?>

functions.php

add_filter('acf/pre_save_post' , 'my_pre_save_post' );

function my_pre_save_post( $post_id ) {
	
	// bail early if not a new post
	if( $post_id !== 'new_post' ) {
		 
		return $post_id;
		
	}
	
	
	// vars
	$title = $_POST['fields']['field_123456'];
	$content = $_POST['fields']['field_789456'];
	
	
	// Create a new post
	$post = array(
		'post_status'	=> 'publish',
		'post_type'		=> 'contact_form',
		'post_title'	=> $title,
		'post_content'	=> $content
	);	
	
	
	// insert the post
	$post_id = wp_insert_post( $post ); 

	
	// return the new ID
	return $post_id;
	
}


add_action('acf/save_post', 'my_save_post');

function my_save_post( $post_id ) {
	
	// bail early if not a contact_form post
	if( get_post_type($post_id) !== 'contact_form' ) {
		
		return;
		
	}
	
	
	// bail early if editing in admin
	if( is_admin() ) {
		
		return;
		
	}
	
	
	// vars
	$post = get_post( $post_id );
	
	
	// get custom fields (field group exists for content_form)
	$name = get_field('name', $post_id);
	$email = get_field('email', $post_id);
	
	
	// email data
	$to = 'contact@website.com';
	$headers = 'From: ' . $name . ' <' . $email . '>' . "\r\n";
	$subject = $post->post_title;
	$body = $post->post_content;
	
	
	// send email
	wp_mail($to, $subject, $body, $headers );
	
}

Related