获取与当前帖子相关的下一个/上一个帖子

时间:2011-04-11 作者:Pippin

我有7篇帖子,如下所示:

1
2
3
4-这是当前的职位
5
6
7

如前所述,数字4是当前显示的帖子。我需要创建一个查询,允许我显示之前的3篇文章(按发布日期),以及之后的3篇文章。这可以通过两个单独的查询完成。

我能够显示上一篇或下一篇文章,只是不能显示进一步向下/向上的文章。

有什么想法吗?

4 个回复
最合适的回答,由SO网友:t31os 整理而成

这可以在一个查询中完成,但我不能具体说明这个查询的性能如何(我没有花太多时间处理联合查询-到目前为止,我从来没有需要过)。。

首先,函数选择两组结果,但使用union将它们作为单个结果集返回。

function get_post_siblings( $limit = 3, $date = \'\' ) {
    global $wpdb, $post;

    if( empty( $date ) )
        $date = $post->post_date;

    //$date = \'2009-06-20 12:00:00\'; // test data

    $limit = absint( $limit );
    if( !$limit )
        return;

    $p = $wpdb->get_results( "
    (
        SELECT 
            p1.post_title, 
            p1.post_date,
            p1.ID
        FROM 
            $wpdb->posts p1 
        WHERE 
            p1.post_date < \'$date\' AND 
            p1.post_type = \'post\' AND 
            p1.post_status = \'publish\' 
        ORDER by 
            p1.post_date DESC
        LIMIT 
            $limit
    )
    UNION 
    (
        SELECT 
            p2.post_title, 
            p2.post_date,
            p2.ID 
        FROM 
            $wpdb->posts p2 
        WHERE 
            p2.post_date > \'$date\' AND 
            p2.post_type = \'post\' AND 
            p2.post_status = \'publish\' 
        ORDER by
            p2.post_date ASC
        LIMIT 
            $limit
    ) 
    ORDER by post_date ASC
    " );
    $i = 0;
    $adjacents = array();
    for( $c = count($p); $i < $c; $i++ )
        if( $i < $limit )
            $adjacents[\'prev\'][] = $p[$i];
        else
            $adjacents[\'next\'][] = $p[$i];

    return $adjacents;
}
其中有一个测试日期,您可以安全地忽略该日期或添加您自己的测试值。

下面是一些示例代码,您可以在single.php 循环列出结果,但请注意,这只是一个通用示例,函数可能需要选择更多/不同的数据,但根据您提供的信息,我不确定您到底想要什么,因此以下是示例,并提供一个可用于测试结果的示例。。

<?php 
$siblings = get_post_siblings( 3 ); // This is the same as doing the call below(which is just for illustration)
//$siblings = get_post_siblings( 3, $post->post_date );

$prev = $siblings[\'prev\'];

foreach( $prev as $p )
    echo get_the_time( \'d m Y\', $p ) . \': \' . apply_filters( \'the_title\', $p->post_title ) . \'<br />\';

$next = $siblings[\'next\'];

foreach( $next as $p )
    echo get_the_time( \'d m Y\', $p ) . \': \' . apply_filters( \'the_title\', $p->post_title ) . \'<br />\';
?>
正在等待反馈…:)

SO网友:raison

使用WP\\u query类的date\\u query属性可以更好地做到这一点。这将在当前帖子的发布日期之前获取帖子

// WP_Query arguments
$args = array (
    \'post_type\'              => \'post\',
    \'post_status\'            => \'publish\',
     \'date_query\'    => array(
        \'column\'  => \'post_date\',
        \'before\'   => get_the_date()
    ),
);

// The Query
$the_query = new WP_Query( $args );
。。。。。。。。。

SO网友:onetrickpony

3 xget_adjacent_post():

global $post;
$current_post = $post; // remember the current post

for($i = 1; $i <= 3; $i++){
  $post = get_previous_post(); // this uses $post->ID
  setup_postdata($post);

  // do your stuff here       
  the_title();

}

$post = $current_post; // restore
对于接下来的3篇文章也是如此,只需将函数更改为get\\u next\\u post()。。。

要在仍然使用WP API的情况下使用单个查询执行此操作,请尝试更改LIMITget_previous_post_sort and get_next_post_sort 过滤器。

SO网友:djb

正如JanFabry在上面对@onetrickpony的回答中所建议的那样,您可以修改get\\u nextrick\\u post()。这就是我所做的。下面是函数。我更改了函数签名,因为这样对我更有意义。

/**
 * Retrieve multiple adjacent posts. Adapted from get_adjacent_post()
 *
 * Can either be next or previous post.
 *
 * @since 2.5.0
 *
 * @param int       $post_id    Optional. Will fall back to loop.
 * @param int       $limit      Optional. Number of posts to return.
 * @param bool          $previous       Optional. Whether to retrieve previous or next posts.
 * @param bool          $in_same_term   Optional. Whether post should be in a same taxonomy term.
 * @param array|string  $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
 * @param string        $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default \'category\'.
 * @return mixed        Array of post objects if successful. Null if global $post is not set. Empty string if no corresponding post exists.
 */
function pst_get_adjacent_posts( $post_id = null, $limit = 1, $previous = true, $in_same_term = false, $excluded_terms = \'\', $taxonomy = \'category\' ) {
    global $wpdb;

    if ( ( ! $post = get_post( $post_id ) ) || ! taxonomy_exists( $taxonomy ) )
        return null;

    $current_post_date = $post->post_date;

    $join = \'\';
    $posts_in_ex_terms_sql = \'\';
    if ( $in_same_term || ! empty( $excluded_terms ) ) {
        $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";

        if ( $in_same_term ) {
            if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
                return \'\';
            $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( \'fields\' => \'ids\' ) );
            if ( ! $term_array || is_wp_error( $term_array ) )
                return \'\';
            $join .= $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id IN (" . implode( \',\', array_map( \'intval\', $term_array ) ) . ")", $taxonomy );
        }

        $posts_in_ex_terms_sql = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
        if ( ! empty( $excluded_terms ) ) {
            if ( ! is_array( $excluded_terms ) ) {
                // back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and "
                if ( false !== strpos( $excluded_terms, \' and \' ) ) {
                    _deprecated_argument( __FUNCTION__, \'3.3\', sprintf( __( \'Use commas instead of %s to separate excluded terms.\' ), "\'and\'" ) );
                    $excluded_terms = explode( \' and \', $excluded_terms );
                } else {
                    $excluded_terms = explode( \',\', $excluded_terms );
                }
            }

            $excluded_terms = array_map( \'intval\', $excluded_terms );

            if ( ! empty( $term_array ) ) {
                $excluded_terms = array_diff( $excluded_terms, $term_array );
                $posts_in_ex_terms_sql = \'\';
            }

            if ( ! empty( $excluded_terms ) ) {
                $posts_in_ex_terms_sql = $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id NOT IN (" . implode( $excluded_terms, \',\' ) . \')\', $taxonomy );
            }
        }
    }

    $adjacent = $previous ? \'previous\' : \'next\';
    $op = $previous ? \'<\' : \'>\';
    $order = $previous ? \'DESC\' : \'ASC\';

    /**
     * Filter the JOIN clause in the SQL for an adjacent post query.
     *
     * The dynamic portion of the hook name, $adjacent, refers to the type
     * of adjacency, \'next\' or \'previous\'.
     *
     * @since 2.5.0
     *
     * @param string $join           The JOIN clause in the SQL.
     * @param bool   $in_same_term   Whether post should be in a same taxonomy term.
     * @param array  $excluded_terms Array of excluded term IDs.
     */
    $join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms );

    /**
     * Filter the WHERE clause in the SQL for an adjacent post query.
     *
     * The dynamic portion of the hook name, $adjacent, refers to the type
     * of adjacency, \'next\' or \'previous\'.
     *
     * @since 2.5.0
     *
     * @param string $where          The WHERE clause in the SQL.
     * @param bool   $in_same_term   Whether post should be in a same taxonomy term.
     * @param array  $excluded_terms Array of excluded term IDs.
     */
    $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = \'publish\' $posts_in_ex_terms_sql", $current_post_date, $post->post_type), $in_same_term, $excluded_terms );

    /**
     * Filter the ORDER BY clause in the SQL for an adjacent post query.
     *
     * The dynamic portion of the hook name, $adjacent, refers to the type
     * of adjacency, \'next\' or \'previous\'.
     *
     * @since 2.5.0
     *
     * @param string $order_by The ORDER BY clause in the SQL.
     */
    $sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT $limit" );

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

    $result = $wpdb->get_col( $query );
    if ( null === $result )
        $result = \'\';

    wp_cache_set( $query_key, $result, \'counts\' );

    if ( $result )
        $result = array_map( \'get_post\', $result );

    return $result;
}

结束