WordPressで作るアンテナサイトの1時間ごと、3時間ごとのRSS配信の仕組みの続きである。前回はクリックカウンタをつけてどの記事が人気なのかを判別できるようにした。では、RSSを配信するにはどうすればよいだろうか。

これまで作ってきた仕組みでは、取得した記事一つ一つがWordPressの一つの投稿記事に対応するようになっている。それをPHPで整形することで取得した記事リストの形に見せている。そのままWordPressのRSS出力機能を使うと、一つの記事リンクが出るだけの個別ページ(テンプレートのsingle.php)が出力されてしまう。取得した記事の名前をタイトルとして使って、カテゴリごとのトップページのリンクをRSSで発信しても、新たに記事を取得したら、タイトルにした記事が流れて行ってしまい、リンクをたどってきてくれた人が目的の記事を見つけられないなどという自体が容易に想像できる。

今回行いたいのは、一定時間内(1時間と3時間の2種類)によくクリックされた記事を、一定数まとめて紹介する記事を作り、RSSで出力することだ。WordPressあと2つあれば、1時間ごとと3時間ごとの記事紹介の記事を生成してRSSで配信できそうだ。

そんな機能を1つのWordPressの中で実現できる仕組みが用意されている。カスタム投稿タイプと呼ばれる機能だ。1つのWordPressの中に3つのブログを作るイメージだ。一つは今まで作った取得した記事を格納しておくブログ。そしてあと二つRSS配信用の記事紹介の記事を生成し、格納しておくブログを追加するのである。この機能は、WordPressを使ってブログじゃないサイトを作るときにも便利である。デフォルトの投稿を使って”新着情報”を発信し、カスタム投稿タイプを追加して”お知らせ”を発信するなどの使い方ができる。今回はそれをRSS発信目的に使ってしまおうというわけだ。

では実際にどうやるのかといえば、functions.phpにこんな感じで追記する。


/* カスタム投稿追加 */
add_action('init', 'my_custom_init');
function my_custom_init()
{
  $labels = array(
    'name' => _x('投稿1h', 'post type general name'),
    'singular_name' => _x('投稿1h', 'post type singular name'),
    'add_new' => _x('新しく投稿1hを書く', 'forrss1h'),
    'add_new_item' => __('投稿1hを追加'),
    'edit_item' => __('投稿1hを編集'),
    'new_item' => __('新規の投稿1h'),
    'view_item' => __('投稿1hを見る'),
    'search_items' => __('過去の投稿1hを探す'),
    'not_found' =>  __('投稿1hグ記事はありません'),
    'not_found_in_trash' => __('ゴミ箱に投稿1hはありません'),
    'parent_item_colon' => ''
  );
  $args = array(
    'label' => __('Events'),
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => 5,
    'supports' => array('title','editor'),
    'has_archive' => true
  );
  register_post_type('forrss1h',$args);
  register_taxonomy_for_object_type('category', 'forrss1h');
}

