web-dev-qa-db-ja.com

投稿の種類による検索結果の分離

元の質問: カスタム投稿検索結果の分離

私は自分のウェブサイトにこのコードを実装しようとしましたが、私はそれに問題があります。私が変更したのは、次のように3番目の投稿タイプ用に別のスイッチを追加したことです。

<?php if (have_posts()) : ?>
    <?php
    $last_type = "";
    $typecount = 0;
    while (have_posts()) :
        the_post();
        if ($last_type != $post->post_type) {
            $typecount = $typecount + 1;
            if ($typecount > 1) {
                echo '</div><!-- close container -->'; //close type container
            }
            // save the post type.
            $last_type = $post->post_type;
            //open type container
            switch ($post->post_type) {
                case 'post':
                    echo "<div class=\"postsearch container\"><h2>Blog Results</h2>";
                    break;
                case 'partner':
                    echo "<div class=\"partnersearch container\"><h2>Partner Search Results</h2>";
                    break;
                case 'fiches_pratiques':
                    echo "<div class=\"lessonsearch container\"><h2>lesson Search Results</h2>";
                    break;
            }
        }
        ?>

        <?php if ('post' == get_post_type()) : ?>
            <li class="post"><?php the_title(); ?></li>
        <?php endif; ?>

        <?php if ('partner' == get_post_type()) : ?>
            <li class="partner"><?php the_title(); ?></li>
        <?php endif; ?>

        <?php if ('lesson' == get_post_type()) : ?>
            <li class="lesson"><?php the_title(); ?></li>
        <?php endif; ?>


    <?php endwhile; ?>

<?php else : ?>
    <div class="open-a-div">
        <p>No results found.</p>    

    <?php endif; ?>       

このコードは次のようになります。

レッスン検索結果

レッスン1レッスン4レッスン3

ブログ結果

テストサブ

パートナー検索結果

第四パートナー

ブログ結果

Lorem ipsum Wave 2.0 Web&Tech Cloudオープンコンテナープロジェクト

お気づきのように、ブログの結果セクションは2倍になっています。問題となる可能性があるものについて何か提案はありますか?

インストール済み検索プラグイン:Relevanssi

注:Relevanssiなしで(ただしSearch Everythingプラグインを使用すると)適切な方法で表示されますが、Search Everythingプラグインでは複数語の検索はできません。場合。

Wordpressの最新バージョン。

前もって感謝します。

1
semibur

これがアイデアです。ループを実行する前にソートしてください。あなたの現在の問題はこれだけです。並べ替えの種類(注文の種類に応じて順番がアルファベット順ではないと思われる場合は正しい場合)はネイティブでは不可能であることがわかりますので、回避策が必要です(偶数)あなたがアルファベット順にソートされた投稿タイプを必要としているだけなら、ネイティブの方法はまだ適切な機能を欠いています)。これがusort()が登場するところです、私達は私達が望む順序でpost型の投稿をソートすることができます。これはthe_postsフィルタの内側で行われます

私はあなたに両方の例を見せることができます。 注:コードサンプルには最低でもPHP 5.4以降が必要です。 5.4より前のすべてのバージョンはEOLされており、サポートされていません。そのため、それらのバージョンをまだ使用している場合、大きなセキュリティ上のリスクがあります。

カスタムPOSTタイプ順で並べ替え

add_filter( 'the_posts', function( $posts, $q ) 
{
    if( $q->is_main_query() && $q->is_search() ) 
    {
        usort( $posts, function( $a, $b ){
            /**
             * Sort by post type. If the post type between two posts are the same
             * sort by post date. Make sure you change your post types according to 
             * your specific post types. This is my post types on my test site
             */
            $post_types = [
                'event_type' => 1,
                'post'       => 2,
                'cameras'    => 3
            ];              
            if ( $post_types[$a->post_type] != $post_types[$b->post_type] ) {
                return $post_types[$a->post_type] - $post_types[$b->post_type];
            } else {
                return $a->post_date < $b->post_date; // Change to > if you need oldest posts first
            }
        });
    }
    return $posts;
}, 10, 2 );

