如何加载带有特定自定义域的随机相关帖子?

时间:2021-06-13 作者:Sadegh

我想加载与当前帖子具有相同自定义字段值的3篇帖子
例如:
当前帖子有3个自定义字段:
颜色:黑色
背景:红色
姓氏:doe
现在我想用这些自定义字段加载三篇帖子:
第一篇帖子:颜色:黑色
第二篇帖子:背景:红色
第三篇帖子:姓氏:doe
这些是我的代码:

$page_id = get_the_ID();
$color= get_field( "color", $page_id );
$background= get_field( "background", $page_id );
$lastname= get_field( "lastname", $page_id );
$color_array = array ("the_color"=>$color);
$background_array = array ("the_background"=>$background);
$lastname_array = array ("the_lastname"=>$lastname);
$related_args = array($color_array ,$background_array ,$lastname_array );
foreach($related_args as $args) {
 foreach($args as $key => $value){
   echo $value; //to know the post after it are from that custom post
   $myargs = array(
            \'post_type\' => \'myposttype\',
            \'orderby\'   => \'rand\',
            \'meta_key\'      => $key,
            \'meta_value\'    => $value,
            \'posts_per_page\' => 1,
            );
         
        $the_query = new WP_Query( $myargs );
        if ( $the_query->have_posts() ) {
        $string .= \'<ul>\';
            while ( $the_query->have_posts() ) {
                $the_query->the_post();
                $string .= \'<li><a href="\'. get_permalink() .\'">\'. \'<div class="post-image">\' . get_the_post_thumbnail() . \'</div>\' . \'<div class="post-title">\' . get_the_title() . \'</div>\' .\'</a></li>\';
            }
            $string .= \'</ul>\';
            wp_reset_postdata();
        } else {
         
        $string .= \'no posts found\';
        }
        echo $string;
  }
}
正如您在代码中看到的,我检索了当前的post自定义字段值,然后创建了具有meta\\u键和meta\\u值的数组。然后创建了一个数组。然后我创建了两个循环来查找3篇文章,其中每一篇都有与当前文章相同的自定义字段<问题是:
它加载一篇带有第一个自定义字段的帖子,两篇带有第二个自定义字段的帖子,三篇带有第三个自定义字段的帖子
但我希望它加载一篇带有第一个自定义字段的帖子,一篇带有第二个自定义字段的帖子,一篇带有第三个自定义字段的帖子<请告诉我怎样才能做到这一点
谢谢

2 个回复
最合适的回答,由SO网友:Paul G. 整理而成

我已经获取了您的代码并对其进行了重构。嵌套for循环并不是实现这一点的理想方式。

此外,我使用的代码和元键名称与您提供的完全相同,因此请仔细检查它们是否正确。其中一些前缀为the_ 有时也不会。这很奇怪,但那是你提供的。

请尝试下面的代码,看看每个代码是否只有一个。

<?php
$page_id = get_the_ID();
$related_args = [
    \'the_color\'      => get_field( \'color\', $page_id ),
    \'the_background\' => get_field( \'background\', $page_id ),
    \'the_lastname\'   => get_field( \'lastname\', $page_id )
];

$content = \'\';

foreach ( $related_args as $meta_key => $meta_value ) {

    $content .= $meta_value;  //to know the post after it are from that custom post

    $posts = get_posts( [
        \'post_type\'   => \'myposttype\',
        \'orderby\'     => \'rand\',
        \'meta_key\'    => $meta_key,
        \'meta_value\'  => $meta_value,
        \'numberposts\' => 1,
    ] );

    if ( !empty( $posts ) ) {
        $postID = current( $posts )->ID;
        $content .= sprintf( \'<ul><li><a href="%s"><div class="post-image">%s</div><div class="post-title">%s</div></a></li></ul>\',
            get_permalink( $postID ),
            get_the_post_thumbnail( $postID ),
            get_the_title( $postID )
        );
    }
    else {
        $content .= \'no posts found\';
    }
}

echo $content;

SO网友:Fabian Mossberg

