前提・実現したいこと
AjaxでのWordpress投稿システムの実装において、投稿後にその内容を表示させられないという問題が発生しました。
下記「該当のソースコード」にあるように、single.php を読むときに、投稿できている情報を使ってくれないという状況です。
自分なりの解決策として、下記「試したこと」にあるように、「Ajaxの中にAjax」という方法を考えたのですが、これは適切な方法ですか?
独学で不安なので、より適切な方法での実装を実現したいと思い質問させて頂きました。
宜しくお願いします。
該当のソースコード
まずこちらのPHPですが、
include locate_template( 'template-parts/single.php' );
と書いても、投稿後にその内容を表示させられないという問題が発生しました。(最後から12行目の部分です)
php
1/* nonceを出しておく */ 2add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' ); 3function my_enqueue_scripts() { 4 $handle_post_new = 'my_script_post_new'; 5 $jsFile_post_new= 'path/to/myscript_post_new.js'; 6 wp_register_script($handle_post_new, $jsFile_post_new, ['jquery']); 7 $action_post_new= 'my_ajax_action_post_new'; 8 wp_localize_script($handle_post_new, 'MY_AJAX_post_new', [ 9 'api' => admin_url( 'admin-ajax.php' ), 10 'action' => $action_post_new, 11 'nonce' => wp_create_nonce( $action_post_new ), 12 ]); 13 wp_enqueue_script($handle_post_new); 14} 15 16/* 投稿する */ 17add_action( 'wp_ajax_my_ajax_action_post_new', 'my_ajax_event_post_new' ); 18function my_ajax_event_post_new() { 19 20 $action_post_new = 'my_ajax_action_post_new'; 21 22 // nonceがただしい 23 if( check_ajax_referer($action_post_new, 'nonce', false) ) { 24 25 // データ受け取り 26 $post_new_title = esc_html( $_POST['post_new_title'] ); 27 $post_new_content = strip_tags( $_POST['post_new_content'], "<br>" ); 28 $post_new_meta_img = esc_html( $_POST['post_new_meta_img'] ); 29 30 // データ更新 31 $post_value = array( 32 'post_type' => 'post', 33 'post_author' => get_current_user_id(), 34 'post_title' => $post_new_title, 35 'post_content' => $post_new_content, 36 ); 37 $insert_id = wp_insert_post($post_value); // 投稿してそのIDを取得 38 if($insert_id) { 39 update_post_meta($insert_id, 'post_meta_img', $post_new_meta_img); 40 } else { 41 die('失敗しました。'); 42 } 43 44 // 出力 45 include locate_template( 'template-parts/single.php' ); 46 47 } 48 // nonceがおかしい 49 else { 50 51 die('失敗しました。'); 52 53 } 54 55 die(); 56}
ちなみにjQueryはこうです。
「.container」の中身を、新しい投稿内容を使った single.php に入れ替えることが目的でした。
jQuery
1$(document).on("click",".post_submit", function(){ 2 3 var post_new_area = $('.container'); 4 var post_new_title = $('#post_new_title').text(); 5 var post_new_content = $('#post_new_content').html(); 6 var post_new_meta_img = $('#post_new_meta_img').val(); 7 8 $.ajax({ 9 url: MY_AJAX_post_new.api, 10 type: 'POST', 11 data: { 12 action: MY_AJAX_post_new.action, 13 nonce: MY_AJAX_post_new.nonce, 14 post_new_title: post_new_title, 15 post_new_content: post_new_content, 16 post_new_meta_img: post_new_meta_img, 17 } 18 }) 19 // 成功したとき 20 .done(function( response_post_new ) { 21 var $articleOuter_post_new = post_new_area; 22 var $response_post_new = response_post_new; 23 $articleOuter_post_new.html(''); 24 $articleOuter_post_new.html( $response_post_new ); 25 }) 26 // 失敗したとき 27 .fail(function( response_post_new ) { 28 alert('失敗しました。'); 29 }); 30 31});
試したこと
上述のソースコードではできず、冒頭に書いたように「Ajaxの中にAjax」という方法を考えました。それがこちらの《変更➀》と《変更➁》です。
《変更➀》
PHP
1 // 出力 2 include locate_template( 'template-parts/single.php' );
↓次のように変更し、投稿されたslugを返すようにしました。
PHP
1 // 出力 2 $str = get_page($insert_id); 3 echo $str -> post_name;
《変更➁》
jQuery
1 // 成功したとき 2 .done(function( response_post_new ) { 3 var $articleOuter_post_new = post_new_area; 4 var $response_post_new = response_post_new; 5 $articleOuter_post_new.html(''); 6 $articleOuter_post_new.html( $response_post_new ); 7 })
↓次のように変更し、投稿されたslugからその記事にアクセスするようにしました。これが「Ajaxの中にAjax」という処理です。これは適切な方法ですか?
jQuery
1 // 成功したとき 2 .done(function( response_post_new ) { 3 $.ajax({ 4 type: 'GET', 5 url: 'http://example.com/post/'+response_post_new, 6 dataType: 'html' 7 }) 8 .done(function(data) { 9 var contentItems = $(data).find('.container'); 10 $('.container').html(contentItems); 11 }) 12 .fail(function () { 13 alert('失敗しました。'); 14 }); 15 })
こちらの「Ajaxの中にAjax」という方法でも、投稿後にその内容を表示できたことはできたのですが、、不安が残ります。
他にもおかしな点がございましたらご指摘頂けますと幸いです。(nonceのチェック方法や変数名など、とにかく独学で不安です。)
質問は以上です。
改めまして、どうぞ宜しくお願い致します。
補足情報(FW/ツールのバージョンなど)
使っているものは全て最新です。
Wordpress → 5.0.3
PHP → 7.3.2