SORT BY POSTタイプのアルファベット順

add_filter( 'the_posts', function( $posts, $q ) 
{
    if( $q->is_main_query() && $q->is_search() ) 
    {
        usort( $posts, function( $a, $b ){
            /**
             * Sort by post type. If the post type between two posts are the same
             * sort by post date. Be sure to change this accordingly
             */

            if ( $a->post_type != $b->post_type ) {
                return strcasecmp( 
                    $a->post_type, // Change these two values around to sort descending
                    $b->post_type 
                );
            } else {
                return $a->post_date < $b->post_date; // Change to > if you need oldest posts first
            }
        });
    }
    return $posts;
}, 10, 2 );

これで、検索ページの投稿の種類別に投稿を並べ替えることができます。つまり、メインのクエリの代わりにカスタムクエリを使用していない場合です。上記のコードに関しては、それをそのままにしておきます。それを調整する必要はありません。

5
Pieter Goosen

Relevanssiプラグインが正しいと思う順序で投稿結果が得られています。つまり、プラグインの要点であるプラグインのロジック(正確にはわかりません)に従って、最も適切な順序で結果が得られます。

一般的に言って、投稿タイプによる順序付けはそれほど難しくありません。

function orderby_type($orderby) {
  remove_filter('posts_orderby','orderby_type');
  global $wpdb;
  return $wpdb->posts.'.post_type';
}
add_filter('posts_orderby','orderby_type');
$args = array(
  'post_type' => array('post','page','book'),
  'orderby' => 'post_type'
);
$w = new WP_Query($args);

しかし、私はプラグインが提供している "適切な"順序付けを破ることを期待したいと思います。実際、あなたがすることは「関連性」の計算をある程度破る可能性があります。次のようなものがあなたができる最善についてのものであるべきです。

function resort_posts($posts) {
  $sorted = $ret = array();
  foreach ($posts as $p) {
    $sorted[$p->post_type][] = $p;
  }
  foreach ($sorted as $s) {
    $ret = array_merge($ret,$s);
  }
  // verify
//   $pid = wp_list_pluck($posts,'ID');
//   $sid = wp_list_pluck($ret,'ID');
//   var_dump(array_diff($pid,$sid));
  return $ret;
}
add_filter('the_posts','resort_posts');

サイト上のすべてのクエリを台無しにせずにRelevanssiでそれを機能させる方法を理解する必要があります(これは記述どおりに行われます)。私はそのプラグインを使ったことがないので私は言うことができません(ところで、プラグイン特有の質問もトピックから外れています)

2
s_ha_dum

あなたは インターネットの無限の広がり を検索しましたか?

SERPの最初のエントリはrelvanssiナレッジベースの記事で、タイトルは" です。投稿タイプで投稿を区切る " 、私に合ったね。以下は提案されたアプローチのためのコードです:

add_filter('relevanssi_hits_filter', 'separate_result_types');
function separate_result_types($hits) {
    $types = array();

    // Split the post types in array $types
    if (!empty($hits)) {
        foreach ($hits[0] as $hit) {
            if (!is_array($types[$hit->post_type])) $types[$hit->post_type] = array();                        
            array_Push($types[$hit->post_type], $hit);
        }
    }

    // Merge back to $hits in the desired order
    $hits[0] = array_merge(
        $types['mycustomtypethatgoesfirst'], 
        $types['thesecondmostimportanttype'], 
        $types['post'], $types['pages']
    );
    return $hits;
}


注:

  • 私は何もしませんでしたが、コードをコピーしました。
  • 私はLMGTFYと検索をリンクすることができなかった、どうやらそれは(少なくともこれ以上)ニースであると考えられていないようです。わかりました、私はそのようなものを - おそらく完全に - それを手に入れましょう。
1
Nicolai