如果您不想使用插件(或者找不到一个可以满足您需要的插件),您可能需要这样做:
添加custom meta box 允许您将帖子标记为hidden.使用修改查询pre_get_posts 从站点中删除标记为隐藏的帖子(但可以通过直接链接获得)
UPDATE
根据上述建议,这里有一个可能的解决方案。
Create a custom meta box
首先,注册一个自定义元框,创建自定义元框:
function yourtextdomain_add_custom_meta_box() {
add_meta_box("demo-meta-box", "Custom Meta Box", "yourtextdomain_custom_meta_box_markup", "post", "side", "high", null);
}
add_action("add_meta_boxes", "yourtextdomain_add_custom_meta_box");
将标记添加到元框(本例中为复选框):
function yourtextdomain_custom_meta_box_markup($object) {
wp_nonce_field(basename(__FILE__), "meta-box-nonce"); ?>
<div>
<br />
<label for="meta-box-checkbox">Hidden</label>
<?php $checkbox_value = get_post_meta($object->ID, "meta-box-checkbox", true);
if($checkbox_value == "") { ?>
<input name="meta-box-checkbox" type="checkbox" value="true">
<?php } else if($checkbox_value == "true") { ?>
<input name="meta-box-checkbox" type="checkbox" value="true" checked>
<?php } ?>
<p style="color: #cccccc"><i>When selected, the post will be removed from the WP loop but still accessible from a direct link.</i></p>
</div>
<?php
}
这将为每个帖子提供一个元框,如下所示:

最后保存元框值:
function yourtextdomain_save_custom_meta_box($post_id, $post, $update) {
if (!isset($_POST["meta-box-nonce"]) || !wp_verify_nonce($_POST["meta-box-nonce"], basename(__FILE__)))
return $post_id;
if(!current_user_can("edit_post", $post_id))
return $post_id;
if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE)
return $post_id;
$slug = "post";
if($slug != $post->post_type)
return $post_id;
$meta_box_checkbox_value = "";
if(isset($_POST["meta-box-checkbox"])) {
$meta_box_checkbox_value = $_POST["meta-box-checkbox"];
}
update_post_meta($post_id, "meta-box-checkbox", $meta_box_checkbox_value);
}
add_action("save_post", "yourtextdomain_save_custom_meta_box", 10, 3);
在
wp_postmeta 表中,您现在应该看到分配给已检查为隐藏和保存的帖子的元值“true”:

Modifying the query with pre_get_posts
现在只需过滤掉那些在主查询中标记为隐藏的帖子。我们可以用
pre_get_posts:
add_action( \'pre_get_posts\', \'yourtextdomain_pre_get_posts_hidden\', 9999 );
function yourtextdomain_pre_get_posts_hidden( $query ){
// Check if on frontend and main query.
if( ! is_admin() && $query->is_main_query() ) {
// For the posts we want to exclude.
$exclude = array();
// Locate our posts marked as hidden.
$hidden = get_posts(array(
\'post_type\' => \'post\',
\'meta_query\' => array(
array(
\'key\' => \'meta-box-checkbox\',
\'value\' => \'true\',
\'compare\' => \'==\',
),
)
));
// Create an array of hidden posts.
foreach($hidden as $hide) {
$exclude[] = $hide->ID;
}
// Exclude the hidden posts.
$query->set(\'post__not_in\', $exclude);
}
}