WordPressタクソノミー内で投稿を並べ替える方法

公開: 2020-12-18

これまでのところ、NelioはWordPress.orgリポジトリにいくつかのプラグインを公開しています。 それらのいくつかは完全に無料で、たとえば、グーテンベルクで作成されたページや投稿にGoogleマップを挿入できるNelio Mapsや、挿入できるNelio Compare Imagesなど、一般的な問題に対するエレガントなソリューションを提供します。名前が示すように、2つの画像を並べて比較するためのブロック。 また、請求書の支払いに役立つプレミアムプラグインをいくつか公開しました。NelioContentとNelio A /BTestingです。

私たちのウェブサイトを見ると、2つのプレミアムプラグインが目立つ場所を占めていることがわかります。どちらにもいくつかのランディングページと価格設定ページがあり、ユーザーが質問に対する答えを見つけることができる関連ナレッジベースがあります。 今日は、Nelio A / BテストとNelioコンテンツのドキュメントページをどのように作成したか、そして質問を好きなように並べ替えるために何をしなければならなかったかについて話します。

WordPressでカスタム投稿タイプを作成する方法

まず、カスタム投稿タイプを作成して、ナレッジベースに含まれるすべての質問を追跡しましょう。 次のスクリーンショットで結果を確認できます。ここには、Nelio A /BTestingのナレッジベース用のこの新しい投稿タイプのインスタンスがあります。

Nelio A/Bテストのナレッジベース
Nelio A /BTestingのナレッジベースの質問の例。