//パネル用
add_filter('post_updated_messages', 'book_updated_messages');
function book_updated_messages( $messages ) {

  $messages['forrss1h'] = array(
    0 => '', // ここは使用しません
    1 => sprintf( __('投稿1hを更新しました <a href="http://www.blogger.com/%s">記事を見る</a>'), esc_url( get_permalink($post_ID) ) ),
    2 => __('カスタムフィールドを更新しました'),
    3 => __('カスタムフィールドを削除しました'),
    4 => __('投稿1h更新'),
    5 => isset($_GET['revision']) ? sprintf( __(' %s 前に投稿1hを保存しました'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
    6 => sprintf( __('投稿1hが公開されました <a href="http://www.blogger.com/%s">記事を見る</a>'), esc_url( get_permalink($post_ID) ) ),
    7 => __('投稿1h記事を保存'),
    8 => sprintf( __('投稿1h記事を送信 <a href="http://www.blogger.com/%s" target="_blank">プレビュー</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
    9 => sprintf( __('投稿1hを予約投稿しました: <strong>%1$s</strong>. <a href="http://www.blogger.com/%2$s" target="_blank">プレビュー</a>'),
      date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
    10 => sprintf( __('投稿1hの下書きを更新しました <a href="http://www.blogger.com/%s" target="_blank">プレビュー</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
  );

  return $messages;
}

//プルダウン用テキスト
add_action( 'contextual_help', 'add_help_text', 10, 3 );

function add_help_text($contextual_help, $screen_id, $screen) {

  if ('forrss1h' == $screen->id ) {
    $contextual_help =
      '<p>' . __('定期実行RSS出力用') . '</p>' ;
  } elseif ( 'edit-book' == $screen->id ) {
    $contextual_help =
      '<p>' . __('カスタム投稿。') . '</p>' ;
  }
  return $contextual_help;
}

これでforrss1hという名前のカスタム投稿ができた。WordPressの管理画面にログオンしてみれば「投稿」メニューの下に「投稿1h」が追加されているはずだ。ここから記事を書けば普通に投稿から投稿された記事とは区別された投稿1hの記事が投稿される。どのように区別されるかというと、データベース内のwp_postsテーブルのpost_typeカラムの値が変わる。デフォルトの投稿では値が”post”となり、今回作ったカスタム投稿タイプ「投稿1h」ではforrss1hとなる。こんな具合である。


mysql>
mysql> show columns from wp_posts;
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field                 | Type                | Null | Key | Default             | Extra          |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| post_author           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| post_date             | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_date_gmt         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content          | longtext            | NO   |     | NULL                |                |
| post_title            | text                | NO   |     | NULL                |                |
| post_excerpt          | text                | NO   |     | NULL                |                |
| post_status           | varchar(20)         | NO   |     | publish             |                |
| comment_status        | varchar(20)         | NO   |     | open                |                |
| ping_status           | varchar(20)         | NO   |     | open                |                |
| post_password         | varchar(20)         | NO   |     |                     |                |
| post_name             | varchar(200)        | NO   | MUL |                     |                |
| to_ping               | text                | NO   |     | NULL                |                |
| pinged                | text                | NO   |     | NULL                |                |
| post_modified         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_modified_gmt     | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content_filtered | longtext            | NO   |     | NULL                |                |
| post_parent           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| guid                  | varchar(255)        | NO   |     |                     |                |
| menu_order            | int(11)             | NO   |     | 0                   |                |
| post_type             | varchar(20)         | NO   | MUL | post                |                |
| post_mime_type        | varchar(100)        | NO   |     |                     |                |
| comment_count         | bigint(20)          | NO   |     | 0                   |                |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.00 sec)

mysql>
mysql>
mysql>
mysql> select post_type,ID from wp_posts where ID = 95622;
+-----------+-------+
| post_type | ID    |
+-----------+-------+
| post      | 95622 |
+-----------+-------+
1 row in set (0.00 sec)


mysql>
mysql> select post_type,ID from wp_posts where ID = 95570;
+-----------+-------+
| post_type | ID    |
+-----------+-------+
| forrss1h  | 95570 |
+-----------+-------+
1 row in set (0.00 sec)

mysql>

作ったカスタム投稿タイプにPHPから投稿したい場合は、ご想像の通り今まで通りwp_insert_postを使い、post_typeに”forss1h”を指定すれば投稿1hに投稿できる。wp_insert_postでカスタム投稿をする際に、post_contentに記事紹介のhtmlを自答生成してぶち込んでやればいい。 カスタム投稿タイプ も普通の投稿と同じくRSSが自動で出力されている。http://サイトドメイン/forrss1h/feed/とすればRSSにアクセスできるはずだ。

あとはcronで1時間ごとに動くように記事紹介HTML生成してを投稿1hに投稿するPHPをセットすればいい。記事紹介HTMLを並べる際にクリックカウンタで重みづけをすれば直近の一時間で人気のあった順に記事100個を紹介するHTMLなどという紹介の仕方もできるだろう。同じ要領で3時間ごとのカスタム投稿タイプを追加したり、30分ごとのを追加したりと増やしていくことも可能だ。

ちなみに、前回まではpost_contentを、-::-を区切り文字とした情報の一時格納庫としてしか使っていなかったが、今回はHTMLlを直接入力している。このぶち込むHTMLではPHPやJavascriptといったプログラムが動作しないようになっている。ブログの投稿者がPHPを記述できてしまうのはセキュリティー的に大問題だからだ。なので、クリックカウンタの数字を表示させようとしてもPHPを直接ぶち込んで表示させるということができない。そんな時に便利なのがショートコードタグである。あらかじめfunctions.phpにadd_shortcodeでショートコードタグを作っておけば、作ったタグを張り付けるだけでfunctions.phpに書いたPHPを動作させることができる。クリックカウンタを取得してクリック数を表示するショートコードタグの例を貼ってみる。


// [count_pop c_id=num]
function count_pop_func($atts) {

      extract(shortcode_atts(array(
               'c_id' => 0,
      ), $atts));


        $link = mysql_connect('ホスト名', 'ユーザ名', 'パスワード');
        if (!$link) {
                echo $link;
                $sql_error = "mysql_error()";
                echo $sql_error;
        }

        $db_selected = mysql_select_db('DB名', $link);
        if (!$db_selected) {
                echo $db_selected;
                $sql_error = mysql_error();
                echo $sql_error;
        }


        $result = mysql_query("select comment_count from wp_posts where ID = $c_id");
        if (!$result) {
                echo 'select failed.' ;
                $sql_error = mysql_error();
                echo  $sql_error;
                die($sql_error);
        }

        $row = mysql_fetch_assoc($result);
        if ($row['comment_count'] != 0 ){
               $count_pop = $row['comment_count']."clicks!";
        } else {
                $count_pop = "";
        }

        return $count_pop;
}
add_shortcode('count_pop', 'count_pop_func');

add_filter('widget_text', 'do_shortcode');

これで、[count_pop 投稿ID]というタグを使えば、post_contentの中でもクリック数をDBから取ってきて表示させるというPHPを動かすことができる。簡単に解説すると、count_pop_funcという関数を作ってそこにクリックカウンタを取得して”n clicks!”という文字列を返すように書いておく。この関数をadd_shortcodeでcount_popというショートコードとして登録し、add_filterでウィジェットでも動くようにフックしている。このショートコードはPHPだけでなく、コードを文字列として返す関数をショートコード化すればJavascriptを動かしたいときにも使えるので、googleアドセンスのコードを格納しておくと便利だ。また、ウィジェットのかかでも使えるので、テキストウィジェットでPHPを動かしたい時などには使いが手が良い。ウィジェット内ではJavascriptは禁止されていないので普通に動く。

これで一通り、RSSやAtomを取得して蓄積し、記事紹介をRSSで発信するという基本的な機能を備えたアンテナサイトが作れるようになったと思う。あとはいろいろな機能を創意工夫して付け加えていくだけで豪華なアンテナになるはずである。WordPressには多種多様なテンプレートがあるので、仕様規約に違反しない範囲でアンテナに改造してしまえば、プロ並みに綺麗な見た目のアンテナも容易にできてしまう。PHP習得の練習問題としてアンテナサイト構築はなかなか手頃な課題なのではないだろうか。これで我がKnowledgeアンテナ研究室(*追記:リニューアルにより現在はWordpressを使わないアンテナサイトに生まれ変わっています。)にもたくさんのアクセスが来てくれるようになれば言うことなしである。RSS配信の仕方の記事を去年の7月ごろにリクエストしてくださった通りすがりの方、遅くなって済みません。次回からは、更新情報を取得して自動でTwitterに呟くbotの作成方法などを、気が向いたら書こうかなぁと思う。期待しないで待て!

*追記: 反響にお答えし、アンテナサイト用Wordpressテーマ「Antena Institute」をリリースいたしました。
詳しくは、「Antena Instituteについて」をご参照ください。
ご購入を希望される方は、下記リンクにてAntena Instituteをご購入ください。

Antena Institute(PHP7版) | 銀仁堂

Antena Institute(PHP5版) | 銀仁堂

さらに、TwitterBotスクリプトも併せてどうぞ。
Twibot Institute | 銀仁堂

2 件のコメント!

  • 初めまして。
    アンテナサイト制作の一連の流れについて読ませていただきました。
    なんとなくどういう事をやっているのかは掴めたのですが、私はhtml/cssしか学んだことがないのでphp,MySQLの部分があまり理解できませんでした。
    よく売っているphpとmysqlの本を読めば伯爵様のようにアンテナサイトを作れるようになりますか?
    他に何かの予備知識は必要になるのでしょうか?

    • anygggさんこんにちは。

      まずは、ViretualBOXなどで練習用のPHPの動くWEB・DBサーバーを構築していろいろいじくってみるといいと思います。わざわざ本を買わなくても、Webを探せばPHPやMySQLのマニュアルが公開されてますのでそれを読むだけでも十分にアンテナサイト程度なら構築可能だと思います。構築できなければAntenaInstituteをご購入いただくと手軽にWordPressを使用してアンテナサイトが作成できちゃいますので、是非ご検討ください。

      頑張ってください。応援しております。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


*


*

投げ銭はこちらへ
bitcoin : 1AFU37YroGt8ohmFz8nG1N2ockL56Z4hfQ

ADA Coin: DdzFFzCqrhskq33AqGL8XkJZ3bb1hpxJYTd2UrJFKVpXphWG8d1RuhQrKymmKU1zzjvGi7oU69PaJ7nXECRG4Kpvg27Pghf3hpRNhRMy
2025年3月
 12
3456789
10111213141516
17181920212223
24252627282930
31  
カテゴリー