Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a custom-post type with the standard meta boxes and some custom fields. How could I edit a post through a form in the frontend?

share|improve this question
add comment

5 Answers

up vote 4 down vote accepted

If you want to edit an existing post, try my Front-end Editor plugin.

If you want to create new posts, try one of these:

share|improve this answer
    
Thanks Scribu. Your plugin is fantastic, but it does not fit my need. I am trying to edit an existing post with a form. I asked a similar question about editing a user's profile with a form in the frontend and I received this response: wordpress.stackexchange.com/questions/9775/… This worked perfectly for me. If there is a similar solution for editing posts I would be so grateful. –  Carson Feb 21 '11 at 3:23
    
is it possible to add metaboxes along with it?? –  nickfrancis.me Jun 17 '11 at 12:13
    
@nickfancis.me use comments for this sort of thing - that's what they're there for! –  TheDeadMedic Jun 17 '11 at 12:30
    
@nickfrancis.me Metaboxes are strictly for the backend. Maybe you mean widgets? –  scribu Jun 17 '11 at 15:34
add comment

The easiest way would be to use something like Ninja Forms with the following paid extension:

http://wpninjas.com/downloads/front-end-posting/

You could also code this yourself. Essentially you'll create a form, and then use wp_insert_post() to create a full post.

A sample form:

<form action="" id="primaryPostForm" method="POST">

    <fieldset>
        <label for="postTitle"><?php _e('Post Title:', 'framework') ?></label>

        <input type="text" name="postTitle" id="postTitle" class="required" />
    </fieldset>

    <fieldset>
        <label for="postContent"><?php _e('Post Content:', 'framework') ?></label>

        <textarea name="postContent" id="postContent" rows="8" cols="30" class="required"></textarea>
    </fieldset>


<fieldset>
    <input type="hidden" name="submitted" id="submitted" value="true" />

    <button type="submit"><?php _e('Add Post', 'framework') ?></button>
</fieldset>

and then on submit, you'd save process it something like:

if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {

    if ( trim( $_POST['postTitle'] ) === '' ) {
        $postTitleError = 'Please enter a title.';
        $hasError = true;
    }

    $post_information = array(
        'post_title' => wp_strip_all_tags( $_POST['postTitle'] ),
        'post_content' => $_POST['postContent'],
        'post_type' => 'post',
        'post_status' => 'pending'
    );

    wp_insert_post( $post_information );

}

The full code and tutorial is from: http://wp.tutsplus.com/tutorials/creative-coding/posting-via-the-front-end-inserting/

share|improve this answer
    
I Just want to update (edit existing) the post/page, not insert. –  user1983017 Jul 14 '13 at 16:00
    
Then why not try the already-referenced "Front End Editor" plugin by Scribu? –  helgatheviking Jul 14 '13 at 16:17
add comment

I use Advanced Custom Fields for lots of front end post editing with meta boxes. ACF allows you to build lots of advanced meta box fields and adds them automatically to the back end post panel.

But there is a front end function as well.

This method is completely free. The only way it costs anything is if you want to use any of their more complex field type add-ons like repeater, flexible, or gallery. Which all work great here.

The first drawback is that it doesn't include the post title and description... but that can be fixed pretty easily by adding this to your functions.php:

/**
 * Deregister admin styles on the front end when using ACF forms
 *
 * ACF makes sure that admin styles are queued when it loads its head, this almost always causes problems with front end forms and isn't needed for our purpose
 */
add_action( 'wp_print_styles', 'custom_acf_deregister_styles', 100 );
function custom_acf_deregister_styles()
{
    if (! is_admin() )
    {
        wp_deregister_style( 'wp-admin' );
    }
}

/**
 * Save ACF field as post_content / post_title for front-end posting
 */
