Sunday, September 26, 2021

wp_insert_post: How to Create New Posts in WordPress

Programmatic WordPress Post Creation

WordPress is used to manage everything from complex sites to casual blogs. While WordPress’s built-in editor suffices for most applications, there are times when you need to create more complex posts or create them in bulk. For those jobs, it might be more economical to write code to take care of the post creation for you. You might think that you have to be some kind of PHP expert to create new posts without destroying what’s already there, but as we’ll see here today, WordPress provides several functions to do all of the heavy lifting for you.

Creating the New Post

In WordPress new posts (and pages) are created using the wp_insert_post() function. It accepts a mandatory array of post information as well as the option $wp_error boolean. When set to false or omitted, wp_insert_post() returns the new ID on success or zero on failure. Setting $wp_error to true causes the function to return a WP_Error object if it fails.

The wp_insert_post() function’s simple signature masks the number of input arguments. I won’t list every one of them here because they are all listed and explained in the WordPress docs. What does bear stating here is that very few of them are required. To illustrate, here is all the code required to create a post with nothing but a title and content:

$my_post = array(
  'post_title'    => 'Post Title',
  'post_content'  => 'Post Content...'
$new_post_id = wp_insert_post( $my_post );
if ($new_post_id == 0) {
    echo 'Could not create the post.';
else {
    echo 'New post created.';

Usually, new post creation will entail more details. The following $args array is what I used to create new restaurant posts. Some of the properties are explicitly being set to their defaults just to give you a sense of what the other attributes are. Special care was taken to create the posts under the restaurant account owner’s ID as well as create a meaningful post_name (slug):

$baseName = 'HintonBurger';
$location = 'Westboro, Richmond rd.';
$restaurant_owner_id = 62;
$args = array(
  'comment_status' => 'closed',
  'ping_status'    => 'closed',
  'post_author'    => $restaurant_owner_id,
  'post_content'   => '',
  'post_excerpt'   => '',
  'post_name'      => strtolower(preg_replace("/[^A-Za-z]/", '', $baseName)  . ' - ' . preg_replace("/[^A-Za-z]/", '', $location)),
  'post_parent'    => 0,
  'post_password'  => '',
  'post_status'    => 'publish',
  'post_title'     => $baseName . ' - ' . $location,
  'post_type'      => 'restaurant',
  'menu_order'     => 0
$new_post_id = wp_insert_post( $args );

Setting Object Terms and Taxonomies

A term and taxonomy type (tag, category, etc) may be related to a post object using the wp_set_object_terms() function. It accepts four input parameters as follows:

Name Required? Type Description
$object_id Yes int The post ID to relate to.
$terms Yes array/int/string The slug or id of the term (such as category or tag IDs), will replace all existing related terms for this taxonomy. To clear or remove all terms from an object, pass an empty string or NULL. Integers are interpreted as tag IDs. Be aware that some functions may return term_ids as strings which will be interpreted as slugs consisting of numeric characters!
$taxonomy Yes array/string The context in which to relate the term to the object. This can be category, post_tag, or the name of another taxonomy.
$append No bool If true, tags will be appended to the object. If false, tags will replace existing tags. False by default.

The Restaurant Menu site that I’ve been working on has a taxonomy called Cuisines containing a list of food types that apply to the restaurant. For instance, HintonBurger above has cuisines of ‘burgers’, ‘fast food’, and ‘diner’. These are added via the wp_set_object_terms() function one at a time as a for loop iterates over the array elements. The $cuisines array could be passed directly to the function if it contained IDs and not the description.

$cuisines = array('burgers', 'fast food', 'diner');
for ($c=0; $c<count($cuisines); $c++) {
           wp_set_object_terms($new_post_id, trim($cuisines[$c]), 'cuisines', true);

Adding Custom Fields

Custom fields may be appended using either the add_post_meta() or update_post_meta() function. In most cases, update_post_meta() will suffice because will make sure that $meta_key already exists on the $post_id. Otherwise, it calls add_post_meta($post_id, $meta_key, $meta_value) instead anyway. Like wp_set_object_terms(), update_post_meta() also accepts four input parameters:

Name Required? Type Description
$post_id Yes integer The ID of the post which contains the custom field.
$meta_key Yes string The key of the custom field.
$meta_value Yes mixed The new value of the custom field. A passed array will be serialized into a string.
$prev_value No mixed The old value of the custom field you wish to change. This is to differentiate between several fields with the same key. If omitted, and there are multiple rows for this post and meta key, all meta values will be updated.

Returns the meta_id if the meta doesn’t exist, otherwise it returns true on success and false on failure. It also returns false if the value submitted is the same as the value that is already in the database.

Here are some examples:

update_post_meta($new_post_id, 'shop_number', $shop_no);
update_post_meta($new_post_id, 'address', $address);
update_post_meta($new_post_id, 'address_town', $town);
update_post_meta($new_post_id, 'address_postcode', $postcode);
update_post_meta($new_post_id, 'phone_number', $phone_number);
update_post_meta($new_post_id, 'url', $websiteUrl);
update_post_meta($new_post_id, 'latitude', $latitude);
update_post_meta($new_post_id, 'longitude', $longitude);           

echo 'New restaurant created.';


The functions presented here today provide all of the functionality you’ll need to create posts, taxonomies, and custom fields. Just be sure to check that a post already exists, unless you don’t care if it’s overwritten. Call get_page_by_title( $post_title ). As long as it returns null, you’re in business!

Rob Gravelle
Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.

Popular Articles