ポータルページを作る。

By | 2017年7月2日

はじめに

今回はあまり手っ取り早くない作業について書きます。

本サイトで使用しているIconic Oneテーマでは、トップページに最新の投稿を表示する設定としていましたが、過去に投稿した記事についても適宜修正を加えています。そこで、以下の機能を持つポータルページを作成することにしました。

  1. 記事の新規投稿と修正・更新を合わせたChangeLog(最新の10件分)をページの先頭に表示する。
  2. ChangeLogの下にランダムに選択した記事を1件表示する。
スポンサーリンク

ChangeLogの自動生成

SQL文の作成

まず、記事の新規投稿と修正・更新を合わせたChangeLogをページの先頭に表示するのですが、WordPressの記事はデータベースに格納されているので、SQL文を使って最近新規投稿されたか修正・更新された記事を新規投稿または修正・更新された時刻の新しい順に10件取り出し、かつその中から以下の情報をデータベースから取り出すためのSQL文を書きます。

  • ID (URLを作成するために必要です。)
  • 記事のタイトル
  • 記事の最後の修正時刻
  • 記事が新規に投稿されたものなのか、それともアップデートされたものなのかを示すフラグ

上記の4個の情報のうち、最後の1個を除く3個についてはwp_portsテーブルにそのものズバリのカラムがありますが、最後の1個は直接カラムに格納されているものではないので、記事の新規投稿時刻(post_dateカラム)と記事の最後の修正時刻(post_modifiedカラム)を利用して作成する必要があります。post_dateカラムとpost_modifiedカラムの値は記事の状況に応じて以下のように変化します。

  • 記事が新規に投稿された場合: 対応するpost_dateカラムとpost_modifiedカラムの値が等しくなる。
  • 記事が修正・更新された場合: post_modifiedカラムが修正・更新された時刻に変更される。よって、post_dataカラムとpost_modifiedカラムの値が等しくなくなる。

ので、SQL文のCASE句を使って仮のカラムを作成し、上記の2ケースのうち前者の場合には1を、後者の場合には2をそれぞれ割り当てることにします。

また、wp_postsテーブルには公開されている記事以外の要素(ナビゲーションの要素等)などについての情報もレコードとして書き込まれているので、記事または固定ページで、かつ公開されているものをwhere句で選択する必要があります。

以上の点を踏まえて、必要な情報をデータベースから取り出すためのSQL文は以下のようになります。

select id,post_title,post_modified,(case when post_date=post_modified then 1 when post_date<>post_modified then 2 else 0 end) as is_updated from wp_posts where post_status=’publish’ and post_type in (‘page’,’post’) order by post_modified desc limit 10;

ChangeLogを表示するためのショートコードを書く。

ここまででSQL文が作ることができたので、これを呼び出して、HTMLのsnippetを作成するためのショートコードをfunction.phpに追加します。今回は以下のようなコードを追加してみました。

function last_updated_code() {
global $wpdb;
$query = “select id,post_title,post_modified,(case when post_date=post_modified then 1 when post_date<>post_modified then 2 else 0 end) as is_updated from wp_posts where post_status=’publish’ and post_type in (‘page’,’post’) order by post_modified desc limit 10”;
$rows = $wpdb->get_results($query,ARRAY_A);
if (count($rows) == 0) {
return “<p>新着記事または修正情報はありません。</p>”;
}
$code = “<p><ul>\n”;
foreach($rows as $row) {
$code .= “<li>”.date(‘Y/n/j’,strtotime($row[‘post_modified’])).”:「<a href=\”/?p=”.$row[‘id’].”\”>”.$row[‘post_title’].”</a>」”.(($row[‘is_updated’]==1)?”を新規に追加”:”の内容を更新”).”しました。</li>\n” ;
}
$code .= “</ul></p>\n”;
return $code;
}

add_shortcode(‘last_updated’,’last_updated_code’);

 
上記のコードを追加して、記事の編集画面中の適当な場所で、

[last_updated]

 
と書くと、新着または更新情報についてのHTML snippetを追加することができます。

ランダムに選択した記事を1件表示する。

ChangeLogだけだとポータルページの内容としてはいまいち内容が薄くなってしまうので、本サイトの記事から記事をランダムに1件選択して表示するためのショートコードを作成して、ポータルページから呼び出すことにします。

以下のコードをfunction.phpに追加します。

function select_random_posts() {
global $from_random_posts;
$args = array(
‘post_type’ => ‘post’,
‘orderby’ => ‘rand’,
‘posts_per_page’ => 1,
);


スポンサーリンク

$the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) {
$string = “”;
while ( $the_query->have_posts() ) {
$the_query->the_post();
$string .= ‘<h1><a href=”‘. get_permalink() .'”>’. get_the_title() .'</a></h1>’;
$string .= apply_filters(‘the_content’,get_the_content());
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
$string = ‘記事がありません。’;
}

return $string;
}

add_shortcode(‘select-random-posts’,’select_random_posts’);

 
検索の条件が前項の新着・修正記事の検索のときほど複雑ではない(少なくともCASE句は使わなくても事足ります。)ので、WP_Queryを使ってランダムに1件記事を取得しています。記事の内容はget_the_content関数を使ったあとthe_contentフィルタを適用していますが、これはthe_content関数をそのまま使用すると、ランダムに取得した記事がページの先頭に来てしまうためで、the_content関数の中からthe_contentフィルタを適用する部分だけを抜き出して適用するコードとしています。これを思いつくまでにかなりハマりました。

上記のコードを追加して、記事の編集画面中の適当な場所で、

[select-random-posts]

 
と書くと、ランダムに選択した記事を1件表示することができます。

まとめ

本記事ではポータルページの作り方について書いてみました。実はショートコードは初めて書いてみたのですが、割といろいろできそうです。あと、MariaDBでもCASE句が使えますが、これをうまく使うと呼び出し側のロジック(今回の例ではPHPのロジックになりますが、)を大幅に削減できるので、覚えておくといろいろなところで役に立つと思います。

この記事は以上です。