add_action( 'acf/save_post', 'custom_acf_save_post' );
function custom_acf_save_post( $post_id )
{
    if (! is_admin() && 'acf' != get_post_type( $post_id ) ) // Don't run if adding/updated fields/field-groups in wp-admin
    {
        $post_title   = get_post_meta( $post_id, 'form_post_title', true );
        $post_content = get_post_meta( $post_id, 'form_post_content', true );
        $post         = get_post($post_id);
        if ( ($post_title && $post_title != $post->post_title) || ($post_content && $post_content != $post->post_content) )
        {
            $post_data = array(
                'ID' => $post_id,
            );
            if ( $post_content ) $post_data['post_content'] = $post_content;
            if ( $post_title )   $post_data['post_title']   = $post_title;

            remove_action( 'acf/save_post', 'custom_acf_save_post' );
            wp_update_post( $post_data );
            add_action( 'acf/save_post', 'custom_acf_save_post' );
        }
    }
}

/**
 * Load existing post_title
 */
add_filter( 'acf/load_value/name=form_post_title', 'custom_acf_load_value_form_post_title', 10, 3 );
function custom_acf_load_value_form_post_title( $value, $post_id, $field )
{
    $value   = get_the_title($post_id);
    return $value;
}

/**
 * Load existing post_content
 */
add_filter( 'acf/load_value/name=form_post_content', 'custom_acf_load_value_form_post_content', 10, 3 );
function custom_acf_load_value_form_post_content( $value, $post_id, $field )
{
    $post    = get_post($post_id);
    $value   = $post->post_content;
    return $value;
}

/**
 *  Install Add-ons (This adds two field groups that you can use to edit title and content)
 *  
 *  The following code will include all 4 premium Add-Ons in your theme.
 *  Please do not attempt to include a file which does not exist. This will produce an error.
 *  
 *  All fields must be included during the 'acf/register_fields' action.
 *  Other types of Add-ons (like the options page) can be included outside of this action.
 *  
 *  The following code assumes you have a folder 'add-ons' inside your theme.
 *
 *  IMPORTANT
 *  Add-ons may be included in a premium theme as outlined in the terms and conditions.
 *  However, they are NOT to be included in a premium / free plugin.
 *  For more information, please read http://www.advancedcustomfields.com/terms-conditions/
 */ 

// Fields 
add_action('acf/register_fields', 'my_register_fields');

/**
 *  Register Field Groups
 *
 *  The register_field_group function accepts 1 array which holds the relevant data to register a field group
 *  You may edit the array as you see fit. However, this may result in errors if the array is not compatible with ACF
 */

if(function_exists("register_field_group"))
{
    register_field_group(array (
        'id' => 'acf_form-post-title',
        'title' => 'Form Post Title',
        'fields' => array (
            array (
                'key' => 'field_25',
                'label' => 'Title',
                'name' => 'form_post_title',
                'type' => 'text',
                'default_value' => '',
                'formatting' => 'html',
            ),
        ),
        'location' => array (
            array (
                array (
                    'param' => 'post_type',
                    'operator' => '==',
                    'value' => 'course',
                    'order_no' => 0,
                    'group_no' => 0,
                ),
            ),
        ),
        'options' => array (
            'position' => 'normal',
            'layout' => 'no_box',
            'hide_on_screen' => array (
            ),
        ),
        'menu_order' => -2,
    ));
    register_field_group(array (
        'id' => 'acf_form-post-content',
        'title' => 'Form Post Content',
        'fields' => array (
            array (
                'key' => 'field_13',
                'label' => 'Content',
                'name' => 'form_post_content',
                'type' => 'wysiwyg',
                'default_value' => '',
                'toolbar' => 'full',
                'media_upload' => 'yes',
            ),
        ),
        'location' => array (
            array (
                array (
                    'param' => 'post_type',
                    'operator' => '==',
                    'value' => 'course',
                    'order_no' => 0,
                    'group_no' => 0,
                ),
            ),
        ),
        'options' => array (
            'position' => 'normal',
            'layout' => 'no_box',
            'hide_on_screen' => array (
            ),
        ),
        'menu_order' => -1,
    ));
}

That will add all the code to support a title and content field that can be added to the front end forms like this:

// Add this above get_header()
// This loads styles/scripts, but it also processes the form, so pretty important
acf_form_head();

get_header();

// Where 51 is the id of the ACF field group of meta box fields that I want to add
acf_form( array(
    'field_groups' => array('acf_form-post-title', 'acf_form-post-content', 51)
) );

I use this method on most of the sites I work on these days. I tend to use Gravity Forms to create a basic post and then I control everything with ACF on the front and back end. The best thing is that you manage it all from one place for both. It is worth noting, however, that ACF can be used to create a post as well. I haven't used it, but will be giving it a try on my next project, so that I can create with full meta access.

