按自定义帖子的自定义分类在单个页面上显示相关帖子

时间:2015-05-15 作者:BigDropGR

我正在尝试建立一个别墅租赁网站。为了实现这一点,我创建了两种自定义帖子类型。一个名为“别墅”,用于显示出租别墅,另一个名为“目的地”,用于显示该别墅所在的位置。

我用了CPT-onomies 插件使“destinations”自定义帖子类型,这是我的自定义帖子类型“villa”的自定义分类法。有两种自定义贴子类型,一种用作另一种的分类,以显示别墅的位置。在每栋别墅上。php页面我想在文章的最后显示一个相关的别墅(在循环之后),我希望这个相关的别墅只通过目的地(这是一个自定义的分类法)相关。

我发现this 文章中,我按照说明做了,但不知怎么的,它帮了我的忙,不幸的是,我不能想出两件事:1。首先,我不知道如何让它只显示一个相关的别墅(帖子),而不是所有相关的帖子。2、我不知道如何将当前帖子从相关帖子中排除(我在上面链接的文章中有关于如何做到这一点的说明,但这对我不起作用。)

我将此代码添加到函数中。php

// Create a query for the custom taxonomy
    function related_posts_by_taxonomy( $post_id, $taxonomy, $args=array() ) {
        $query = new WP_Query();
        $terms = wp_get_object_terms( $post_id, $taxonomy );

        // Make sure we have terms from the current post
        if ( count( $terms ) ) {
            $post_ids = get_objects_in_term( $terms[0]->term_id, $taxonomy );
            $post = get_post( $post_id );
            $post_type = get_post_type( $post );

            // Only search for the custom taxonomy on whichever post_type
            // we AREN\'T currently on
            // This refers to the custom post_types you created so
            // make sure they are spelled/capitalized correctly
            if ( strcasecmp($post_type, \'sites\') == 0 ) {
                $type = \'sites\';
            } else {
                $type = \'sites\';
            }

            $args = wp_parse_args( $args, array(
                    \'post_type\' => $type,
                    \'post__in\' => $post_ids,
                    \'taxonomy\' => $taxonomy,
                    \'term\' => $terms[0]->slug,
                ) );
            $query = new WP_Query( $args );
        }

        // Return our results in query form
        return $query;
    }
而这个代码到了单人别墅。php

<?php $related =  related_posts_by_taxonomy( $post->ID, \'destinations\' );
        while ( $related->have_posts() ): $related->the_post(); ?>

            <div class="inner">
                <a href="<?php get_permalink(); ?>"><?php the_post_thumbnail(); ?>  </a>
                <?php echo get_the_title(); ?>      

        </div>

        <?php endwhile; ?>
我不想使用任何插件,相反,我想为我的主题添加一些代码来实现这一点。

提前感谢您的时间和回答!我想道歉,但英语不是我的母语!感谢您的理解。

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

我只想放弃上面的函数,因为代码中有几个bug,而且效率也不太高。我真的很惊讶它真的对你有用。

您最好的解决方案是编写一个完整的新函数。以下是我们想要做的事情以及我们将如何实现这一点

获取单个贴子页面上的当前贴子对象。$post 不可靠,因此我们将在此处使用主查询对象,并返回get_queried_object(). 从这里,我们可以使用帖子ID和帖子类型来获取其他相关信息

查看当前帖子的条款wp_get_post_term(). 我们将设置fields 参数仅获取术语ID。然后可以在我们的tax_query

添加一些验证以验证用户输入并清理输入

让我们把这一切都放在代码中(注意:这都是未经测试的,至少需要PHP 5.4+)

function get_related_posts( $taxonomy = \'\', $args = [] )
{
    /*
     * Before we do anything and waste unnecessary time and resources, first check if we are on a single post page
     * If not, bail early and return false
     */
    if ( !is_single() )
        return false;

    /*
     * Check if we have a valid taxonomy and also if the taxonomy exists to avoid bugs further down.
     * Return false if taxonomy is invalid or does not exist
     */
    if ( !$taxonomy ) 
        return false;

    $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
    if ( !taxonomy_exists( $taxonomy ) )
        return false;

    /*
     * We have made it to here, so we should start getting our stuff togther. 
     * Get the current post object to start of
     */
    $current_post = get_queried_object();

    /*
     * Get the post terms, just the ids
     */
    $terms = wp_get_post_terms( $current_post->ID, $taxonomy, [\'fields\' => \'ids\'] );

    /*
     * Lets only continue if we actually have post terms and if we don\'t have an WP_Error object. If not, return false
     */
    if ( !$terms || is_wp_error( $terms ) )
        return false;

    /*
     * Set the default query arguments
     */
    $defaults = [
        \'post_type\' => $current_post->post_type,
        \'post__not_in\' => [$current_post->ID],
        \'tax_query\' => [
            [
                \'taxonomy\' => $taxonomy,
                \'terms\' => $terms,
                \'include_children\' => false
            ],
        ],
    ];

    /*
     * Validate and merge the defaults with the user passed arguments
     */
    if ( is_array( $args ) ) {
        $args = wp_parse_args( $args, $defaults );
    } else {
        $args = $defaults;
    }

    /*
     * Now we can query our related posts and return them
     */
    $q = get_posts( $args );

    return $q;
}
现在我们有了一个更好的功能,我们可以在单个帖子页面或内容模板部分中使用它,具体取决于您的具体用例。您可能已经注意到,我们的新功能get_related_posts() 有两个参数,第一个参数接受单个分类法值,第二个参数是参数数组。此参数将传递给查询的参数,因此您可以传递可接受的任何有效参数数组WP_Queryget_posts 在这里

示例:

您需要返回一篇文章,因此可以尝试以下操作:(请注意,不要在此处使用post类型参数或任何分类类型参数,您可能会得到意外的输出)

if ( function_exists( \'get_related_posts\' ) ) {
    $related_posts = get_related_posts( \'my_taxonomy_name\', [\'posts_per_page\' => 1] );
    if ( $related_posts ) {
        foreach ( $related_posts as $post ) {
            setup_postdata( $post ); 
            // Use your template tags and html mark up as normal like
            the_title();
            the_content();
            // etc etc
        }
        wp_reset_postdata();
    }
}
根据评论,您的PHP版本似乎早于5.4版本,它不支持新的短数组语法([]), 因此你得到了可怕的WSOD。为此,需要将新的数组语法更改为旧语法(array()).

您可以尝试以下操作:

function get_related_posts( $taxonomy = \'\', $args = array() )
{
    /*
     * Before we do anything and waste unnecessary time and resources, first check if we are on a single post page
     * If not, bail early and return false
     */
    if ( !is_single() )
        return false;

    /*
     * Check if we have a valid taxonomy and also if the taxonomy exists to avoid bugs further down.
     * Return false if taxonomy is invalid or does not exist
     */
    if ( !$taxonomy ) 
        return false;

    $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
    if ( !taxonomy_exists( $taxonomy ) )
        return false;

    /*
     * We have made it to here, so we should start getting our stuff togther. 
     * Get the current post object to start of
     */
    $current_post = get_queried_object();

    /*
     * Get the post terms, just the ids
     */
    $terms = wp_get_post_terms( $current_post->ID, $taxonomy, array( \'fields\' => \'ids\') );

    /*
     * Lets only continue if we actually have post terms and if we don\'t have an WP_Error object. If not, return false
     */
    if ( !$terms || is_wp_error( $terms ) )
        return false;

    /*
     * Set the default query arguments
     */
    $defaults = array(
        \'post_type\' => $current_post->post_type,
        \'post__not_in\' => array( $current_post->ID),
        \'tax_query\' => array(
            array(
                \'taxonomy\' => $taxonomy,
                \'terms\' => $terms,
                \'include_children\' => false
            ),
        ),
    );

    /*
     * Validate and merge the defaults with the user passed arguments
     */
    if ( is_array( $args ) ) {
        $args = wp_parse_args( $args, $defaults );
    } else {
        $args = $defaults;
    }

    /*
     * Now we can query our related posts and return them
     */
    $q = get_posts( $args );

    return $q;
}
然后要在模板中使用代码,请更改为

if ( function_exists( \'get_related_posts\' ) ) {
    $related_posts = get_related_posts( \'my_taxonomy_name\', array( \'posts_per_page\' => 1) );
    if ( $related_posts ) {
        foreach ( $related_posts as $post ) {
            setup_postdata( $post ); 
            // Use your template tags and html mark up as normal like
            the_title();
            the_content();
            // etc etc
        }
        wp_reset_postdata();
    }
}

SO网友:ngearing

因此,要解决您的2个问题,我们所要做的就是修改用于查询的$args数组。由于这是一个查询,我们可以使用Wordpress在此处为我们提供的任何参数:WP_Query.

就像这个:post__not_in (array) - use post ids. Specify post NOT to retrieve.

还有这个:posts_per_page (int) - number of post to show per page

现在,让我们将这两个参数添加到$args数组中。

$args = wp_parse_args( $args, array(
    \'post_type\' => $type,
    \'post__in\' => $post_ids,
    \'taxonomy\' => $taxonomy,
    \'term\' => $terms[0]->slug,
    \'post__not_in\' => $post_id, // $post_id has already been provided for us.
    \'posts_per_page\' => 1,
) );
应该就是这样。这可能还会显示分类法的最新帖子,因此您可能会看到很多相同的“别墅”。但您可以设置orderby 参数来修复该问题。

结束

相关推荐