这是我对事情的看法。我已经放弃了您的完整想法,选择了一个不使用SQL的替代解决方案。我已经做了一些测试,发现我的方法比您问题中的代码快得多
想法是:
你首先需要获得当前的帖子id,我会通过它
get_queried_object_id()
. 帖子ID将用于检索:
该职位所属的职位术语wp_get_post_terms()
. 为了加快速度,只会返回条款的ID。将使用第一个ID(如果一篇文章有多个术语,您可以在此处修改代码以决定将使用哪个术语),并将使用该ID检索具有该特定术语的所有文章
与此帖子直接相邻的帖子ID,用于确定和检索此帖子的下一篇和上一篇帖子
上述所有信息将用于tax_query
具有get_posts
从当前帖子中检索共享术语的所有帖子。在函数中,默认分类法为category
以及post_type
设置为any以获取具有此特定术语的所有帖子
同样,为了使代码更快和资源更安全,我们只需要获取post ID,因为这是所需的全部
现在是代码的重要部分。我们现在需要确定以下内容:
当前帖子在自定义返回的帖子ID数组中的当前位置get_posts
查询此处使用的函数是array_search
如果在这篇文章之前或之后有一篇文章(下一篇或之前的文章),定义与内置函数相同next_post_link()
和previous_post_link()
),获取这些帖子的ID
使用IDget_post
从当前帖子中检索下一篇和上一篇帖子的标题
最后将返回链接。如果当前帖子是数组中的第一篇或最后一篇帖子,并且没有下一篇或上一篇帖子,我已经设置了消息。您可以决定在这里要做什么,对于所有重要的事情,代码的其余部分
为了使代码更快、更高效,我使用了Transient API 你可以进一步阅读。我还使用了transition_post_status
动作钩子钩住一个函数,每当post的post状态改变时,该函数将删除这些瞬态。这包括发布新帖子、更新帖子和删除/取消删除帖子
代码:
这是代码。这将进入您的功能。php
function get_post_link( $taxonomy = \'category\', $post_type = [ \'any\' ] ) {
$id = get_queried_object_id(); // Get the current post ID
$transient_id = \'post_number_\' . md5( $id . $taxonomy . implode( \',\', $post_type ) ); //Create a unique transient id
if ( false === ( $links = get_transient( $transient_id ) ) ) {
// Get the terms a post belongs to
$terms = wp_get_post_terms( $id, $taxonomy, array( \'fields\' => \'ids\' ) );
// Use a tax_query to get all posts from the given term
// Just retrieve the ids to speed up the query
$post_args = [
\'post_type\' => $post_type,
\'fields\' => \'ids\',
\'posts_per_page\' => -1,
\'tax_query\' => [
[
\'taxonomy\' => $taxonomy,
\'field\' => \'term_id\',
\'terms\' => $terms[0],
\'include_children\' => false,
],
],
];
// Get all the posts having the given term from all post types
$q = get_posts( $post_args );
//Get the current post position. Will be used to determine next/previous post
$current_post_position = array_search( $id, $q );
// Get the previous/older post ID
if ( array_key_exists( $current_post_position + 1 , $q ) ) {
$previous = $q[$current_post_position + 1];
}
// Get post title link to the previous post
if( isset( $previous ) ) {
$previous_post = get_post( $previous );
$previous_post_link = get_permalink( $previous );
$previous_title = \'<a href="\' . $previous_post_link . \'">\' . $previous_post->post_title . \'</a></br>\';
}
// Get the next/newer post ID
if ( array_key_exists( $current_post_position - 1 , $q ) ) {
$next = $q[$current_post_position - 1];
}
// Get post title link to the next post
if( isset( $next ) ) {
$next_post = get_post( $next );
$next_post_link = get_permalink( $next );
$next_title = \'<a href="\' . $next_post_link . \'">\' . $next_post->post_title . \'</a></br>\';?><pre><?php var_dump($next_title); ?></pre><?php
}
// The returned post links
if( isset( $previous_title, $next_title ) ) {
$links = [
\'previous_post\' => $previous_title,
\'next_post\' => $next_title,
];
}elseif( !isset( $previous_title ) && $next_title ) {
$links = [
\'previous_post\' => \'You are currently viewing the newest post\',
\'next_post\' => $next_title,
];
}elseif( $previous_title && !isset( $next_title ) ) {
$links = [
\'previous_post\' => $previous_title,
\'next_post\' => \'You are currently viewing the last post\',
];
}
set_transient( $transient_id, $links, 7 * DAY_IN_SECONDS );
}
return (object)$links;
}
add_action( \'transition_post_status\', function ( $new_status, $old_status, $post )
{
global $wpdb;
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient%_post_number_%\')" );
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient_timeout%_post_number_%\')" );
}, 10, 3 );
如何使用:您现在可以在单曲中使用以下代码。php。默认分类法为
category
岗位类型为
any
. 如果调用自定义分类法
mytax
, 您可以这样使用代码
if( function_exists( \'get_post_link\' ) ) {
$post_links = get_post_link( \'mytax\' );
echo $post_links->previous_post . \'</br>\' . $post_links->next_post;
}