そこで、今回は最近の一覧を表示するのではなく、毎日のチェックを表示しないウィジェットと毎日のチェックだけを表示するウィジェットを作ってみることにしました。
まず「最近のエントリ」ウィジェット自体がどうなっているのかを探してみます。このウィジェットは WordPress 本体にバンドルされている標準ウィジェットなので Core コードの中にあるはずです。
Core コードの中を recent というキーワードで探してみたところ、 wp-includes/defualt-widgets.php の中で WP_Widet_Recent_Posts というウィジェットが定義されていました。
527 528 529 530 531 532 |
/** * Recent_Posts widget class * * @since 2.8.0 */ class WP_Widget_Recent_Posts extends WP_Widget { |
このクラスがまさに「最近のエントリ」と表示しているウィジェットの定義なので、この中でエントリを抽出しているところを探したところ、WP_Widget_Recent_Posts クラスの widget メソッドで WP_Query を実行しています
1 2 3 4 5 |
function widget($args, $instance) { […] $r = new WP_Query( apply_filters( 'widget_posts_args', array( 'posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true ) ) ); […] } |
WP_Query は WordPress のエントリを検索するための関数です。どのようなものを検索するかを apply_filters で定義しています。
したがって、WP_Query で “Checked” カテゴリを除いて検索すれば「最近のエントリ」の中に Checked カテゴリのものが含まれなくなります。WP_Query の使い方は WordPress Codex を参考にして、カテゴリを Query キーに設定するようにします
関数リファレンス/WP Query – WordPress Codex 日本語版
ざっくり言うと、Query しているパラメータにカテゴリを示す cat を指定して、排除するカテゴリ ID を指定します。今回、排除したいカテゴリ ID は 3 ですので -3 を指定します。
(カテゴリ ID はそれぞれのブログやカテゴリによって異なります。 WordPressで記事とカテゴリのIDを調べる方法 | Web活メモ帳 にある方法で調べられます。)
1 2 3 4 5 |
function widget($args, $instance) { […] $r = new WP_Query( apply_filters( 'widget_posts_args', array( 'posts_per_page' => $number, 'no_found_rows' => true, 'post_status' => 'publish', 'ignore_sticky_posts' => true, 'cat' => '-3' ) ) ); […] } |
この変更で Checked カテゴリのエントリが排除された「最近のエントリ」が表示されるようになりました。しかし core コードを修正するのは今後のことを考えるとあまり良い方法では無いので、別の方法で実現することにします。
Widgetをどこに定義するか
先ほどの処理は、試しに Core コードを修正して動作を確認しましたが、今度は独立したウィジェットとして定義したいと思います。ウィジェットを定義する場所ですが、テーマによっては特定のウィジェットを定義しているものがありますので、今回は子テーマの中で定義したいと思います。
なお、この方法は後述する理由から、あまりオススメではなく、本来はプラグインにした方が良いと思いますが、段階的に進めていきたいと思います。
標準でバンドルされているテーマ TwentyEleven でもウィジェットを定義していますので、 TwentyEleven ではどうやって定義しているのかを見てみたところ inc/widgets.php で定義して functions.php で読み込んでいましたので、同じようにやってみます。
子テーマの中に inc/widgets.php というファイルを作成して、その中でウィジェット mySelectedRecentPostWidget と myRecentCheckedPostWidget を作成します。
ウィジェットは WP_Widget を継承して作れば良いのですが、今回は WP_Widget_Recent_Posts とほとんど同じ機能なので、 WP_Widget_Recent_Posts を継承して作りました。WP_Widget_Recent_Posts から変更しなければならないメソッドはウィジェットのクラス名などを登録するコンストラクタと WP_Query を実行している widgets メソッドのみ。あとは変更不要なので、この 2 つを widgets.php に定義します。
コンストラクタは WP_Widget_Recent_Posts のコンストラクタを呼べれば良かったのですが、継承できる構造になっていなかったので WP_Widget を呼び出しています。キャッシュの仕組みやオプションの仕組みは WP_Widget_Recent_Posts のものをそのまま利用しています。
途中までのソースを載せておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class mySelectedRecentPostWidget extends WP_Widget_Recent_Posts { function mySelectedRecentPostWidget() { $widget_ops = array('classname' => 'widget_selected_recent_entries', 'description' => __( "The most recent posts on your site without checked category") ); $this->WP_Widget('selectedentries', '最近の投稿(Checkedのぞく)', $widget_ops); $this->alt_option_name = 'widget_selected_recent_entries'; add_action( 'save_post', array(&$this, 'flush_widget_cache') ); add_action( 'deleted_post', array(&$this, 'flush_widget_cache') ); add_action( 'switch_theme', array(&$this, 'flush_widget_cache') ); } function widget($args, $instance) { $cache = wp_cache_get('widget_selected_recent_posts', 'widget'); […] |
カテゴリ checked だけを読み込むためには、WP_Query で cat に 3 を指定するようにするだけ。同じように書けばOKです。
本当は表示するカテゴリをオプションで選択できるようにしてあげるのが正しいのでしょうが、今回は練習でもあるのでこんな感じで書いてみました。
functions.phpでウィジェットを読み込む
先ほど定義したウィジェットを functions.php で読み込みます。ここでのポイントは widgets.php の読み込み方。子テーマのフォルダをとり出すためのメソッドは get_stylesheet_directory を使っています。get_template_part というメソッドもあるようなのですが、テンプレート用というよりも、スタイルシートのディレクトリを取得する方が正しい気がするので、こちらを利用。
1 2 3 4 5 6 7 8 9 10 11 |
if ( ! function_exists( 'birdtipscustom_widget_init' ) ): function birdtipscustom_widgets_init() { require(get_stylesheet_directory() . '/inc/widgets.php' ); register_widget( 'mySelectedRecentPostWidget' ); register_widget( 'myRecentCheckedPostWidget' ); } add_action('widgets_init', 'birdtipscustom_widgets_init' ); endif; |
あとは単純にウィジェットを登録するように書いて、その関数を widget_init から呼び出すようにアクションを追加して完成です。
プラグインにした方が良い理由
今回は子テーマの機能として実装しましたが、本来はプラグインにした方が良いと先ほど書きました。その理由は以下の2点です。- ウィジェットを使わなくなった時にデータベースからオプションデータを消す後始末ができない
- テーマを変更する時に子テーマに組み込み直す必要がある
オプションデータの後始末は、今回はタイトルと表示するエントリ数の 2 つだけですが、 wp_options にデータを保持しています。このデータを削除する手段がないのです。プラグインだとプラグインを削除する時にこのデータを削除する機能を埋め込むことができます。
また、子テーマに組み込んでしまっているため、当たり前ですがテーマを変えた時に作り直さないといけません。
これらの理由から、本来はプラグインにするべきでしょう。
ということで今回のウィジェットはプラグインにしてからソースを公開したいと思います。
WordPress 関連のエントリ
インストールや設定変更とデータ移行
プラグイン
バージョンアップ
カスタマイズ
Stinger 3関連
チューニング
MAMPを使ったバックアップサイトの構築
開発関連
最後まで読んでいただきありがとうございます。
左のアイコンをクリックして、このブログを Feedly に登録していただけると嬉しいです
Facebook ページでも情報を発信していますのでよろしかったら「いいね!」をお願いします
RSSリーダへの登録は こちら からどうぞ。
コメントを残す