Practical example 02

Edit existing posts
with a front-end form

Allow signed-in users to edit existing posts from a site-facing form instead of the WordPress admin screen. The target post is identified with post_id, then the template checks its post type and edit capability.

01

What this example does

  • Edits CFS fields on an existing post from a front-end form.
  • Passes post_id from an edit link to identify the target post.
  • Locks the allowed post type so another type cannot be edited through the URL.
  • Uses WordPress's edit_post capability to decide whether saving is allowed.
Separate this from new-post creation

For new posts, see the new-post form example. This page focuses only on editing existing posts.

02

Check edit permission when saving

Add this to the theme's functions.php or a site-specific plugin. Existing-post editing receives a post_id, so use current_user_can( 'edit_post', $post_id ).

functions.php

PHP / Permissions
<?php
add_filter(
  'cfs_form_can_save',
  function ( $can_save, $post_id, $post_data ) {
    if ( ! is_user_logged_in() ) {
      return false;
    }

    if ( 0 < $post_id ) {
      return current_user_can( 'edit_post', $post_id );
    }

    return false; // This page does not allow new-post creation.
  },
  10,
  5
);
03

Load the form CSS and JavaScript

This example uses a page with the slug front-form-edit.

functions.php

PHP / Assets
<?php
add_action( 'wp_enqueue_scripts', function () {
  if ( is_page( 'front-form-edit' ) && is_user_logged_in() ) {
    CFS()->form->load_assets();
  }
} );
05

Load the existing post in a page template

If post_id is missing, there is no edit target, so return 404 or 403. After checking the post type and edit capability, pass the ID to CFS()->form().

page-front-form-edit.php

PHP / Template
<?php
/* Template Name: CFS Front-end Edit Form */

if ( ! is_user_logged_in() ) {
  auth_redirect();
}

$post_id   = absint( $_GET['post_id'] ?? 0 );
$post_type = 'member_entry'; // Post type allowed for editing.

if ( ! $post_id ) {
  wp_die( 'No post was selected for editing.', '', array(
    'response' => 404,
  ) );
}

// Prevent a different post type from being selected through the URL.
if ( $post_type !== get_post_type( $post_id ) ) {
  wp_die( 'This post type is not allowed.', '', array(
    'response' => 404,
  ) );
}

// Confirm that the current user may edit this post.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
  wp_die( 'You are not allowed to edit this post.', '', array(
    'response' => 403,
  ) );
}

get_header();
?>

<main class="front-form">
  <h1>Edit entry</h1>

  <?php
  echo CFS()->form( array(
    'post_id'          => $post_id, // Update this existing post.
    'field_groups'     => array( 123 ), // Field group ID.
    'submit_label'     => 'Save',
    'confirmation_url' => get_permalink( $post_id ),
  ) );
  ?>
</main>

<?php get_footer(); ?>
06

Limit editing to the user's own posts

For member-submitted content, you may want users to edit only posts they authored. Add an author check on top of the capability check.

Author check

PHP / Owner check
<?php
$owner_id = (int) get_post_field( 'post_author', $post_id );

if ( get_current_user_id() !== $owner_id ) {
  wp_die( 'You are not allowed to edit this post.', '', array(
    'response' => 403,
  ) );
}
When administrators and editors should still be allowed

An author-only check can also block administrators. Decide whether current_user_can( 'edit_post', $post_id ) should be enough, or whether the form must be limited to the post owner.

07

Test before deployment

  • The form is not displayed when post_id is missing.
  • A different post type returns a 404 response.
  • A post ID without edit permission returns a 403 response.
  • Only permitted users can update existing posts.
  • The confirmation URL points to the edited post or a completion page.