问题描述

我有一个 custom-post 类型与标准元框和一些自定义字段。如何通过前台的表单编辑帖子?

最佳解决方法

如果您想编辑现有的帖子,请尝试我的 Front-end Editor 插件。

如果要创建新帖子,请尝试以下操作之一:

次佳解决方法

我使用 Advanced Custom Fields 进行大量前端后期编辑与元框。 ACF 允许您构建许多高级元框字段,并将它们自动添加到后端后面板。

但是还有一个 front end function

这种方法是完全免费的。花费任何东西的唯一方法是,如果您想使用任何更复杂的字段类型 add-ons,如转发器,灵活或画廊。这一切在这里都很好。

第一个缺点是它不包括帖子标题和描述… 但是可以很容易地将它添加到你的 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,
    ));
}

这将添加所有代码来支持标题和内容字段,可以添加到前端表单,如下所示:

// 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)
) );

我在这几天工作的大多数网站上都使用这种方法。我倾向于使用 Gravity Forms 来创建一个基本的帖子,然后我使用 ACF 在前端和后端控制一切。最好的事情是,您从一个地方管理这两个。不过值得注意的是,ACF can be used to create a post 也是如此。我没有使用它,但会尝试在我的下一个项目,以便我可以创建与完全元访问。

ACF 是个人,唯一的插件,我不能没有重力形式作为一个接近的秒。

第三种解决方法

以下是更新帖子/页面的基本解决方案。我添加了一个自定义元字段的快速演示。这是非常基本的,但是会指向 plugin-less 编辑 front-end 上的帖子。这不是超级灵活,但你可以添加任何你需要的。

将此代码添加到您的循环中:

<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>

然后将此代码添加到页面顶部以处理表单:

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");
    }
}

第四种方法

最简单的方法是使用以下付费扩展程序使用像 Ninja Forms 这样的东西:

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

你也可以自己编码。基本上你将创建一个表单,然后使用 wp_insert_post()创建一个完整的帖子。

样本表格:

<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>

然后提交,您将保存进程,如:

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 );

}

完整的代码和教程来自:http://wp.tutsplus.com/tutorials/creative-coding/posting-via-the-front-end-inserting/

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。