WordPress で承認フローを作成する場合、「Peter’s Collaboration E-mails」と「User Role Editor」の2つのプラグインを組み合わせる方法が、多くのブログ等で紹介されています。その基本は「Peter’s Collaboration E-mails」で承認者を設定して、寄稿者が投稿した際に承認者にメールで通知されるようにし、「User Role Editor」では、寄稿者にファイルのアップロード権限を付けたり、独自のロールを作成したりするというものです。

今回、承認フローが必要な案件があり、上記のプラグインを導入して実装しました。さらに「Peter’s Post Notes」プラグインも導入して承認依頼や差し戻しの際のメールにコメントを追加できるようにしました。

しかし、これだけでは実現できないことがありました。それは、公開中のページを差し替える場合の承認フローです。ページを公開したままの状態で、寄稿者が内容を修正して承認待ちとし、承認者が確認してページを差し替えるという流れが必要ですが、WordPress には差し替え用のページを作る機能はありませんので、公開中のページは修正した流れで即更新することになります。また、そもそも寄稿者は公開中のページを編集することができません。「User Role Editor」で寄稿者に公開中のページを編集する権限を付けることは可能ですが、そうすると、そのまま更新するこも可能になってしまいます。

そこで、「Revisionary」と「WP Post Branches」という2種類のプラグインを試してみました。機能としては「Revisionary」がマッチしていますが、機能が特化している故に様々な問題があり、最終的に「WP Post Branches」を使い、不足する機能を他のプラグインや設定で補うことで、目的のフローを実装することができました。

まず「Revisionary」プラグインを使ってみました。

このプラグインの機能はまさに求めていたそのもので、導入するだけで寄稿者に公開中のページを編集する権限が付与されます。プラグインの中に承認フローを持っているので寄稿者に更新の権限はありません。寄稿者が公開中のページを修正してレビュー待ちとして送信すると、修正前のページを公開したままで修正後のページが承認待ちの状態になります。次に承認者が承認待ちのページを公開すると、修正後のページに差し替わります。

すんなりとこれで実装できたかに思えたのですが、いろいろと検証していく中で、3つの問題に遭遇しました。

1つは承認メールの重複です。「Revisionary」プラグイン自身に承認メールの送信機能があるため、「Peter’s Collaboration E-mails」による承認メールと合わせて2通送信されます。「Revisionary」の設定でメールを送らないようにすることもできるのですが、「Peter’s Collaboration E-mails」によるページ差し替えの承認メールには、承認用の URL の記載がありません。

2つ目はカスタムフィールドに対応していないということです。公開中のページを修正してレビュー待ちとして送信するところまでは問題ないのですが、承認者が承認待ちのページを確認しようとした場合、編集画面はタイトルと本文欄だけでカスタムフィールドが表示されません。

3つ目はプレビュー画面にテンプレート階層が適用されないということです。編集画面でカスタムフィールドが見えないので、プレビュー画面で確認しようとすると、無条件に single.php が適用されるのか、投稿タイプや特定の固定ページに設定してあるテンプレートが適用されず、やはりカスタムフィールドの内容を確認することができません。

カスタムフィールドで実装したコンテンツの修正内容を確認できないのは致命的で、非常に簡単に導入できたのですが、これでは使えません。

次に「WP Post Branches」プラグインを使ってみました。

このプラグインは公開中のページを複製して修正用のページを作り、複製したページを公開すると公開中のページが複製したページに上書きされるというものです。

「Revisionary」のように承認メールを送信する機能はありませんし、独自の編集画面やプレビュー画面を持たないので、前述のような問題はありません。複製したページは通常のページと同様の編集画面を使用するので、承認メールは「Peter’s Collaboration E-mails」で問題なく送信されます。

ですが、「Revisionary」のような承認フローはありませんので、別途寄稿者に公開中のページを編集する権限を与える必要があります。これは冒頭で書いたように「User Role Editor」で寄稿者に対し、「edit_published_pages」や「edit_published_posts」あるいは「edit_published_(カスタム投稿タイプ)」を有効にすることで権限を付与することができます。

画像:User Role Editor の設定画面

しかし、この権限を与えると、冒頭で書いたように寄稿者がそのまま更新するこも可能になってしまいます。

そこで、寄稿者に対して公開中のページは[更新]ボタンを表示しないようにしました。以下を function.php に記述します。(参考:WordPress管理画面 ロールによって『公開』ボタンを制御

if (!current_user_can('publish_pages')) {  // ページの公開権限がないユーザー
  add_action('admin_print_styles', 'admin_preview_css_custom');
  function admin_preview_css_custom() {
    [ここから削除]global $post;
    $ID = $post->ID;[ここまで削除]
    [ここから追記]$ID = get_post($post)->ID;[ここまで追記]
    if(empty($ID))return;   // update post
    $post = get_post($ID);  // 現POST情報
    if($post->post_status == 'publish'){
      echo '<style>input#publish {display: none;}</style>';
    }
  }
}

これで思い通りの承認フローが完成しました。

  1. 公開中のページの編集画面で[ブランチを作る]ボタンを押す。寄稿者は更新することはできない。
    画像:公開中のページの編集画面
  2. 修正用のページ(ブランチ)が作成され、寄稿者は編集後レビュー待ちとして送信する。
    画像:作成された修正用ページの編集画面
  3. 承認者が公開すると、公開中のページが差し替わる。
    画像:承認者の修正したページの編集画面

承認フローまでは必要なくても、「WP Post Branches」プラグインを使えば、公開中のページを公開したまま修正して下書き保存しておくこともできますので、他のサイトでも標準的に導入してもいいかなと思います。

(1月14日追記)
寄稿者に対して公開中のページは[更新]ボタンを表示しないようにする記述ですが、新規投稿の際のタイトルがデフォルトで「自動下書き」と入力された状態になってしまいました。因果関係はよくわかりませんが、global $post; が影響しているようでしたので、一部変更しました。