WordPressの記事保存(更新)時に記事ファイルを作成する

WordPressのアクションフックの話なので特に説明も何もないんですが備忘録して。
今回の趣旨はマニュアルや資料をWordpressを使ってコンテンツを整理しておきたく、また資料はmdで保存しておきたいというのがありました。このブログもそうですが、手順書やマニュアルといったものは過去の履歴を含めて保存しておきたいのですが、Wordpressのリビジョン機能は履歴のバージョン管理ではないので、厳密な管理ができない。ですのでファイルで出力しておいてWordpressのコンテンツごとファイルでその履歴を管理してやろうという魂胆です。バックアップにもなる。
また今回はMarkdown変換のプラグインにJP Markdownを利用しています。

WordPressの記事保存時のアクションフック

フック自体はpublish_postです。publish_post
ですので、基本形はこんな感じになります。記事のIDを付与して保存・更新の際に処理をしてあげます。

function save_file($post_id){
  // ファイルを作成して保存する処理
  return true;
}
add_action('publish_post', 'save_file', 1 ,6);

保存時の処理と同時に記事削除時の処理も書いてあげる必要があります。trashed_postになります。似たようなフックでtrash_postというのがありますが、これは記事がゴミ箱に移動しつつある際のフックです。(アラートとかそういうのに使えそうです)実際にゴミ箱に移動が完了した際のフックは以下になります。

function trash_file($post_id){
  // ファイルを削除する処理
  return true;
}
add_action('trashed_post', 'trash_file', 1 ,6);

記事の内容をファイルに書き込む

記事の内容は

$post = get_post($post_id);
$post->post_content;

で取り出せます。この場合Markdownの記述がすでにHTMLに変換された状態で出力されます。Markdown記述そのものを保存したい場合は、$post->post_content_filtered;で取り出すことができます。(これはその他のプラグインなどを通した状態のものを取り出すことができます。)
ここまでで最低限必要な要素は揃っているので、あとはデータをmdで保存すればいいだけになります。
ああ、ちゃんとプラグインにしたい。

function saveFilePost($post_id) {
    $post = get_post($post_id);

    /* ディレクトリの作成 */
    $category = get_the_category($post->ID);
    $save_dir = $_SERVER['DOCUMENT_ROOT'].'/../postfiles/'.$category[0]->slug;
    if (!file_exists($save_dir)) {
      mkdir($save_dir, 0777, true);
    }
    // $post->post_content_filtered : Markdown format
    // $post_content : HTML format
    $post_content = $post->post_content_filtered;
    $post_file = $save_dir.'/'.urldecode($post->post_name).'.md';
    $fp = fopen($post_file, "w") or die("Unable to open file! Check permission".$post_file);
    flock($fp, LOCK_EX);
    fputs($fp, $post_content);
    flock($fp, LOCK_UN);
    fclose($fp);

    // ここでカスタムフィールドなどでコミットコメントをつけて
    // 自動的にコミットするようにするのがよい。
    // ログもほしい monolog
    return;
}
add_action('publish_post', 'saveFilePost', 1 ,6);


function trash_file($post_id){
  $post = get_post($post_id);
  $category = get_the_category($post->ID);
  $save_dir = $_SERVER['DOCUMENT_ROOT'].'/../postfiles/'.$category[0]->slug;
  /*
  trash_file()内でpost_nameを取得すると__trashedというpostfixがつくので、削除する
  */
  $file_name = preg_replace("/__trashed/","",$post->post_name);
  $post_file = $save_dir.'/'.urldecode($file_name).'.md';
  @unlink($post_file);

  /* ディレクトリ内にファイルが一つもなかったらディレクトリは削除 */
  // 未実装

  // ここでカスタムフィールドなどでコミットコメントをつけて
  // 自動的にコミットするようにするのがよい。
  // ログもほしい monolog
  return;
}
add_action('trashed_post', 'trash_file', 1 ,6);
Last update: 2019.01.07 (月)