许多主题或插件会创建自定义文章类型(如“网址”、“产品”等)及其关联的分类法(如“网址分类”)。有时,我们需要允许前端用户向这些自定义分类法下的条目投稿,而不是向默认的“文章”投稿。本文将介绍如何通过纯代码实现此功能。
核心实现原理
WordPress 提供了强大的 wp_insert_post() 函数来创建任何类型的文章。关键在于正确设置其参数,特别是 post_type(文章类型)和 tax_input(分类法关联)。
关键代码示例
以下是一个处理表单提交、创建一篇待审核状态的自定义文章并关联到指定分类的示例代码。请将其放入主题的 functions.php 文件或自定义插件中。
/**
* 处理前端投稿表单提交
*/
function wukongsou_handle_submission() {
// 1. 安全检查:验证 Nonce 和用户权限
if ( ! isset( $_POST['submit_nonce'] ) || ! wp_verify_nonce( $_POST['submit_nonce'], 'wukongsou_submit_action' ) ) {
wp_die( '安全校验失败,请重试。' );
}
// 2. 数据清洗与验证
$post_title = sanitize_text_field( $_POST['bbs_post_title'] ?? '' );
$post_content = wp_kses_post( $_POST['bbs_post_content'] ?? '' );
$themes_id = absint( $_POST['buluo_category_id'] ?? 0 ); // 假设前端传递了分类ID
if ( empty( $post_title ) || empty( $post_content ) || $themes_id <= 0 ) {
wp_die( '请填写所有必填字段并选择分类。' );
}
// 3. 组装文章数据
$new_post = array(
'post_type' => 'buluo', // 你的自定义文章类型名称,例如 'website', 'product'
'post_title' => $post_title,
'post_content' => $post_content,
'post_status' => 'pending', // 投稿后状态为“待审核”,管理员审核后发布
'tax_input' => array(
'buluo_category' => array( $themes_id ), // 'buluo_category' 是你的自定义分类法名称
),
);
// 4. 插入文章
$post_id = wp_insert_post( $new_post, true );
// 5. 错误处理与反馈
if ( is_wp_error( $post_id ) ) {
wp_die( '投稿失败:' . $post_id->get_error_message() );
} else {
// 投稿成功,可以重定向或显示成功信息
wp_safe_redirect( home_url( '/thank-you/' ) );
exit;
}
}
// 将函数挂载到合适的 Action,例如 init 或 admin_post_{action}
add_action( 'admin_post_nopriv_wukongsou_submit', 'wukongsou_handle_submission' ); // 未登录用户
add_action( 'admin_post_wukongsou_submit', 'wukongsou_handle_submission' ); // 已登录用户
前端表单要点
你需要在前端创建一个表单,其 action 指向 admin-post.php,并包含一个隐藏的 action 参数,与上述代码中的钩子对应。
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'wukongsou_submit_action', 'submit_nonce' ); ?>
<input type="hidden" name="action" value="wukongsou_submit">
<label for="bbs_post_title">标题:</label>
<input type="text" id="bbs_post_title" name="bbs_post_title" required>
<label for="bbs_post_content">内容:</label>
<textarea id="bbs_post_content" name="bbs_post_content" required></textarea>
<!-- 这里需要生成一个分类选择下拉菜单,获取分类ID -->
<label for="buluo_category_id">选择分类:</label>
<?php
wp_dropdown_categories( array(
'taxonomy' => 'buluo_category',
'name' => 'buluo_category_id',
'show_option_none' => '请选择',
'required' => true,
'value_field' => 'term_id',
) );
?>
<input type="submit" value="提交投稿">
</form>
重要说明与安全提示
- 权限控制:代码示例中使用了
admin_post_*钩子,这是一种标准且安全的前端表单处理方式。 - 数据验证:务必使用
sanitize_text_field(),wp_kses_post(),absint()等函数对用户输入进行清洗,防止 XSS 和 SQL 注入攻击。 - Nonce 验证:
wp_nonce_field()和wp_verify_nonce()用于防止跨站请求伪造(CSRF)。 - 分类法名称:请将代码中的
buluo(文章类型)和buluo_category(分类法)替换为你实际注册的名称。 - 状态管理:设置
post_status为pending(待审核)是推荐做法,便于管理员审核内容后再公开。
通过以上步骤,你就能为自定义文章类型和分类法构建一个安全、可靠的前端投稿系统。