我知道您正在使用ACF,但我想给出一个解决方案,在这个过程中我会更深入一些,并将其分解到不同的步骤中。我还没有使用ACF,所以它可以在没有任何插件的情况下工作。

首先,函数我将所需的不同部分分解为可以在其他地方重用的函数。

我也试着写得恰到好处docblocks, 因此,如果您有一个支持它的编辑器,就会提醒您函数的作用,并且它会阻止您传递任何错误类型的变量。

这可以粘贴到您的主题中functions.php, 或一个名为fabians-functions.php 然后只需将以下行添加到functions.php.

require_once __DIR__ . \'/fabians-functions.php\';
/**
 * Get meta data key/value pairs.
 *
 * Pass an array of meta keys, get an array of
 * key/value pairs.
 *
 * @param array $meta_keys the meta keys you want to fetch.
 * @param int   $post_id the post ID you want to fetch them from.
 * @return array an associative array with meta_key => meta_value.
 */
function get_multiple_meta_values( array $meta_keys, int $post_id ) {
    $output_meta_key_value_pairs = array();
    foreach ( $meta_keys as $meta_key ) {
        $meta_value = get_post_meta( $post_id, $meta_key, true );
        if ( $meta_value ) {
            $output_meta_key_value_pairs[] = array(
                $meta_key => $meta_value,
            );
        }
    }
    // Flatten the array and remove any invalid entries.
    return array_merge( ...array_filter( $output_meta_key_value_pairs ) );
}

/**
 * Fetch posts with same meta vaues
 *
 * Pass in an associative array with the custom fields
 * you want to use to find similar posts.
 *
 * We will fetch one post per meta key/value passed.
 * We will not return the current post.
 * We will not return the same post twice.
 *
 * @param array $meta_collection an associative array with meta_key => meta_value.
 * @return WP_Post[] an array of WP Posts.
 */
function get_posts_with_same_meta( array $meta_collection ) {
    $output          = array();
    $wp_ignore_posts = array( get_the_ID() );

    // Now let\'s go trhough each of the meta fields you want to find posts on.
    foreach ( $meta_collection as $key => $value ) {

        $args = array(
            \'post_type\'      => \'post\',
            // Only one posts.
            \'posts_per_page\' => 1,
            \'post_status\'    => \'publish\',
            // That shares the first meta key/value pair.
            \'meta_key\'       => "$key",
            \'meta_value\'     => "$value",
            /**
             * Because we don\'t want to end up short, we need to
             * filter out any posts that was previously fetched.
             * We don\'t want duplicates to show up.
             */
            \'post__not_in\'   => $wp_ignore_posts,
        );

        $the_query = new WP_Query( $args );
        if ( $the_query->have_posts() ) :
            while ( $the_query->have_posts() ) :
                $the_query->the_post();
                // If we got a hit, add that post to $output[].
                $output[] = $the_query->post;
                // Also, add that posts ID to the ignore-list, so we won\'t fetch it again.
                $wp_ignore_posts[] = get_the_ID();
            endwhile;
        endif;
        wp_reset_postdata();
    }
    return $output;
}

然后,有趣的是,现在我们已经完成了所有设置,我们可以开始使用页面模板中的功能了。

// Setup - Define the meta keys you wish to use.
$meta_keys_i_want_to_use = array( \'color\', \'background_color\', \'lastname\' );

// Fetch the meta values from the current post and save in $wpm_meta.
// You can set any number of meta values.
$wpm_meta = get_multiple_meta_values( $meta_keys_i_want_to_use, get_the_ID() );

// Get posts.
$the_posts = get_posts_with_same_meta( $wpm_meta );

// Do what you want with them.
foreach ( $the_posts as $p ) {
    // The post is available as $p.
    ?>
    <div>
    <a href="<?php the_permalink( $p ); ?>">
    <h3><?php echo esc_html( $p->post_title ); ?></h3>
    <img src="<?php echo esc_attr( get_the_post_thumbnail_url( $p, \'thumbnail\' ) ); ?>"></a>
    </div>
    <?php
}

相关推荐