24/10/2020

The archive contains older posts which may no longer reflect my current views.

# I previously detailed how the post form operates so thought I'd do the same for the inline editing. The two work on the same principles but there is an additional step involved with editing rather than just posting: you have to pull in the post content but it's easier than it sounds as it's all done within the loop.

First, I've contained the code within the loop inside a DIV, this is given a unique ID to be used later:

<?php while ( $today_query->have_posts() ) : $today_query->the_post(); ?>
  <div id="post<?php echo $post->ID; ?>"> // container div for post
    <?php
      // code in the loop to display the post
    ?>
</div>

Still within the loop, but after the code used to display the normal post, I have the form used to do the editing. It is in a hidden DIV by default which is, again, given a unique ID and is only visible if logged in and the current_user_can( 'edit_posts' ). The form contains a hidden input which holds the current post ID as its value and the textarea holds the original post content:

<?php
  if (current_user_can( 'edit_posts' )) {
?>
    <div id="edit<?php echo $post->ID; ?>" style="display: none;"> //container div for edit form

      <form id="form<?php echo $post->ID; ?>" name="form<?php echo $post->ID; ?>" action="" method="post">
        <input type="hidden" id="updatepost" name="updatepost" value="<?php echo $post->ID; ?>">
        <textarea id="newcontent" name="newcontent"><?php the_content(); ?></textarea>
    <?php
      echo '<a onclick="quit(' . $post->ID . ')"><span style="float:left;" class="dashicons dashicons-dismiss"></span></a>';
    ?>
        <input style="float:right;" type="submit" name="submit" id="submit" value="Update">
      </form>

    </div>
<?php } ?>

Inserted within the first DIV, just before the post content, is a WordPress dashicon used to toggle to 'edit mode' - for my theme this is a separate template called content.php. In the editing form, I have another dashicon to switch back and dismiss the form.

// toggle inserted before each post - within loop code

if (current_user_can( 'edit_posts' )) {
  echo '<a style="display: none;" class="editicon" onclick="toggleEdit(' . $post->ID . ')"><span class="dashicons dashicons-edit"></span></a>';
}

Both dashicons have an onclick event which triggers a simple JavaScript function to toggle the display states of the normal post content and edit form:

<script>
  function toggleEdit(e) {
    let post = "post" + e;
    let edit = "edit" + e;
    document.getElementById(post).style.display='none';
    document.getElementById(edit).style.display='block';
  }

  function quit(e) {
    let post = "post" + e;
    let edit = "edit" + e;
    document.getElementById(post).style.display='block';
    document.getElementById(edit).style.display='none';
  }
</script>

I could have used a single function with an if...else statement but kept it separate on this occasion.

The edit form method is post and there is no action specified so it reload the same page. This means I need to process the form output so, at the start of the page is the code to do that:

<?php

// Update post

if ( isset($_POST['updatepost']) && ($_POST['newcontent'] !='') ) {
  $body = stripslashes($_POST['newcontent']);
  $ID = $_POST['updatepost'];

  $update_post = array(
    'ID'           => $ID,
    'post_content' => $body,
  );

  wp_update_post($update_post);
}

?>

After a quick check to ensure that the post content isn't empty and that a post ID has been passed it's a simple matter of creating a post array and updating the specified post. It is recommended to use stripslashes() when dealing with HTML form content via $_POST just in case of any issues.

And that's it. Inline post editing without having to go to wp-admin.