Frontend Post Submission & Edit with Advanced Custom Fields

This is going to be a follow-up to my previous post Advanced Custom Fields on Front-end & Front-end Posting. With the latest version of Advanced Custom Fields Pro, we can accomplish the frontend post submission & edit with ease. The previous article I wrote was only about how to get your post submitted from frontend and lacked the editing portion. In this post, I am going to cover both submission and editing with detailed instructions so, you can easily apply it to your project.

The Scenario

Let us assume, you have a website where you enlist your favorite books or for affiliation purposes. You have a custom post type called “Books”. The custom post type has 6 important fields that we will work with. Which are:

Field NameTitle on Field Group
TitleBook Title
ContentDescription
Featured ImageBook Cover
CategoryGenre
PriceBook Price
URLyPurchase Link

Tip: This process doesn’t require a custom post type. However, we are using it to cover more of the things we can do with this method. If you need to create custom post type but don’t know how you can use a plugin like Custom Post Type UI.

Create Field Groups

For our fields, we will create two separate fields groups. First one as “Books – Essential”. Also, the image field for “Book Cover” which will work as the featured image.

It is a good idea to limit the image upload to the post only. That will ensure non-admin users don’t see other media library files uploaded to the site. So, if you have many users that will do the posts you may choose Uploaded to post else, you may keep it to All.

Select the image field return value to Image ID

The next field is Genre a Taxonomy field, which we will use for the category of books.

If you want to allow adding new categories keep the “Create Terms” field to Yes. Change it to No if you want to prevent users from adding new categories while they post. It is important to keep the “Save Terms” and “Load Terms” options to Yes for our purpose.

The last step for this field group is to set the location. Select “Options Page” and keep it to “No options page exist” like the following image.

On the next field group, we will call it “Books – Custom Fields”. The two fields that we will add to this field group are Book Price and Purchase Link. These are generic fields, just add them and this time select the location according to the following image. We are now adding these fields to the “Books” custom post type.

This ends the creation of field groups for our frontend post submission and editing. Next, we will prepare our theme files for the post submission and edit.

Modding Theme Files for Submission

We are going to use a page template for our post submission. To make a page template, you may copy the page.php file from your activated theme folder and copy to the child theme directory. In case, you are not using a child theme, just copy the file to the currently activated theme folder with a different name like template-book-entry.php. You can find more about page templates here.

The template file code should start with something like this

<?php
get_header();
......

Modify the file like the following code

<?php
/*
Template Name: Book Entry
*/
if ( is_user_logged_in() || current_user_can('publish_posts') ) { // Execute code if user is logged in
    acf_form_head();
    wp_deregister_style( 'wp-admin' );
}
get_header();

The next portion of code is going to be added in the body/content area of the page. Try to locate the_content(); on your code to paste in another piece of code. If your copied page.php content does not contain that, you may try writing in a container class, which is pretty common in most themes. You can also try inspecting a regular page to get the appropriate area.

Get the ID of two Field Groups from their URL. It will be something like this

http://yoursite.com/wp-admin/post.php?post=6&action=edit

Here 6 is the ID of the field group. You will need to get the ID of both fields following that method.

<?php
if ( ! ( is_user_logged_in() || current_user_can('publish_posts') ) ) {
    echo '<p>You must be a registered author to post.</p>';
} else {
     acf_form(array(
         'post_id' => 'new_post',
         'field_groups' => array(6,11), // Used ID of the field groups here.
         'post_title' => true, // This will show the title filed
         'post_content' => true, // This will show the content field
         'form' => true,
         'new_post' => array(
             'post_type' => 'books',
             'post_status' => 'publish' // You may use other post statuses like draft, private etc.
         ),
         'return' => '%post_url%',
         'submit_value' => 'Submit Book',
     ));
}
?>

You will notice that we have post_title and post_content as true. These two helps us automatically add the Title and Content field to the post submission form.

Tip: If you are not going to use a custom post type, just don’t use the ‘post_type’ => ‘books’ part.

For the Featured Image, in our case, the Book Cover field needs to be configured to set the uploaded image as the featured image to the post. To do that, we will add some code to the functions.php file. Again, if you are using a child theme, add the code to the child theme’s functions.php file.