カスタム投稿タイプを作成するには、WordPressのregister_post_type関数を次のように使用するだけです。

 function nelio_add_help_type() { $labels = array( 'name' => __( 'Questions', 'nelio-help' ), 'singular_name' => __( 'Question', 'nelio-help' ), 'menu_name' => __( 'Testing's Help', 'nelio-help' ), 'all_items' => __( 'All Questions', 'nelio_help' ), 'add_new_item' => __( 'Add New Question', 'nelio_help' ), 'edit_item' => __( 'Edit Question', 'nelio_help' ), 'view_item' => __( 'View Question', 'nelio_help' ), ); register_post_type( 'nab_help', array( 'capability_type' => 'post', 'labels' => $labels, 'map_meta_cap' => true, 'menu_icon' => 'dashicons-welcome-learn-more', 'public' => true, 'show_in_rest' => true, 'supports' => [ 'title', 'editor', 'author' ], ) ); } add_action( 'init', 'nelio_add_help_type' );

そして出来上がり! カスタム投稿タイプのインターフェイスを作成およびカスタマイズするのに役立つAdvancedCustomFieldsのようなプラグインがあることはすでにご存知かもしれませんが、このような単純な例を実装することを必ずしもお勧めしません。

ちなみに、このスニペットをどこに配置するか迷っている場合は、カスタムプラグインを使用してWordPressをカスタマイズする方法に関するチュートリアルをお見逃しなく。

コンテンツを整理するための新しい分類法を作成する方法

次のスクリーンショットに示すように、ナレッジベースは「トピック」と「キーワード」で構成されています。

WordPressダッシュボードのスクリーンショット。トピックとキーワードの2つの分類法で新しい投稿タイプを示しています。
WordPressダッシュボードのスクリーンショット。トピックキーワードの2つの分類法を使用した新しい投稿タイプのテストのヘルプを示しています。

トピックとキーワードは、WordPressの投稿にデフォルトであるカテゴリとタグに相当します。 後者はまったく同じなので、前者に焦点を当てましょう。

すでに想像できるように、トピックは、カスタムコンテンツタイプ用に作成したカスタム分類法です。 WordPressの投稿タイプに新しい分類法を追加するには、次のようにregister_taxonomy関数を使用する必要があります。

 function nelio_add_help_taxonomy() { $labels = array( 'name' => __( 'Topics', 'nelio-help' ), 'singular_name' => __( 'Topic', 'nelio-help' ), 'menu_name' => __( 'Topics', 'nelio-help' ), 'all_items' => __( 'All Topics', 'nelio_help' ), /* ... */ ); register_taxonomy( 'nab_topic', [ 'nab_help' ], array( 'hierarchical' => true, 'label' => __( 'Topic', 'nelio-help' ), 'query_var' => true, 'show_admin_column' => false, 'show_ui' => true, 'show_in_rest' => true, ) ); } add_action( 'init', 'nelio_add_help_taxonomy' );

この関数は非常に簡単に使用できます。 まず、分類法に名前を付けます(この例ではnab_topic )。 次に、関連する投稿タイプを指定します( nab_helpは1つだけです)。 最後に、分類法をカスタマイズするためにさらにいくつかの引数を追加します。 その結果、ナレッジベースで質問を分類するために必要な具体的なトピックを作成するための新しい分類法が作成されます。

WordPressダッシュボードのカスタム分類のスクリーンショット。
カスタム分類のスクリーンショット(トピック)。

分類法で投稿を並べ替える方法

カスタム分類法があり、作成する各トピックに質問を追加できるようになったので、特定のトピック内でそれらの質問をどのように並べ替えますか? さて、私たちは少しコーディングする必要があるのではないかと思います…

データベースを見てみる

WordPressとその投稿との関係は、次の4つの異なるデータベーステーブルに保存されます。

  • wp_termsには、特定の分類法内で作成するすべての用語が含まれます。 たとえば、トピックの分類法には、一般的な質問互換性支払いと請求などの用語があります。
  • wp_termmetaは、各用語に関連する追加データを保存するのに役立ちます。 wp_postmetaとよく似ています。
  • wp_term_taxonomyは、 wp_termsの各用語をその定義する分類法に関連付けます。 したがって、たとえば、このテーブルは、一般的な質問の用語が実際にはnab_topic分類法のインスタンスであるという事実を追跡します。
  • wp_term_relationshipsは、各用語( term_taxonomy_id )を「含む」投稿( object_id )に関連付けます。 たとえば、この表は、Nelio A / Bテストとは何かに関する質問が一般的な質問であることを示しています(そのため、トピックを参照すると質問が表示されます)。

WordPress 2.5は、 wp_term_relationshipsテーブルに新しい数値フィールドterm_orderを追加しました。これにより、特定の要素が分類法内で占める位置を指定できます。 これは、トピック内で質問を並べ替えるために探していた候補のように聞こえますが、落とし穴があります。私が知る限り、WordPressには、(1) term_orderフィールドの値を定義し、( 2)特定の分類内の投稿を実際に並べ替えるために使用します。 これを直そう!

term_orderフィールドを使用して、分類法に含まれる投稿を並べ替える方法

次のスクリーンショットに示すように、必要なterm_order値をなんとかして設定できたとしましょう。

データベースに表示される注文と実際にWebに表示される注文のスクリーンショット。
私たちがデータベースに表示する順序(そしてそれが私たちが期待する順序)は、私たちのWebサイトを閲覧するときに実際に取得する順序とは異なります。

デフォルトでは、WordPressはこのフィールドを無視し、投稿はフロントエンドで並べ替えられません。 そのため、上のスクリーンショットに示されている3つの質問は適切に並べ替えられていません。

幸い、WordPressにフィールドを使用して投稿を並べ替えるように簡単に指示できます。 posts_orderbyフィルターを使用して、特定の用語に属する投稿を取得するクエリを微調整して、並べ替え要求が含まれるようにします。

 add_filter( 'posts_orderby', 'nelio_sort_questions_in_topic', 99, 2 ); function nelio_sort_questions_in_topic( $orderby, $query ) { if ( ! nelio_is_topic_tax_query( $query ) ) return; global $wpdb; return "{$wpdb->term_relationships}.term_order ASC"; } function nelio_is_topic_tax_query( $query ) { if ( empty( $query->tax_query ) ) return; if ( empty( $query->tax_query->queries ) ) return; return in_array( $query->tax_query->queries[0]['taxonomy'], [ 'nab_topic' ], true ); }

前のスニペットは、特定の分類法(この場合はnab_topic )をクエリしていることを確認するだけで、クエリにORDER BY句を追加して、最終結果が$wpdb->term_relationshipsテーブルにあるterm_order属性:

分類法の結果(順序付け)のスクリーンショット
分類法内の(ソートされた)投稿のスクリーンショット。

分類法の内容を注文するためのユーザーインターフェイスの実装

最後に、やるべきことは1つだけです。 前のセクションでは、 term_orderフィールドに何らかの方法で正しい値を設定できたと想定しました。 しかし、どのように? この値をユーザーフレンドリーな方法で設定するための画面またはオプションがどこかにありますか? 私の知る限り、ありません。 しかし、私たちはそれを作成することができます。

私の意見では、この問題の最善の解決策は、並べ替える分類を選択し、すべての質問をドラッグアンドドロップして順序を確立できるUIを用意することです。 このようなもの、行きます:

特定の分類法で投稿を簡単に並べ替えるためのユーザーインターフェイス。
特定の分類法で投稿を簡単に並べ替えるためのユーザーインターフェイス。

目的の効果を実現するには、次の手順を実行する必要があります。

  • WordPressダッシュボードに新しいページを登録する
  • 選択した分類法内の分類法セレクターと投稿をレンダリングする関数を実装します
  • UIがレスポンシブになるように、小さなJavaScriptスニペットを追加します
  • 投稿の並べ替えが完了したら、新しいコールバックを作成して結果の順序を保存します

新しいWordPress開発スタックを使用して、このインターフェースを必要に応じて複雑にすることができます。 しかし、今日は、仕事を成し遂げるための迅速で汚い解決策の概要を説明します。

私が言ったように、最初に私たちがインターフェースを置くページを登録することです。 admin_menuアクション中にadd_submenu_page関数を使用して、これを簡単に行うことができます。

 add_action( 'admin_menu', function() { add_submenu_page( 'edit.php?post_type=nab_help', 'Sort', 'Sort', 'edit_others_posts', 'nab-help-question-sorter', __NAMESPACE__ . '\render_question_sorter' ) } );

render_question_sorterメソッドも非常に簡単です。

 function render_question_sorter() { echo '<div class="wrap"><h1>Sort Questions</h1>'; $terms = get_terms( 'nab_topic' ); render_select( $terms ); foreach ( $terms as $term ) { render_questions_in_term( $term ); } render_script(); echo '</div>'; }

ご覧のとおり、 nab_topic分類法のすべての用語を取得し、3つの補助関数を使用して、(1)セレクターをレンダリングし、(2)各カテゴリの質問をレンダリングし、(3)小さなスクリプトを追加してすべてを作成します。動的。

セレクターのレンダリングは、各用語を繰り返してoptionをレンダリングするのと同じくらい簡単です。

 function render_select( $terms ) { echo '<select>'; foreach ( $terms as $term ) { printf( '<option value="%s">%s</option>', esc_attr( $term->slug ), esc_html( $term->name ) ); } echo '</select>'; }

分類法の各用語にある質問をレンダリングするために、データベースへのクエリを起動し、それらすべてを反復処理します。

 function render_questions_in_term( $term ) { printf( '<div class="term-block" data-term->', esc_attr( $term->slug ), esc_attr( $term->term_id ) ); echo '<div class="sortable">' $query = new WP_Query( array( 'post_type' => 'nab_help', 'post_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'nab_topic', 'field' => 'term_id', 'terms' => $term->term_id, 'orderby' => 'term_order', ), ), ) ); while ( $query->have_posts() ) { $query->the_post(); global $post; printf( '<div class="question" data-question->%s</div>', esc_attr( $post->ID ), esc_html( $post->post_title ) ); } echo '</div>'; printf( '<input type="button" data-term- value="%s" />', esc_attr( $term->term_id ), esc_attr( 'Save' ) ); echo '</div>'; }

この関数は、現在の$termslugをIDとして使用するdivをレンダリングし、質問をさらに別のdiv要素にグループ化し、最後に[保存]ボタンを含むことに注意してください。 これらの詳細はすべて、アプリを配線するスクリプトを最終的にレンダリングするときに役立ちます。

すべての準備ができたら、JavaScriptの魔法を追加するだけです。 特に、この迅速で汚いUIには、ドラッグアンドドロップ機能を実装するための2つのスクリプト( jqueryjquery-ui )と、次のJSスニペットが必要です。

 ( function() { // MAKE QUESTIONS SORTABLE $( '.sortable' ).sortable(); // TERM SELECTOR const select = document.getElementById( 'topic' ); const termBlocks = [ ...document.querySelectorAll( '.term-block' ) ]; select.addEventListener( 'change', showSelectedTermBlock ); // Helper function function showSelectedTermBlock() { /* ... */ } // SAVE BUTTONS [ ...document.querySelectorAll( '.term-block input[type="button"]' ) ].forEach( addButtonLogic ); // Helper function function addButtonLogic( button ) { const termId = button.getAttribute( 'data-term-id' ); button.addEventListener( 'click', () => { button.disabled = true; const selector = `div[data-term-] .question`; const ids = [ ...document.querySelectorAll( selector ) ] .map( ( question ) => question.getAttribute( 'data-question-id' ); $.ajax( { url: ajaxurl, method: 'POST', data: { action: 'nelio_save_tax_sorting', objectIds: ids, termId, }, } ).always( () => button.disable = false ); } } } )()

一見すると、前のスニペットは複雑に見えるかもしれません。 しかし、私は約束します:そうではありません。 まず、jQuery UIのsortable関数を使用して、質問を「並べ替え可能」にします。 次に、ヘルパー関数を使用して適切な質問のセットを表示/非表示にするリスナーをselectコンポーネントに追加します。 最後に、 clickリスナーを[保存]ボタンに追加して、ユーザーがクリックしたときに、質問が並べ替えられた順序がデータベースに保存されるようにします。

ご覧のとおり、この新しい注文の保存はAJAXリクエストを介して行われます。つまり、対応するPHPコールバックを実装する必要があります。

 add_action( 'wp_ajax_nelio_save_tax_sorting', __NAMESPACE__ . '\save_tax_sorting' ); function save_tax_sorting() { $term_id = isset( $_POST['termId'] ) ? absint( $_POST['termId'] : 0 ); if ( ! $term_id ) die(); $object_ids = isset( $_POST['objectIds'] ) ? $_POST['objectIds'] : []; if ( ! is_array( $object_ids ) || empty( $object_ids ) ) die(); $object_ids = array_values( array_map( 'absint', $object_ids ) ); global $wpdb; foreach ( $object_ids as $order => $object_id ) { $wpdb->update( $wpdb->term_relationships, array( 'term_order' => $order + 1 ), array( 'object_id' => $object_id, 'term_taxonomy_id' => $term_id, ), ); } die(); }

以上です! とても簡単ですね

要約すれば

WordPressは、特定の分類法内で投稿を並べ替えるデフォルトのメカニズムを提供していません。 しかし、それは大丈夫です! 自分で実装できます。WordPress分類法で投稿を並べ替えるには、 term_relationshipsデータベーステーブルのterm_orderフィールドを設定し、 posts_orderbyフィルターを使用してWordPressを拡張してそのフィールドを使用するだけです。

最後に、特定の分類法に含まれる投稿をドラッグアンドドロップすることで、 term_orderフィールドに簡単に入力できるシンプルなUIの概要を説明しました。

このチュートリアルが気に入っていただけたら幸いです。気に入った場合は、お友達や同僚と共有してください。 また、いつものように、ご不明な点がございましたら、下のコメントセクションにご記入ください。喜んで対応させていただきます。

UnsplashのSteveJohnsonによる注目の画像。