wp_publish_post() Does Not Set post_*

The inline documentation for wp_publish_post() says that it will:

Publish a post by transitioning the post status.

and that’s exactly what it does. Moreover, that’s all it does.

If you are creating a draft post via wp_insert_post() (or wp_update_post(), which calls wp_insert_post()), certain defaults will be set for you when the post status is set to publish (or future, etc.). Among these is the automatic creation of the post_name from the post_title (if none has been explicitly provided) and setting post_date_gmt.

I had some code on my site that was hitting a service to get data, creating a draft, adding some meta data and taxonomy information, then publishing it. When I was initially doing this (and using wp_publish_post() instead of wp_update_post()), I was ending up with published, unnamed posts. Not what I had in mind.

There are two ways around this:

  1. Use wp_update_post() instead of wp_publish_post(). This works fine, but it’s a little heavier, and conceptually I think the code reads better with the wp_publish_post() call instead.
  2. Use wp_publish_post(), but make sure to set the post_name, post_date_gmt, etc. when you create your draft post via wp_insert_post().

For what it’s worth, I was using wp_update_post(), switched to wp_publish_post() because it seemed cleaner, and have since gone back to wp_update_post(). Using less of my own code and letting WordPress core code do more work for me feels more future-proof.

Hopefully this is useful to someone else who starts digging through the code and is having trouble deciding which of the various functions to use.