Steamer Lane Studio技術備忘録ワードプレス

WordPress トップページのイベント案内などで終了したら自動で非表示にしつつアーカイブは残す

wordpress WordPress トップページのイベント案内などで終了したら自動で非表示にしつつアーカイブは残す
最終更新日: 2023年12月2日

表題の通り。トップページにイベントなどを表示させた際に記事を下書きにするか、など考えるがイベント案内記事が過去のものとなってもそれが検索上位表示されることもありまた、有意なコンテンツであればサイトのSEO・コンテンツマーケのためにも「過去のイベント」としてどこかに残っていた方が良い。突発的なイベントでなく恒例行事なら意外と過去記事を残しておくことで集客などに繋がる。
だが記事ってアップするときはイベントから逆算してとか他の媒体と合わせてアップとか気にするが、こうした「消す」ことは忘れがちだし煩わしい。
なのでGoogleにインデックスされたまま、イベント一覧ページに残しつつトップページなどの案内一覧からは設定した期限で消える、そんな仕組みを考えた。
もともとはMovableTypeでやっていたのだが、表示するカテゴリーと件数を設定しその中の記事に設定した表示期限で消えるまた、期限最大値を抽出し現在時刻との比較で入れ子(入れ子に見出しと「もっと読む」だけでもいいが、格好悪い)の表示・非表示をphpスクリプトで制御してた。
MTではmtmlとphpの組合せで最大値の比較抽出関数組むのが容易だったが、(時限設定しアクションさせるプラグインにも依ると思うが)Wordpressでは記事毎の表示期限抽出とmax関数への配列組みがやっかいだった(純粋なYmdHisで出ずここが配列として出されるから)ので、入れ子の表示・非表示を制御する最大値設定の部分を組むのが少し手間がいる。

ここではPublish press futureプラグインをWpにインストールした前提で。

<?php //ここから3件の記事のPublishpress futureでのアクション日-基本的には非表示にする日時を抽出件数により抽出コードを加減し後のmax関数に比較引数を追記、category_nameにラベルを記入、$newslist1以下は表示件数分コピペし連番としてoffsetの数値を変える。面倒くさいけど、publish press futureを改造せずに最新n件の記事のアクティヴィティ日時を吐き出させるとmax関数による比較に適した配列で吐き出さない。プラグインを改造するリスクは取れないので、表示=取得件数分のYmdHisを個別に取得する。$ld = date('YmdHis', strtotime('-24 hours'));//投稿件数が少ない場合、取得しようとした投稿日時が空になりエラーを吐くので、当該変数が空の際この24時間前の数値を呼び出し「空」によるエラーを防ぐ。吐いてもwrningだがphpのバージョンが古ければ空/nullを許すので不要かも。
$newslist1 = get_posts( array(
'category_name' => 'informations','posts_per_page' => 1,// 'offset' => 0,));foreach( $newslist1 as $post ): setup_postdata( $post );?><?php $et1 = do_shortcode('[postexpirator dateformat="YmdHis" type=date]');?><?php endforeach;?><?php$newslist2 = get_posts( array('category_name' => 'informations','posts_per_page' => 1,'offset' => 1,));foreach( $newslist2 as $post ): setup_postdata( $post );?><?php $et2 = do_shortcode('[postexpirator dateformat="YmdHis" type=date]');?><?php endforeach;?><?php$newslist3 = get_posts( array('category_name' => 'informations','posts_per_page' => 1,'offset' => 2,));foreach( $newslist3 as $post ): setup_postdata( $post );?><?php $et3 = do_shortcode('[postexpirator dateformat="YmdHis" type=date]');?><?php endforeach;?><?php //抽出した日時の最大値の比較と現在時刻の取得mあた空の場合の置換$et1v = !empty($et1) ? $et1 : $ld;
$et2v = !empty($et2) ? $et2 : $ld;
$et3v = !empty($et3) ? $et3 : $ld;
$mx = max($et1v,$et2v,$et3v);$mx = max($et1,$et2,$et3);
$td = date('YmdHis');//現在時刻echo '<!--'.($et1).'/'.($et2).'/'.($et3).'/'.($mx).'|'.($td).'-->';//html上コメントアウトで現在と記事のアクティヴィティ日時を表示、あくまで確認のためのものあのでここのecho以下消してよし?>

上記コードで直近3件の記事のPPFプラグインでのアクション日時の抽出と最大値抽出ができた。
問題点としては(MTからCMS始めたからそっちの方が圧倒的にながい故比較する)MTの場合は件数設定の件数が期間内のものをその件数拾って比較演算するが、このコードの場合直近3件のみで比較するので4件前に期限未達のものがあっても表示されない(再表示、これもおかしなはなしだが・・・)。
前提としてその一覧からいつか消える=PPFでのアクション設定があること。イベントなどの頻度に応じて件数を増やしたり=個々のアクション日時を抽出する/表示件数を増やす必要がある。一年間のキャンペーンと来月のイベント、こんなのが混在すると、時系列的に先に書いた1年間のキャンペーンが一覧から消える。

さて、問題はこんなところだが、ざっくり言えば件数多めにすれば済むこと。
で、コードの続き。
入れ子の開始表示・非表示

<?php if ($mx > $td)://入れ子の表示非表示~記事の最大値と現在時刻の比較?>入れ子、ulでもdivでも何でもいいわ<?php else://表示期限内の記事がない場合入れ子等を非表示、だからelse文は基本いらない。?><?php endif; ?>

投稿情報タイトルなど抽出ループ。htmlタグは当スタジオのテーマInitializeのアトリなんかに合ってるので適当に。
コメントアウト部分は個別の記事別の終了日を表す、稼働確認できたら削除して良し。

<?php /*投稿情報抽出ループ、per_pageで件数、catでカテゴリID htmlタグは適当に*/?><?php $args = array('posts_per_page' => 3,'cat' => 2);$the_query = new WP_Query($args);if ( $the_query->have_posts() ) :?><?php while ( $the_query->have_posts() ) : $the_query->the_post();?><?php $endtime = do_shortcode('[postexpirator dateformat="Y-m-d" timeformat="H:i:s"]');if (date('Y-m-d H:i:s') < $endtime) { ?><!--<?php $endtime = do_shortcode('[postexpirator dateformat="Y-m-d" timeformat="H:i:s"]');echo $endtime; ?>--><a href="<?php echo get_permalink(); ?>"><picture><img src="<?php the_post_thumbnail_url('thumbnail', array('class' => 'alignnone')); ?>" alt="<?php the_title(); ?>" /></picture><h3 class="newsR"><span><?php echo get_the_date('Y年m月d日'); ?></span><?php the_title(); ?></h3></a><?php } ?><?php endwhile; ?><?php endif; ?>

入れ子の終了表示・非表示

<?php if ($mx > $td)://入れ子(閉じ)の表示非表示?><?php else://表示期限内の記事がない場合入れ子等を非表示、このelseはなくていい?><?php endif; ?>

これでカテゴリー2の直近3件の表示期限と全記事消える際に入れ子も消えるコード。