ACF is, personally, the only plugin I can't live without with Gravity Forms as a close second.

share|improve this answer
    
Thanks for the TIP, But I was looking for a solution without any plugin –  user1983017 Jul 15 '13 at 14:36
1  
It can be done. It is just a really complicated subject. I have something called "Catapost" that allows you to add metaboxes to posts and then create frontend forms to edit post title/content with the metaboxes. It is LIKE a plugin, but it is included in the theme instead, so it that it can be distributed with themes. Is that the type of thing you are looking for? –  Jake Jul 15 '13 at 15:15
    
Well. A flexible solution is complex... If you just want to edit a basic post... That might not be so bad. –  Jake Jul 15 '13 at 15:20
    
I added a really basic solution in another answer that lays out how to do it with no plugin. It isn't very flexible, but works well for a one-time use. –  Jake Jul 15 '13 at 16:11
add comment

Here is a basic solutions for updating a post/page. I added a quick demo of custom meta fields. This is pretty basic, but will point you in the direction of plugin-less editing of posts on the front-end. This isn't super flexible, but you can add whatever you need to it.

Add this code into your loop:

<form id="post" class="post-edit front-end-form" method="post" enctype="multipart/form-data">

    <input type="hidden" name="post_id" value="<?php the_ID(); ?>" />
    <?php wp_nonce_field( 'update_post_'. get_the_ID(), 'update_post_nonce' ); ?>

    <p><label for="post_title">Title</label>
    <input type="text" id="post_title" name="post_title" value="<?php echo $post->post_title; ?>" /></p>

    <p><?php wp_editor( $post->post_content, 'postcontent' ); ?></p>

    <p><label for="post_title">Test</label>
    <?php $value = get_post_meta(get_the_ID(), 'edit_test', true); ?>
    <input type="text" id="edit_test" name="edit_test" value="<?php echo $value; ?>" /></p>

    <p><label for="post_title">Test 2</label>
    <?php $value = get_post_meta(get_the_ID(), 'edit_test2', true); ?>
    <input type="text" id="edit_test2" name="edit_test2" value="<?php echo $value; ?>" /></p>

    <input type="submit" id="submit" value="Update" />

</form>

Then add this code at the top of the page to process the form:

if ( 'POST' == $_SERVER['REQUEST_METHOD'] && ! empty($_POST['post_id']) && ! empty($_POST['post_title']) && isset($_POST['update_post_nonce']) && isset($_POST['postcontent']) )
{
    $post_id   = $_POST['post_id'];
    $post_type = get_post_type($post_id);
    $capability = ( 'page' == $post_type ) ? 'edit_page' : 'edit_post';
    if ( current_user_can($capability, $post_id) && wp_verify_nonce( $_POST['update_post_nonce'], 'update_post_'. $post_id ) )
    {
        $post = array(
            'ID'             => esc_sql($post_id),
            'post_content'   => esc_sql($_POST['postcontent']),
            'post_title'     => esc_sql($_POST['post_title'])
        );
        wp_update_post($post);

        if ( isset($_POST['edit_test']) ) update_post_meta($post_id, 'edit_test', esc_sql($_POST['edit_test']) );
        if ( isset($_POST['edit_test2']) ) update_post_meta($post_id, 'edit_test2', esc_sql($_POST['edit_test2']) );
    }
    else
    {
        wp_die("You can't do that");
    }
}
share|improve this answer
1  
Thanks it is the solution I was looking for. –  user1983017 Jul 16 '13 at 1:17
    
I added esc_sql(). It just occurred to me that you should escape data being submitted from a public (semi-public) form like that. –  Jake Jul 16 '13 at 23:01
1  
Thanks, But my form is only available for Admin. Anyway it will be helpful if ever I use this form for public posting. –  user1983017 Jul 17 '13 at 2:48
add comment

In addition to other user's answers - wpDataTables (commercial) plugin has a generic front-end editing for MySQL tables: http://wpdatatables.com/editable-tables-wpdatatables-wordpress-table-plugin/

You can set it up for editing whatever table you like - it just has to have an ID field.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.