Programmatic WordPress Post Creation

By Rob Gravelle

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:

$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:

$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 resides in Ottawa, Canada, and is the founder of GravelleWebDesign.com. Rob has built systems for Intelligence-related organizations such as Canada Border Services, CSIS as well as for numerous commercial businesses.

In his spare time, Rob has become an accomplished guitar player, and has released several CDs. His band, Ivory Knight, was rated as one Canada's top hard rock and metal groups by Brave Words magazine (issue #92).

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
Thanks for your registration, follow us on our social networks to keep up-to-date