WordPressで「Advanced Custom Fieldsで増設した入力欄を更新すると、記事一覧にも更新した旨を表示する」という実装をする機会がありました。
このような実装は経験したことがなく、ネットで調べてみました。
しかし、私が調べた範囲では、そのような情報は見つかりませんでした。
そのため、自分なりに考えたものを実装しましたので、この記事に実装手順をまとめます。
同じ問題でお悩みのWEB制作、WordPressテーマ開発の方々の参考になれば良いなと思います。
目次
作りたい記事一覧
上記画像のように、記事一覧には下記のものを時系列で表示させていきます。
- 複数投稿タイプの、記事リンク・投稿日時
- Advanced Custom Fieldsの入力欄を更新した、記事のリンク・変更日時(※上記投稿タイプに所属)
前提条件
下記のような条件で行います。
- スラッグ名「comapny」、ラベル名「会社」というを投稿タイプを用意
- Advanced Custom Fieldsで入力欄を増設する
- 記事一覧は固定ページを使用
- SQL文で記事情報を抽出
- ページャー機能を追加できるようにする
実装方法
Advanced Custom Fieldsの設定
今回は上記の画像のような例で設定を行いました。
- フィールドタイプ:テキスト
- 代表者名(president)
- 住所(location)
- 電話番号(phone)
- デイトピッカー:Date Time Picker(表示フォーマットYMD)
- 代表者名変更日(president_date)
- 住所変更日(location_date)
- 電話番号(phone_date)
合計6つの入力欄を用意します。
( ※括弧の中はフィールド名とします。 )
日付入力欄を用意した理由は、間違って入力してしまい意図せず記事を一覧で表示させることを防ぐためです。
最初はwp_postsテーブルのposts_modifiedカラムを活用し、メタ値の更新を一覧で表示できないかと考えました。しかし、このposts_modifiedカラムは投稿を更新する度に上書きされてしまうため、適切ではありませんでした。 また、WordPressでは個々のメタ情報のレコードが追加された日付のカラムまでは存在しません。
そのため、日付を入力する手間が発生してしまうのですが、各項目一つずつ日付入力欄を用意し、SQLで抽出できるようにしようという考えに至りました。
もっと良い方法がないものかと悩んだ部分です。。。
functions.php に関数を追記
/**
* 通常+メタキー('company_date', 'president_date', 'phone_date')の投稿情報を返す
* @param
* $post_num:投稿表示数
* $cur_page_num:表示するページ数
* @return 該当する記事があればTRUE
*/
function get_my_posts_info(int $post_num = 10, int $cur_page_num = 1): array
{
global $wpdb;
$off_set = $post_num * ($cur_page_num - 1);
$post_types = ['company', 'post'];//更新一覧に表示したい投稿タイプ
$post_types = "'".implode("','", $post_types)."'";
$meta_keys = ['company_date','president_date','phone_date'];//更新一覧に表示したいメタキー
$meta_keys = "'".implode("','", $meta_keys)."'";
$query = "
(
SELECT $wpdb->posts.`ID`, `meta_key` AS `key`, DATE_FORMAT(`meta_value`,'%Y-%m-%d %T') AS `date` FROM $wpdb->postmeta
LEFT JOIN $wpdb->posts
ON $wpdb->posts.`ID` = $wpdb->postmeta.`post_id`
WHERE `meta_key` IN ( $meta_keys )
AND `meta_value` != ''
AND `meta_value` < NOW()
)
UNION ALL
(
SELECT `ID`, 'post_date' AS `key`, `post_date` AS `date` FROM $wpdb->posts
WHERE `post_type` IN ($post_types)
AND `post_date` < NOW()
AND `post_status` = 'publish'
)
ORDER BY `date` DESC
LIMIT $post_num
OFFSET $off_set
";
return $wpdb->get_results( $query );
}
通常の投稿・’company_date’, ‘president_date’, ‘phone_date’のメタキーを抽出するselect文をUNION ALLで結合させた情報を返す関数になります。
※MySQLのタイムゾーンは’Asia/Tokyo’にしておきましょう。
記事一覧を表示させたい固定ページテンプレートファイルに記事一覧を表示する記述を行う
固定ページテンプレートファイルに下記を追加すると、記事一覧が表示されます。
また、変数「$paged」に現在の任意のページ数を代入すると、記事一覧が表示されました。
$paged = get_query_var('paged') ? get_query_var('paged') : 1;//現在のページ数を入力する
$posts_per_page = get_option('posts_per_page');
$my_posts = get_my_posts_info($posts_per_page, $paged);
echo '<ul style="margin-left:50px;">';
foreach($my_posts as $my_post){
$post_id = $my_post->ID;// 投稿ID
$post_key = $my_post->key;//メタキーの種類
$post_title = get_the_title($post_id);// タイトル
$post_date = get_the_date('Y/m/d', $post_id);// 日付
$post_link = get_permalink($post_id);// リンク
switch ($post_key) {
case 'phone_date':
$string = 'の電話番号の変更を行いました。';
break;
case 'president_date':
$string = 'の代表者名の変更を行いました。';
break;
case 'location_date':
$string = 'の住所の変更を行いました。';
break;
default:
$string = 'の更新行いました。';
}
//表示
echo '<li><a href="'.$post_link.'">【'.$post_date.'】「'.$post_title.'」'.$string.'</a></li>';
}
echo '</ul>';
さいごに
WordPressは最新記事、検索結果、カテゴリ毎など様々な一覧表示がありますが、
SQLをこのようにゴリゴリ書いて、記事一覧の表示させる実装を行ったのは初めてで勉強になりました。
特にSQLで抽出する方法がわかれば、様々な一覧表示の可能性がありそうです。