浏览同一类别中具有不同帖子类型的帖子

时间:2014-11-30 作者:at least three characters

我创建了两个共享相同类别分类法的自定义帖子类型。我正在使用next_post_link()previous_post_link() 浏览具有相同类别但仅适用于单个帖子类型的帖子。

我找到了以下链接帖子类型的代码,但下一篇和上一篇帖子不能与当前帖子位于同一分类/类别中。

/*
 * Replacement for get_adjacent_post()
 *
 * This supports only the custom post types you identify and does not
 * look at categories anymore. This allows you to go from one custom post type
 * to another which was not possible with the default get_adjacent_post().
 * Orig: wp-includes/link-template.php 
 * 
 * @param string $direction: Can be either \'prev\' or \'next\'
 * @param multi $post_types: Can be a string or an array of strings
 */
function mod_get_adjacent_post($direction = \'prev\', $post_types = \'post\') {
    global $post, $wpdb;

    if(empty($post)) return NULL;
    if(!$post_types) return NULL;

    if(is_array($post_types)){
        $txt = \'\';
        for($i = 0; $i <= count($post_types) - 1; $i++){
            $txt .= "\'".$post_types[$i]."\'";
            if($i != count($post_types) - 1) $txt .= \', \';
        }
        $post_types = $txt;
    }

    $current_post_date = $post->post_date;

    $join = \'\';
    $in_same_cat = FALSE;
    $excluded_categories = \'\';
    $adjacent = $direction == \'prev\' ? \'previous\' : \'next\';
    $op = $direction == \'prev\' ? \'<\' : \'>\';
    $order = $direction == \'prev\' ? \'DESC\' : \'ASC\';

    $join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_cat, $excluded_categories );
    $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type IN({$post_types}) AND p.post_status = \'publish\'", $current_post_date), $in_same_cat, $excluded_categories );
    $sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );

    $query = "SELECT p.* FROM $wpdb->posts AS p $join $where $sort";
    $query_key = \'adjacent_post_\' . md5($query);
    $result = wp_cache_get($query_key, \'counts\');
    if ( false !== $result )
        return $result;

    $result = $wpdb->get_row("SELECT p.* FROM $wpdb->posts AS p $join $where $sort");
    if ( null === $result )
        $result = \'\';

    wp_cache_set($query_key, $result, \'counts\');
    return $result;
}
使用情况

<?php
$prev = mod_get_adjacent_post(\'prev\', array(\'post\', \'custom1\', \'custom2\'));
$next = mod_get_adjacent_post(\'next\', array(\'post\', \'custom1\', \'custom2\'));
?>

<?php if($prev) : ?>
    <a href="<?php echo get_permalink($prev->ID)?>">&laquo; Go back in time</a>
<?php endif; ?>

<?php if($next) : ?>
    <a href="<?php echo get_permalink($next->ID)?>">Next: <?php echo $next->post_title; ?> &raquo;</a>
<?php endif; ?>
如何使用相同的分类法浏览帖子?

1 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

这是我对事情的看法。我已经放弃了您的完整想法,选择了一个不使用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;
}

结束

相关推荐

在没有MySQL错误的情况下将测试主题移动到实时站点-如何?

我在一个隐藏的测试站点上安装了wordpress主题,并对css/设计进行了一些更改。如何将其移动到我的live站点?遗憾的是,当我试图将帖子从实时站点复制到测试站点数据库时,我把一些PHP/MySQL的东西搞砸了,出现了一个非常可怕的重定向循环。我是否可以避免重蹈覆辙,或者我真的需要从头开始基本主题和定制?测试地点:http://173.254.28.65/~neveren2/thundercatsaremyhomeboys/ - 可怕的重定向循环-实时站点:http://www.neverenough