質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

1758閲覧

wordpress管理ページ、カスタム投稿一覧でのソート機能

suzukimanabu

総合スコア5

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/12/19 14:20

お世話になります。

wordpress管理ページ、カスタム投稿一覧で、カスタムフィールドの値(イベントの開始日)を取得し自動でソートさせることはできたのですが、読み込み後、クリックして(手動で)別の値(イベントの終了日や投稿日時)でのソートをさせることができず困っております。
自動ソート部分のコードを消すと、手動でソートできます。

カスタムフィールド名はイベントの開始日が(start_day) 終了日が(end_day)です。
カスタム投稿スラッグは(event_day)
開始日を(start)、終了日を(end)で一覧画面表示オプションとして表示させています。

コードはfunctions.phpに

function add_posts_columns($columns) { // $columns['example'] = '展示会開始日'; // return $columns; foreach ($columns as $name => $val) { if ('date' == $name) { //日付の手前に追加する $new_columns['start'] = '展示会開始日'; $new_columns['end'] = '終了日'; } $new_columns[ $name ] = $val; } return $new_columns; } function custom_posts_column($column_name, $post_id) { if ($column_name == 'start') { $date_start = date_create(get_field('start_day')); $start_day = date_format($date_start, 'Y年m月d日'); // $cf_example = get_post_meta( $post_id, 'start_day', true ); echo ($start_day) ? $start_day : '-'; } if ($column_name == 'end') { $date_end = date_create(get_field('end_day')); $end_day = date_format($date_end, 'Y年m月d日'); // $cf_example = get_post_meta( $post_id, 'start_day', true ); echo ($end_day) ? $end_day : '-'; } } add_filter('manage_event_news_posts_columns', 'add_posts_columns'); add_action('manage_event_news_posts_custom_column', 'custom_posts_column', 10, 2); //カスタムフィールドで手動ソートを可能にする function posts_sortable_columns($sortable_column) { $sortable_column['start'] = 'start'; $sortable_column['end'] = 'end'; return $sortable_column; } add_filter('manage_edit-event_news_sortable_columns', 'posts_sortable_columns'); //カスタムフィールドでソートする際のパラメータ function posts_columns_sort_param($vars) { if (isset($vars['orderby']) && 'start' === $vars['orderby']) { $vars = array_merge( $vars, array( 'meta_key' => 'start_day', 'orderby' => 'meta_value', //対象が文字列の場合は「meta_value」を指定 ) ); } if (isset($vars['orderby']) && 'end' === $vars['orderby']) { $vars = array_merge( $vars, array( 'meta_key' => 'end_day', 'orderby' => 'meta_value', //対象が文字列の場合は「meta_value」を指定 ) ); } return $vars; } add_filter('request', 'posts_columns_sort_param'); // event情報一覧自動ソート 開始日順 function set_post_types_event_admin_order($wp_query) { if (is_admin()) { $post_type = $wp_query->query['post_type']; if ($post_type == 'event_news') { $wp_query->set('orderby', 'start_day'); $wp_query->set('order', 'DESC'); } } } add_filter('pre_get_posts', 'set_post_types_event_admin_order');

見ずらいコードで恐縮ですが、ご教授ください。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

コードから予想するに、例えば手動でイベントの終了日をクリックしても、イベントの開始日でソートされた状態で表示されてしまう感じですかね・・?

今回の問題で重要なのは、posts_columns_sort_param関数と、set_post_types_event_admin_order関数の関係ですね。

それぞれ、add_fileterでフィルターに適用させていますが、前者がrequest、後者がpre_get_postsです。

数あるフィルターの中で、それぞれ実行される順番が違うのですが、requestとpre_get_postsの場合、requestが先で、pre_get_postsが後です。

requestは、そのページのデータを表示する際、どのデータを取得するかを指定するクエリの値に対して、値を入れ込んだり操作するためのフィルターです。

このrequestの処理が実行されると、「今回のリクエストでは、こういったデータが欲しい」というクエリ条件が完成します。

この後、クエリ条件に対して実際にDBにSQLが実行されて、指定のデータが取得されてきます。

ところが、今回のコードだと、DBにSQLが実行される前に、pre_get_postsフィルターが発動します。
このpre_get_postsフィルターに指定されているset_post_types_event_admin_order関数の処理内容が実行されます。

中の処理の概要は、「event_newsの管理画面だった場合には、イベント開始日でソートするように。」
なので、どれだけrequestフィルターでクエリ条件変えても、直前でイベント開始日でソートするようになってしまうので、今回の現象になっているのだと思います。

対処としては、$wp_query->set()をしている部分に処理を追加する必要があるかと思います。
多分、引数の$wp_queryの中に、posts_columns_sort_param関数内での$vars['orderby']のように、どのソートをしたいかという情報が入っていると思います。

その値によって、$wp_query->set()の実行を分けるようなイメージです。

こちらの実装をしたら、多分、posts_columns_sort_paramは不要かと思います。
以上です。
参考になれば幸いです。

##################### 返信に対して #####################

こちら遅くなってすみません。
自分だったらこうするかな?というのを書いてみました。

ちょっと上記で言ってることと違う内容になってしまいますが、多分これでイケるのではないかと。
動作確認とか、パラメータの中の値とかしていないので、あくまで参考になれば・・・。

php

1function add_posts_columns($columns) 2{ 3 // $columns['example'] = '展示会開始日'; 4 // return $columns; 5 foreach ($columns as $name => $val) { 6 if ('date' == $name) { 7 //日付の手前に追加する 8 $new_columns['start'] = '展示会開始日'; 9 $new_columns['end'] = '終了日'; 10 } 11 $new_columns[ $name ] = $val; 12 } 13 return $new_columns; 14} 15function custom_posts_column($column_name, $post_id) 16{ 17 if ($column_name == 'start') { 18 $date_start = date_create(get_field('start_day')); 19 $start_day = date_format($date_start, 'Y年m月d日'); 20 // $cf_example = get_post_meta( $post_id, 'start_day', true ); 21 echo ($start_day) ? $start_day : '-'; 22 } 23 if ($column_name == 'end') { 24 $date_end = date_create(get_field('end_day')); 25 $end_day = date_format($date_end, 'Y年m月d日'); 26 // $cf_example = get_post_meta( $post_id, 'start_day', true ); 27 echo ($end_day) ? $end_day : '-'; 28 } 29} 30add_filter('manage_event_news_posts_columns', 'add_posts_columns'); 31add_action('manage_event_news_posts_custom_column', 'custom_posts_column', 10, 2); 32 33//カスタムフィールドで手動ソートを可能にする 34function posts_sortable_columns($sortable_column) 35{ 36 $sortable_column['start'] = 'start'; 37 $sortable_column['end'] = 'end'; 38 return $sortable_column; 39} 40add_filter('manage_edit-event_news_sortable_columns', 'posts_sortable_columns'); 41 42//カスタムフィールドでソートする際のパラメータ 43function posts_columns_sort_param($vars) 44{ 45 // if文バラバラに2つだったのを、if-elseif-elseにまとめます。 46 // 最初アクセスした時、$vars['orderby']が存在しない、もしくはstart,end以外の値だと思います。 47 // なので、その時は開始日の降順で設定するようにします。 48 if (isset($vars['orderby']) && 'start' === $vars['orderby']) { 49 $vars = array_merge( 50 $vars, 51 array( 52 'meta_key' => 'start_day', 53 'orderby' => 'meta_value', //対象が文字列の場合は「meta_value」を指定 54 ) 55 ); 56 }elseif (isset($vars['orderby']) && 'end' === $vars['orderby']) { 57 $vars = array_merge( 58 $vars, 59 array( 60 'meta_key' => 'end_day', 61 'orderby' => 'meta_value', //対象が文字列の場合は「meta_value」を指定 62 ) 63 ); 64 } else { 65 // 最初にアクセスした時に動く想定 66 $vars = array_merge( 67 $vars, 68 array( 69 'meta_key' => 'start_day', 70 'orderby' => 'DESC', //開始日の降順で固定。 71 ) 72 } 73 74 75 return $vars; 76} 77add_filter('request', 'posts_columns_sort_param'); 78 79// event情報一覧自動ソート 開始日順 80function set_post_types_event_admin_order($wp_query) 81{ 82 if (is_admin()) { 83 84/* 85posts_columns_sort_param関数を上記のようにすると、この部分の処理はいらなくなるかと思います。 86コメントアウトしてありますので、この状態で想定通り動くのであれば、このset_post_types_event_admin_order関数ごと削除して大丈夫です。 87 $post_type = $wp_query->query['post_type']; 88 if ($post_type == 'event_news') { 89 $wp_query->set('orderby', 'start_day'); 90 $wp_query->set('order', 'DESC'); 91 } 92 } 93*/ 94 95} 96 97 add_filter('pre_get_posts', 'set_post_types_event_admin_order');

以上です。

投稿2021/12/22 03:37

編集2022/01/03 02:58
Iya712

総合スコア158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suzukimanabu

2021/12/24 07:28

@Iya712様 丁寧に教えていただき誠にありがとうございます。 なぜ、機能が動かないのかは分かったのですが、色々いじってみても解決ができませんでした。 お時間ののある時で結構ですのでお時間のある時でかまいませんので、具体的に語のように書けばよろしいかご教授ください。 一応、力技を使って機能的には成り立たせることができました。 「set_post_types_event_admin_order」自動ソート側をオフにして、jQueryで管理画面メニューのURLを書き換えることで、自動ソート風には なり、解決したともいえるのですが、 functions.phpからスマートに行いたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問