// Set Featured Image from ACF Field
function acf_set_featured_image( $value, $post_id, $field ) {
    if($value != ''){
        update_post_meta($post_id, '_thumbnail_id', $value);
    } else {
        if ( has_post_thumbnail() ) {
            delete_post_thumbnail( $post_id);
        } 
    }
    return $value;
}
add_filter('acf/update_value/name=book_cover', 'acf_set_featured_image', 10, 3);

Here, we used the field name of Book Cover field which is book_cover on the filter and that does the job of setting the uploaded image as featured image.

Amazingly, thats all that we need for the submission part! Moving on to the next portion which is editing the submitted post.

Modding Theme File for Editing The Post

While our post was submitted, we should be redirected to the post URL as we have set that in our code. That page is rendered by single.php if you don’t already have a post template for the Books custom post type.

In order to create the post template, you may copy the single.php file from your current activated theme and make a new file called single-books.php. As our custom post type slug is books we are adding it after the word “single” and a “-“ followed by the extension of the file which is “.php”.

So, the rule is single-<post_slug>.php

We will also need to add the custom fields “Book Price” and “Purchase URL” in the single-books.php file to display the values.

Look at the top of the file and change

<?php
get_header();

To this..

<?php
get_currentuserinfo();
if ( ( is_user_logged_in() && $current_user->ID == $post->post_author ) ) { // Execute code if user is logged in or user is the author
    acf_form_head();
    wp_deregister_style( 'wp-admin' );
}
get_header();

Now we need to add the following code to add the form for editing the post

<?php 
    if ( ( is_user_logged_in() && $current_user->ID == $post->post_author ) ) {
        echo "<div class='acf-edit-post'>";
            acf_form (array(
                'field_groups' => array(6,11), // Same ID(s) used before
                'form' => true,
                'return' => '%post_url%',
                'submit_value' => 'Save Changes',
                'post_title' => true,
                'post_content' => true,
            ));
        echo "</div>";
    }
?>

Done! With these simple changes, you now have a fully functional frontend post editing feature with Advanced Custom Fields.

To improve the look and feel and the UI of the post edit form, I used a class acf-edit-post in the code. You can simply add a button to the template and reveal the post editor/updater form as you want.

Code for the button

<a href="<?php echo get_permalink() ?>?action=edit"></a>

Code for revealing the form once the button is pressed

<?php
    if (isset($GET['action'])) {
        if($GET['action'] == 'edit') {
            /* Put the edit form code here */
            <div class="acf-edit-post">
                ...
                ...
            </div>
        }
    }
?>

Here we followed a very basic way to show the form if the the button is pressed. You may customize this more to your need with jQuery and CSS.

Bonus!

You may want to customize some of the things as you implement the codes I have shared above. I am adding some snippets to help you with some common customizations. You may add the codes given bellow on the functions.php file or just above the acf_form() c0de on the template file.

Changing the label of Title and Content field

We used automatically generated title and content fields on both our forms. They work fine but in some projects, you might want to change them to better define the form fields. To do this, you use the following code

// Change Title Lable
function change_title_label( $field ) {
    $field['label'] = 'Book Title';
    return $field;
}
add_filter('acf/load_field/name=_post_title', 'change_title_label');
 
// Change Content Label 
function change_content_label( $field ) {
    $field['label'] = 'Description';
    return $field;
}
add_filter('acf/load_field/name=_post_content', 'change_content_label');

Changing the Content field to be required

By default, the Content field will not be required. You may use the following code to make the field required for verification

// Change Post Content to Required
function change_post_content_required( $field ) {
    $field['required'] = true;
    return $field;
}
add_filter('acf/load_field/name=_post_content', 'change_post_content_required');

Disabling the media upload button on Content field

In many projects, we need to disable the media upload button on the content field. It is good for keeping out non-admin users from uploading unnecessary files. You may use the following code for this

// Change Post Content Type
add_filter( 'acf/get_valid_field', 'change_post_content_type');
function change_post_content_type( $field ) { 
    if($field['type'] == 'wysiwyg') {
        $field['tabs'] = 'visual';
        $field['toolbar'] = 'basic';
        $field['media_upload'] = 0;
    }
    return $field;
}

Conclusion

I hope this post helps you with frontend post submisson and editing. Feel free to share your opinion in the comments and let me know how it went. Thank you.