ようこそのお運びで、厚く御礼申し上げます。
今回は、記事を自動的に読み込むショートコードを作成します。
指定した件数ごとに、記事を自動的に読み込むショートコード
ありそうな機能ではありますが、今回は記事の読み込みとAjaxの実装について考えてみます。
WordPressでAjaxを使う場合のおさらい
Ajaxについては、以前記事に書いたことがありますのでまずはこちらを参照してください。
※こちらは書き込みの場合ですが基本は一緒
基本は 「HTTPリクエスト」→「wp_ajaxアクションフック」→「コールバック関数の実行」 という流れです。
HTTPリクエストを受け取ったWordPressは、「wp_ajaxアクションフック」で受け取り、 処理を実行する関数に渡します。
今回の仕様について
- 記事に「記事一覧(Ajax)」を読み込むショートコード「[paka3GetPosts]」を記入
- 属性は
一度に読み込む件数(count): デフォルト値2
並び順(order):ASC/DESC:デフォルト値DESC
関連タグ(tag):複数の場合カンマ区切り
関連カテゴリー(cat):カテゴリーID、複数の場合カンマ区切り - ショートコードの再帰的な実行は許可しない
- 記事一覧の作成にはget_postsを使う(SQLの直打ちはしない)
- スクロールをし、指定場所にくると自動的に読み込み
- 自動的に読み込むのは今回は記事タイトル・日付・本文です。
画面フローについて
記事本文にショートコードを記入する。
記事を表示してみると、一番目の記事を読み込んで表示。
※分かりやすいように画面フローの本文は省略しています。※続きを読み込むボタンは、読み込み中は非アクティブです(あまり意味はない)。
スクロールをすると、記事を取得するため自動的に問い合わせを行う 記事が読み込まれて表示されます。
プラグインファイルを準備します。
「wp-contents>plugins」ディレクトリに「paka3_get_posts」ディレクトリを作成し、「paka3_get_posts.php」と「js/paka3_post.js」を作成します。(ローディング画像も用意してください)
コードのダウンロードはこちらから
ダウンロードしたい方、コード全体を確認したい方は、先にこちらからどうぞ(gitHub)。
機能の実装:paka3_get_posts.php
このファイルでは
- ショートコードの実装
- Ajax:コールバック関数
等を実装しています。
クラス構造の作成する
今回は、上記の機能を「ひとつのクラス」にしています。
$a = new Paka3GetPosts ; class Paka3GetPosts{ public function __construct(){ } //################### //AjaxのJavascriptの指定 //################### function my_action_javascript($hook_suffix) { } //################################## //Ajaxコールバック関数 //################################## public function my_action_callback(){ } //################################## //表示(ショートコードで表示されるHTML) //################################## public function paka3_html( $atts ){ } //################### //表示:スタイルシートの指定 //################### public function my_style($hook_suffix) { } }
※機能毎に2つに分けた方が分かりやすいかもしれません。
まずは、ショートコードを設定します。
今回は、paka3GetPostsというショートコードを作成します。
※ショートコードについて、分からない方はこちらを参照してください。
コンストラクタでショートコードを追加します。
//ショートコード[paka3GetPosts]を設定 add_shortcode("paka3GetPosts",array($this,'paka3_html'));
関数「paka3_html」が実行されます。
public function paka3_html( $atts ){ //処理と、表示される内容(html) }
ショートコードで表示される内容
今回は、Ajaxで記事一覧を取得します。なので、表示されるidを設定します。
<!-- ここに表示 --> <ul id="res"></ul>
また、スクロールで読み込みするポイントも設定してあげます。
<!-- このポイントで読み込み --> <div class="paka3_trigger"></div>
読み込む方法は色々ありますが、今回は
hiddenで読み込み回数をもたせて、それを基準にHTTPリクエストをおこなっていきます。
<!--読み込み回数--> <input type=hidden id=paka3getpost_count value = "0" /> <!-- 読み込みボタン --> <button type="button" class="btn" id="getPostsSubmit">続きを読み込む</button> <div id=loadingmessage><img src="{$dirUrl}/loadimg.gif" />
今回は遠回りかもしれませんが、分かりやすく、
id="getPostsSubmit"のボタンがクリックされると実行されることにします。
※スクロールされるとこのボタンがクリックされるという処理を行う
ショートコードの属性については・・・
本当は属性をあまりもたせない方が良いかもしれませんが、
今回は属性を設定しちゃったので、属性の配列をシリアライズをし、base64化して
//配列をシリアライズしてbase64化する $args = base64_encode (serialize($args));
hiddenに設定します。
<!--属性で設定した値--> <input type=hidden id=paka3getpost_data value = "$args" />
※ショートコードの属性値の配列設定については、ソースコードを参照。
paka3_post.jsファイルの読み込み。その1
Javascriptの読み込みはコンストラクタでwp_enqueue_scriptsをフックし、
//Javascript読み込み add_action( 'wp_enqueue_scripts', array($this,'my_action_javascript'),10,1);
paka3_post.jsファイルの読み込み。その2
my_action_javascript関数で読み込みます。
※このとき「wp_create_nonce」を生成し、jsファイルに渡します。(セキュリティ対策)。
function my_action_javascript($hook_suffix) { wp_enqueue_script( 'paka3_submit', plugin_dir_url( __FILE__ ) . '/js/paka3_post.js', array( 'jquery' )); //jsファイルに値を送る wp_localize_script( 'paka3_submit', 'paka3Posts', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'security' => wp_create_nonce( get_bloginfo('url').'paka3GetPosts' )) ); }
paka3_post.js:HTTPリクエストのタイミングについて
今回、読み込むタイミングは以下のとおりです
- ウィンドウを開いたとき
- スクロールしたとき(指定の場所にきたとき)
- ボタンがクリックされたとき
この読み込みをJQueryで処理をしていきます。
※実行処理本体はクリックされたときに処理されます。
paka3_post.js:ウィンドウが開いたとき
jQuery(function($) { //初回、ページの読み込みが完了したら実行 $(function(){ $(window).load(function () { $('#getPostsSubmit').trigger("click"); }); }); })(jQuery);
paka3_post.js:スクロールしたとき
//指定した場所を表示したら //#getPostsSubmitをchick jQuery(function($) { $(function() { $('#getPostsSubmit').trigger("click"); //基準となる要素を指定する var triggerNode = $(".paka3_trigger"); // 画面をスクロールしたときに実行 $(window).scroll(function(){ var triggerNodePosition = $(triggerNode).offset().top - $(window).height(); if ($(window).scrollTop() > triggerNodePosition) { //#getPostsSubmitをchick $('#getPostsSubmit').trigger("click"); } }); }); })(jQuery);
paka3_post.jsのコード
javascrptのソースコード全体です。ボタンをクリックしたときの部分が本体。
再び、paka3_get_posts.php、コールバック関数の設定
コールバック関数は、コンストラクタで設定を行います。 記事一覧のHTTPリクエストが行われたとき、コールバック関数「my_action_callback」が呼び出されます。
if( is_admin() ){ //コールバック関数の呼び出し //すべてのユーザーを対象(ログイン+非ログイン) //*ログインユーザ add_action('wp_ajax_paka3_gp_action',array($this,'my_action_callback')); //*非ログインユーザ add_action('wp_ajax_nopriv_paka3_gp_action',array($this,'my_action_callback')); } else { //通常の表示 add_shortcode("paka3GetPosts",array($this,'paka3_html')); }
コールバック関数「my_action_callback」でJSONを出力
get_postsで正しく取得できれば、記事一覧をJSON出力をします。
//記事の取得(配列) $posts_array = get_posts( $this->args ); //JSON出力 $response = json_encode( $posts_array ); header( "Content-Type: application/json" ); echo $response; exit;
get_postsで記事を取得しよう!
そのJSON出力するには、get_postsで記事を取得する必要があります。 まずは、コンストラクタで引数の初期値を設定しておきます。
//get_postsの呼び出し条件(初期値) $this->args = array( 'numberposts' => 2, 'offset' => 0, 'category' => '', 'orderby' => 'post_date', 'order' => 'DESC', 'post_type' => 'post', 'post_status' => 'publish');
次にコールバック関数「my_action_callback」でショートコードに設定した属性値を取得します。 このコールバック関数にはPOSTデータとしてbase64化された値がわたってくるのでデコードします。
//base64を解除→アンシリアライズする(配列) $args = unserialize( base64_decode( $_POST['paka3getpost_data'] ) );
値を配列にデコードしたら、夫々に設定をします。
//データの設定 $this->args['numberposts'] = $args[ 'count' ] ? $args[ 'count' ] : $this->args['count'];; $this->args['offset']= $_POST['paka3getpost_count'] * $this->args['numberposts'] ; $this->args['order'] = $args[ 'order' ] ? $args[ 'order' ] : $this->args['order']; $this->args['tag'] = $args[ 'tag' ] ? $args[ 'tag' ] : $this->args['tag']; $this->args['category'] = $args[ 'cat' ] ? $args[ 'cat' ] : $this->args['category'];
あとは、get_postsで値を取得します。
//記事の取得 $posts_array = get_posts( $this->args );
※呼び出された記事本文のショートコードについて
記事本文は、テキストデータです。 今回はショートコードをdo_shortcodeで動かせるようにしておきます。
$a = array(); //記事データの整形 foreach ( $posts_array as $akey => $aval) { $a[ $akey ] = $aval ; //ショートコードを有効にする $a[ $akey ]->post_title = $a[ $akey ]->post_title; $a[ $akey ]->post_content = do_shortcode( $aval->post_content ) ; }
また、今回のショートコードは再帰的に読み出すことを禁止にしておきたいので
//ショートコードの再帰呼び出しの回避 remove_shortcode( "paka3GetPosts" );
とコールバック関数内に追記しておきます。 当然ですが、こちらで呼び出された記事本文はthe_contentのフィルターフックは有効化されません。
セキュリティ対策:nonceを精査しよう
HTTPリクエストを受け取ったときに、nonceも「paka3_post.jsファイルの読み込み。その2」で設定されており、同時に送信されています。 なので、セキュリティ対策としてcheck_admin_refererで精査しましょう。
if( isset($_POST['paka3getpost_count']) && isset($_POST['paka3getpost_data']) && check_admin_referer( get_bloginfo('url').'paka3GetPosts','security')){ //処理 }
paka3_get_posts.phpのコードと有効化
paka3_get_posts.phpのコード全体は以下のようになりました。
説明では省略している部分もあるので、よく確認してみましょう。
プラグインを有効化し実際にショートコードを書いてみてください。
今回のまとめ
取得したデータは、そのままではショートコードが使えない、the_contentなどのフィルターフックが使えない等も発生するので注意は必要かもしれません。