警告:这个答案中的代码示例非常基本,可能需要也可能不需要进一步的条件逻辑来适应您的精确需求,这个逻辑是作为一个示例来帮助您完成任务的
您需要注意两个方面:
考虑事项1:
如果您添加新帖子并将其保存为
post_status
属于
draft 首先,该职位将不会有
slug
在
post_name
数据库中的字段
*_posts
直到您
publish 至少
once.
考虑事项2:
如果添加新帖子,请将其保存为
post_status
属于
draft, 或者只是通过
draft 登台并直接进入
publish 然后将帖子放回
draft post_status
, 然后,立柱会将缓动块插入
post_name
中的列
*_posts
桌子
为什么这一点很重要:与考虑因素1有关id 或者post_name
为了检索帖子,它是唯一的。
您会注意到,当您创建草稿帖子并尝试预览它时,WordPress会将您带到一个类似以下内容的预览URL:
http://example.com/?p=123&preview=true
之所以这样做,是因为识别和预览相关帖子的唯一方法是通过数据库中与之关联的ID来完成。
关于对价2如果您publish 至少发布一次,然后将其放回draft, 您可以在draft 由于post_name
列包含段塞值。
一些示例代码:
以下代码允许您在
draft 或
pending 只要帖子之前至少发布过一次,就可以使用slug来获取状态(请参见考虑事项2)。
function preview_draft_posts($query) {
if ( is_admin() || get_query_var(\'suppress_filters\') )
return $query;
$query->set(\'post_status\', array(\'publish\', \'pending\', \'draft\'));
return $query;
}
add_filter(\'pre_get_posts\', \'preview_draft_posts\');
以上内容适用于登录和注销用户。
如果注销并希望预览草稿,会发生什么情况
正常,因此如果
draf 以前至少未发布过一次,预览帖子的唯一方法是使用以下格式:
http://example.com/?p=123
WordPress依赖于这种格式来查找没有slug的帖子。
如果您已注销,尽管pre_get_posts
我们在上述示例中使用的逻辑。
相反,您需要连接到过滤器上the_posts
并将帖子添加回要查看的结果,因为WP_Query
将排除draft 由于注销用户没有适当的用户功能,因此从结果集中为注销用户发布帖子。
另一方面,如果您尝试(在注销时)访问类似于考虑因素1的帖子,其默认预览URL如上述示例中所述http://example.com/?p=123&preview=true
(带或不带preview=true
) 然后你会看到一个404页的未找到通知。
以下示例代码纠正了以下问题:
function the_posts_preview_draft_posts($posts, $wp_query) {
//abort if $posts is not empty, this query ain\'t for us...
if ( count($posts) ) {
return $posts;
}
$p = get_query_var(\'p\');
//get our post instead and return it as the result...
if ( !empty($p) ) {
return array(get_post($p));
}
}
add_filter(\'the_posts\', \'the_posts_preview_draft_posts\', 10, 2);
太好了。。。但是等等,这还是很糟糕,因为你必须使用URL格式,比如
http://example.com/?p=123
访问帖子。
返回中概述的主要问题consideration 1, 我能想到的唯一解决方案如下:
解决方案#1
- 保存草稿帖子,并通过将标题转换为标题来按标题查找帖子
示例。。。
function the_posts_preview_draft_posts($posts, $wp_query) {
//abort if $posts is not empty, this query ain\'t for us...
if ( count($posts) ) {
return $posts;
}
$id = get_query_var(\'p\');
$name = get_query_var(\'name\');
//this is a bit of a bad idea...
if ( empty($id) && !empty($name) ) {
$name = preg_replace(\'/\\W/\', \' \', $name);
global $wpdb;
$id = $wpdb->get_var(
"
SELECT ID
FROM $wpdb->posts
WHERE UPPER(post_title) LIKE UPPER(\'".$name."\')
LIMIT 1"
);
}
//get our post instead and return it as the result...
if ( !empty($id) ) {
return array(get_post($id));
}
}
add_filter(\'the_posts\', \'the_posts_preview_draft_posts\', 10, 2);
以上。。。↑ ...这是一个坏主意,但只是你需要达到的长度的一个例子。为什么这是一个坏主意很简单,您需要确保数据库中没有重复的帖子标题,并且您需要确保不修改slug,以便将其保存为草稿时与标题不同。
正如你所看到的,充满了问题。
解决方案#2
处理此问题的更好方法可能是将post的post\\U状态设置为
publish 因此
post_name
列获取slug值,然后立即将post放回
draft 地位
手动操作会很糟糕,下面是一些代码:
function allow_draft_public_preview( ) {
global $post;
if ( !empty($post->post_name) )
return;
$html =<<<DOC
<div class="misc-pub-section">
<label>
<input type="checkbox" id="_allow_public_preview" name="_allow_public_preview" value="1" />
Allow public preview
</label>
</div>
DOC;
echo $html;
}
add_action(\'post_submitbox_misc_actions\', \'allow_draft_public_preview\');
function update_post_status( $post_id, $post, $update ) {
if ( !empty($_POST[\'_allow_public_preview\']) ) {
//un-hook to prevent infinite loop
remove_action( \'save_post\', \'update_post_status\', 13, 2 );
//set the post to publish so it gets the slug is saved to post_name
wp_update_post( array( \'ID\' => $post_id, \'post_status\' => \'publish\' ) );
//immediately put it back to draft status
wp_update_post( array( \'ID\' => $post_id, \'post_status\' => \'draft\' ) );
//re-hool
add_action( \'save_post\', \'update_post_status\', 13, 2 );
}
}
add_action(\'save_post\', \'update_post_status\', 13, 2);
附加到的第一个回调
post_submitbox_misc_actions
操作将复选框添加到后期编辑屏幕;允许公共预览;。。。
...当您标记此复选框时,将通过在
save_post
行动
在save_post
操作我们检查中是否存在复选框$_POST
超全局,如果存在,我们将post状态设置为publish 然后立即将其设置回draft.
现在,您可以通过他们的slug/pretty permalinks访问草稿帖子,登录或注销。
现在大家一起:
function preview_draft_posts($query) {
if ( is_admin() || get_query_var(\'suppress_filters\') )
return $query;
$query->set(\'post_status\', array(\'publish\', \'pending\', \'draft\'));
return $query;
}
add_filter(\'pre_get_posts\', \'preview_draft_posts\');
function the_posts_preview_draft_posts($posts, $wp_query) {
//abort if $posts is not empty, this query ain\'t for us...
if ( count($posts) ) {
return $posts;
}
$p = get_query_var(\'p\');
//get our post instead and return it as the result...
if ( !empty($p) ) {
return array(get_post($p));
}
}
add_filter(\'the_posts\', \'the_posts_preview_draft_posts\', 10, 2);
function allow_draft_public_preview( ) {
global $post;
if ( !empty($post->post_name) )
return;
$html =<<<DOC
<div class="misc-pub-section">
<label>
<input type="checkbox" id="_allow_public_preview" name="_allow_public_preview" value="1" />
Allow public preview
</label>
</div>
DOC;
echo $html;
}
add_action(\'post_submitbox_misc_actions\', \'allow_draft_public_preview\');
function update_post_status( $post_id, $post, $update ) {
if ( !empty($_POST[\'_allow_public_preview\']) ) {
//un-hook to prevent infinite loop
remove_action( \'save_post\', \'update_post_status\', 13, 2 );
//set the post to publish so it gets the slug is saved to post_name
wp_update_post( array( \'ID\' => $post_id, \'post_status\' => \'publish\' ) );
//immediately put it back to draft status
wp_update_post( array( \'ID\' => $post_id, \'post_status\' => \'draft\' ) );
//re-hool
add_action( \'save_post\', \'update_post_status\', 13, 2 );
}
}
add_action(\'save_post\', \'update_post_status\', 13, 2);