投稿前に確認ダイアログを出す
Wordpressで投稿をする時、通常は日時を変えなければ投稿と同時に即時公開状態になる。
が、予約投稿がメインで、なおかつ公開と同時にSNSに共有するというようなサイトの場合、「日付を変え忘れて即時投稿になっちゃった☆彡」はちょっと困る。(特に企業向けのサイトの場合)
デフォルトの投稿時刻設定を現在時刻+1時間とかにできないかなあとも考えたけれど、例えば投稿画面を1時間放置してたら意味ないし...ってことで、色々考えた結果、
・投稿ボタンを押した時に確認ダイアログを表示
・確認ダイアログに公開予定時刻を表示
という感じにしてみることにした。
ブラウザの確認ダイアログを出す
同じことをやろうとしている先人がいたので、とりあえずそのまま実装。
お手軽で、もうこれでいいかなーと思っていたんだけど、このダイアログ、表示時にフォーカスされているボタンが「OK」ボタンのため、勢い余ってEnterキーとか押しちゃうと、さらっとスルーできてしまう。それじゃあ意味ない。
ちょっと調べてみたけどこのフォーカスを変更する術は無い模様。
となると、自前でキャンセルボタンがフォーカスされているウィンドウを作るしかない。
jQuery UIのdialogを使う
どうせ管理画面だから、デザインなんかも気にする必要は無い。
ってなわけで、Wordpressには標準でjQuery UIが同梱されているので、それを使う。
dialogウィジェットを有効にするには、functions.phpに下記の呪文を追加。
wp_enqueue_script('jquery-ui-dialog'); wp_enqueue_style("wp-jquery-ui-dialog");
で、ウィンドウの表示は先人の知恵を借りつつ、下記のように書いてみた。
function pre_post_dialog () { echo <<< EOF <script> jQuery(document).ready(function($) { var dialog_box = $('<div>'), publish_btn = $('#publish'), dialog_id = 'confirm_dialog'; dialog_box.attr('id', dialog_id); dialog_box.appendTo('body'); $('#' + dialog_id).hide(); function show_confirm_dialog() { var msg = '<strong style="font-size:15px;">' + $('#aa').val() + '年' + $('#mm').val() + '月' + $('#jj').val() + '日 ' + $('#hh').val() + '時' + $('#mn').val() + '分</strong><br>' + '記事を<strong>「' + $('#publish').val() + '」</strong>しても宜しいですか?'; $('#' + dialog_id).html(msg); $('#' + dialog_id).dialog({ modal: true, title: '投稿確認', buttons: { 'キャンセル': function() { $(this).dialog('close'); return false; }, 'OK': function() { $('#post').trigger('submit'); $(this).dialog('close'); } } }); return false; } publish_btn.on('click', show_confirm_dialog); }); </script> EOF; } add_action('admin_head-post.php', 'pre_post_dialog'); add_action('admin_head-post-new.php', 'pre_post_dialog');
上記で動いて完成!・・・かと思いきや、思わぬ罠があった。
「公開」ボタンを押しても、何故か「下書き」状態にしかならない。
「公開」状態にできないのを修正
推測ですが、恐らく公開ボタンをreturn falseしているせいで、イベントが消失。
しかし消失したイベントの中に、記事の状態を「公開」にするための設定があったんでしょう。
というわけで、確認画面表示用の別の投稿ボタンを用意して、ダイアログ内のOKを押されたら元の#publishボタンが押される、という処理に変えてみた。
jQuery(document).ready(function($) { var dialog_box = $('<div>'), publish_btn = $('#publish'), dialog_id = 'confirm_dialog', confirm_btn = publish_btn.clone(); // 投稿ボタンの設定。元のボタンは隠しておく confirm_btn.attr('id', 'confirm_btn'); publish_btn.hide(); publish_btn.after(confirm_btn); dialog_box.attr('id', dialog_id); dialog_box.appendTo('body'); $('#' + dialog_id).hide(); function show_confirm_dialog() { var msg = '<strong style="font-size:15px;">' + $('#aa').val() + '年' + $('#mm').val() + '月' + $('#jj').val() + '日 ' + $('#hh').val() + '時' + $('#mn').val() + '分</strong><br>' + '記事を<strong>「' + $('#publish').val() + '」</strong>しても宜しいですか?'; $('#' + dialog_id).html(msg); $('#' + dialog_id).dialog({ modal: true, title: '投稿確認', buttons: { 'キャンセル': function() { $(this).dialog('close'); return false; }, 'OK': function() { publish_btn.trigger('click'); $(this).dialog('close'); } } }); return false; } confirm_btn.click(show_confirm_dialog); // 日付や記事の状態を変えた時に、ボタンのvalueが変わるように。 // setTimeoutしないとうまく切り変わらない。。。 $('#submitdiv a.button').on('click', function() { setTimeout(function() { confirm_btn.val($('#publish').val()); }, 1); }); });
まとめ
「公開」状態にできないバグはかなり悩んだので、管理画面のボタンをいじるときは細心の注意が必要(当たり前
デフォルトのイベントは殺してはいけない。
これもうちょっと頑張れば、投稿前のプレビューウィンドウとかにできそう。