プログラムで固定ページを作成する

プログラムでページを作る方法を知っておいたほうがなにかと便利なんで、そのやり方です。

wp_insert_post関数について

引数

  • $postarr: [必須] 配列。
  • $wp_error: [オプション] ブール値。 デフォルトはfalse。エラー時に int:0 ではなく WP_Error型のインタンスを返してほしいときは、true を指定します。

戻り値

  • 成功:
    • int: 投稿IDが返却されます
  • 失敗:
    • int: 0 (第2引数で false を指定している時)
    • WP_Error: 第2引数で true を指定している時は、WP_Errorインスタンスがエラー内容を保持したオブジェクトとして返却されます。
      • WP_Error型を受け取りたいケースとしては、より詳細なエラーメッセージを取得して、失敗原因を特定しやすくするためです。
      • 例えば、 post_title、 post_content、 post_excerpt が全て空っぽのときは、 new WP_Error( 'empty_content', __( 'Content, title, and excerpt are empty.' ) ); といったエラーオブジェクトが戻ってきます。

使用例

実行して確認

例によって WP-CLI で実行しています。
debugオプションを有効にしておくと、スクリプトにエラーが有ったときにスタックトレースを出力してくれます。

こんな風に post の内容が出力されましたんで、うまくいっているみたい。

wp_insert_post 関数のポイント

  • 最初の引数の配列で ID を指定すると その対象のpostを、指定した内容で update します。 ID 指定しなければ insert になります。
  • また、関数の最初の引数の配列のデフォルト値は以下のようになっています。
    • $defaults = array(
      'post_author' => $user_id,
      'post_content' => '',
      'post_content_filtered' => '',
      'post_title' => '',
      'post_excerpt' => '',
      'post_status' => 'draft',
      'post_type' => 'post',
      'comment_status' => '',
      'ping_status' => '',
      'post_password' => '',
      'to_ping' => '',
      'pinged' => '',
      'post_parent' => 0,
      'menu_order' => 0,
      'guid' => '',
      'import_id' => 0,
      'context' => '',
      );
  • post_author を指定しないときは、 get_current_user_id() の結果$user_idが入ります。
  • デフォルトのキー以外に、 post_categorypost_datepost_date_gmtpost_mime_type を指定することもできます。
  • attachmentの登録/更新としても使えますが、別途用意されている wp_insert_attachment関数 を使うほうが自然でしょう。
  • 投稿/ページのアップデート用には wp_update_post 関数があります。

使い所

固定ページに依存するようなプラグインを作る場合に、register_activation_hookを使って、あらかじめ固定ページを用意するときに便利です。例えばWooCommerceでは幾つかの固定ページを予め作成するため、このwp_insert_post関数を使っています。ただ、この関数は500行ほどあるので、一括で大量にページを作るような処理(バルク処理)には時間がかかるため向いてないです。その場合は、素直にSQLを直接実行するようにしたほうがよいでしょう。

wp_insert_post関数実行にともなって発行されるSQL

以下は、wp_insert_post関数で発行されるSQLです。参考までに。

  • SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = ‘test-page1’ AND wp_posts.ID NOT IN (0) AND wp_posts.post_type IN (‘post’, ‘page’, ‘attachment’) AND ((wp_posts.post_status = ‘trash’)) ORDER BY wp_posts.post_date DESC
  • SELECT post_name FROM wp_posts WHERE post_name = ‘test-page1’ AND post_type IN ( ‘page’, ‘attachment’ ) AND ID != 0 AND post_parent = 0 LIMIT 1
  • SHOW FULL COLUMNS FROM wp_posts
  • INSERT INTO wp_posts (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid) VALUES (1, ‘2017-03-15 08:15:57’, ‘2017-03-14 23:15:57’, ‘テストページ1の内容です。’, ‘テストページ1の内容です。’, ‘テストページ1’, ”, ‘publish’, ‘page’, ‘closed’, ‘closed’, ”, ‘test-page1’, ”, ”, ‘2017-03-15 08:15:57’, ‘2017-03-14 23:15:57’, 0, 0, ”, ”)
    • DBに登録しているところです。
  • SELECT * FROM wp_posts WHERE ID = 347 LIMIT 1
  • UPDATE wp_posts SET guid = ‘http://wpwand.com/test-page1/’ WHERE ID = 347
  • SELECT * FROM wp_posts WHERE ID = 347 LIMIT 1
  • SELECT autoload FROM wp_options WHERE option_name = ‘_transient_is_multi_author’
  • SHOW FULL COLUMNS FROM wp_options
  • UPDATE wp_options SET option_value = ‘0’ WHERE option_name = ‘fresh_site’
  • SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (347) ORDER BY meta_id ASC
  • SELECT meta_id FROM wp_postmeta WHERE meta_key = ‘_wpcom_is_markdown’ AND post_id = 347
  • SHOW FULL COLUMNS FROM wp_postmeta
  • INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (347, ‘_mykey1’, ‘1’)
    • postmetaも登録させることができる。

関連フック(action/filter)

  • apply_filters( ‘wp_insert_post_empty_content’, $maybe_empty, $postarr )
    • ページ内容が空っぽのときにエラーにするかどうか?あるいは、そのときに何か処理を付け加えるためのフィルター
  • array_filter( $postarr[‘post_category’] );
    • カテゴリーを処理する

もっと知るには?

この関数の定義場所は、 wp-includes/post.php なので一度ソースに読んでみるのがよいと思います。

Filed under: WordPressの応用

No comment yet, add your voice below!


Add a Comment

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください