web-dev-qa-db-ja.com

特定の投稿をワードプレスのループの前面に移動する方法

それで、私はWordPressループが進行中です。以下のコードは、woocommerce商品アーカイブページのテンプレートページです。これが私が達成する方法を見つけようとしているもののためのユースケースです:

  • ユーザーは製品アーカイブページで表示されます(リンクに囲まれた製品サムネイルが一覧表示されます)。
  • ユーザーがサムネイル(リンク)をクリックすると、前のページに表示されていたのと同じ商品のスライダーが表示される点を除けば、現在のページと基本的に同じページに移動します(番号はわかります)クリックされた記事のうち、クリックされたページ1、ページ2、またはページ3に表示されたページ上の投稿の数。
  • このページには、すべての商品の大きなサムネイルが表示されたスライダーが表示されます。選択した商品は、スライダーの先頭に表示されます。それに応じて)。

TL; DR:要約すると、まったく同じページ番号でまったく同じ投稿がある別のページに移動するにはどうすればよいですか。ただし、選択した投稿はページのループの先頭に表示されますが、選択した投稿はそれより前に表示され、それ以降は表示されます。それ)?

PS:プラグインソリューションもクライアントサイドソリューションも使用しない方がいいでしょう(それをすべてPHPのサーバー上で行いたいです)。

次に例を示します。

私はページにいます5

投稿は以下の通りです:41、42、43、44、45、46、47、48、49、50。

44をクリックしたとしましょう。

私が持って行ったページは同じループを持っていますが、最初は44で、他はそれに応じて並べ替えました。

ループは、44、45、46、47、48、49、50、41、42、43のようになります。

次のページをクリックしたら。私はページにいます5そして6をクリックしたので、ループ51、52、53 ...再び正常になります.

<?php get_template_part('templates/page', 'header');

    /**
    * woocommerce_before_main_content hook
    *
    * @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content)
    * @hooked woocommerce_breadcrumb - 20
    */
    do_action('woocommerce_before_main_content');

    do_action( 'woocommerce_archive_description' );

    if ( have_posts() ) {

        /**
         * woocommerce_before_shop_loop hook
         *
         * @hooked woocommerce_result_count - 20
         * @hooked woocommerce_catalog_ordering - 30
         */
        do_action( 'woocommerce_before_shop_loop' );

        woocommerce_product_loop_start();

        woocommerce_product_subcategories();

        while ( have_posts() ) {

            the_post();

        ?>

        <li>

            <?php get_template_part( 'woocommerce/content', 'product' );

        </li>

        <?php
        }
        woocommerce_product_loop_end();
        /**
         * woocommerce_after_shop_loop hook
         *
         * @hooked woocommerce_pagination - 10
         */
        do_action( 'woocommerce_after_shop_loop' );

    } elseif ( ! woocommerce_product_subcategories( array( 'before' => woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) {

    wc_get_template( 'loop/no-products-found.php' );
    }
    /**
    * woocommerce_after_main_content hook
    *
    * @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content)
    */
    do_action('woocommerce_after_main_content');

    ?>
2
yaharga

'the_posts' フィルタフックを使用すると、ループに表示される投稿を編集できます。

それはすべてのクエリ(メインとセカンダリ)のために起動されますので、あなたはあなたが行動しているクエリが正しいものであることを確認する必要があります。

それはあなたの場合あなたができることを言った:

  1. 選択した投稿を個別化するためのクエリ変数を送信する
  2. 選択した投稿をpost配列の先頭に移動するには'the_posts'フィルタを使用

1.選択した投稿を個別化するためのクエリ変数を送信します

投稿のサムネイルは、次のようなものを使用して印刷する必要があります。

<a href="<?php esc_url( add_query_arg( array('psel' => get_the_ID() ) ) ) ?>">
  <?php the_thumbnail() ?>
</a>

add_query_arg() 現在のURLにクエリ変数を追加すると、その投稿のサムネイルをクリックしてURL example.com/some/path/page/5があるページに移動した場合ID 44であなたはURL example.com/some/path/page/5?psel=44に送られます。

表示される投稿が同じになると同じになりますが、pselというurl変数のおかげで postsを並べ替えて選択した投稿を投稿の先頭に配置することができます。

2. 'the_posts'フィルタを使用して、選択した投稿を投稿配列の先頭に移動します

Url変数で選択した投稿IDを取得したら、関連する投稿オブジェクトを投稿配列の上に配置するのは、ほんの2、3個のPHP関数の問題です。

function get_selected_post_index() {
  $selID = filter_input(INPUT_GET, 'psel', FILTER_SANITIZE_NUMBER_INT);
  if ($selID) {
    global $wp_query;
    return array_search($selID, wp_list_pluck($wp_query->posts, 'ID'), true);
  }
  return false;
}

add_filter('the_posts', function($posts, $wp_query) {

  // nothing to do if not main query or there're no posts or no post is selected
  if ($wp_query->is_main_query() && ! empty($posts) && ($i = get_selected_post_index())) {
      $sel = $posts[$i]; // get selected post object
      unset($posts[$i]); // remove it from posts array
      array_unshift($posts, $sel); // put selected post to the beginning of the array
  }

  return $posts;

}, 99, 2);

前のコードはポストがあなたが望むように順序付けられていることを保証するでしょう。

投稿が選択されていない場合(または誤ったIdがfalse url変数を介して送信された場合)はpselが返されるため、get_selected_post_index()関数はテンプレート内でも選択された投稿があるかどうかを知るために使用できます。 。

5
gmazzap