acf_form()

Last updated Feb 17, 2022

Overview

This function creates a form to add or update a post. There are many settings available to customize the form and these are set by adding to the $options array as explained below.

Parameters

<?php acf_form( $options ); ?>

$options an optional array containing 1 or more of the settings below

  • post_id The post ID to load data from and save data to. Defaults to the current post.
  • field_groups An array of field group IDs to override the field’s which would normally be displayed for the post
  • form Whether or not to create a form element. Useful when hard-coding the form element Defaults to true.
  • form_attributes An array or HTML attributes for the form element.
  • return The URL to be redirected to after the post is created / updated. Defaults to the current URL with an extra GET parameter called updated=true
  • html_before_fields A string containing extra HTML to add before the fields
  • html_after_fields A string containing extra HTML to add after the fields
  • submit_value A string containing the text displayed on the submit button
  • updated_message A string message which id displayed above the form after being redirected

Notes

It is important to note that whilst the acf_form() function will create a form allowing you to input data, it will not perform the logic needed to save the data. This logic is handled by another function called acf_form_head(). To allow the form to save data, you will need to place the acf_form_head() function at the top of your page template before any HTML is rendered.

Examples

Basic

This example shows a basic acf_form to edit the current post.

<?php acf_form_head(); ?>
<?php get_header(); ?>

	<div id="primary">
		<div id="content" role="main">

			<?php /* The loop */ ?>
			<?php while ( have_posts() ) : the_post(); ?>

				<?php acf_form(); ?>

			<?php endwhile; ?>

		</div><!-- #content -->
	</div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Editing a specific post

This example shows how to target a specific post, customize the button label and hide the post title input.

<?php acf_form_head(); ?>
<?php get_header(); ?>

	<div id="primary">
		<div id="content" role="main">

			<?php /* The loop */ ?>
			<?php while ( have_posts() ) : the_post(); ?>

				<?php acf_form(array(
					'post_id'	=> 123,
					'submit_value'	=> 'Update the post!'
				)); ?>

			<?php endwhile; ?>

		</div><!-- #content -->
	</div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Create a new post

Unfortunately, the ACF4 API does handle creating new post objects. This logic can be added manually by hooking into a filter called acf/pre_save_post and modifying the $post_id parameter to a new post.

<?php 

// functions.php

function my_pre_save_post( $post_id ) {

    // check if this is to be a new post
    if( $post_id != 'new' )
    {
        return $post_id;
    }

    // Create a new post
    $post = array(
        'post_status'  => 'draft',
        'post_title'  => 'A title, maybe a $_POST variable',
        'post_type'  => 'event',
    );

    // insert the post
    $post_id = wp_insert_post( $post );

    // update $_POST['return']
    $_POST['return'] = add_query_arg( array('post_id' => $post_id), $_POST['return'] );

    // return the new ID
    return $post_id;
}

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

?>
<?php acf_form_head(); ?>
<?php get_header(); ?>

	<div id="primary">
		<div id="content" role="main">

			<?php /* The loop */ ?>
			<?php while ( have_posts() ) : the_post(); ?>

				<?php acf_form(array(
					'post_id'	=> 'new',
					'field_groups'	=> array( 123 ),
					'submit_value'	=> 'Create a new event'
				)); ?>

			<?php endwhile; ?>

		</div><!-- #content -->
	</div><!-- #primary -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Related