How to Bulk Create Multiple Posts At Once
In this tutorial, I intend to show you how to bulk create multiple posts and pages at once in WordPress. We’re going to do that without using any WordPress plugins. So, if you are looking for a plugin solution, this post is probably not what you need.
However, we’re only going to bulk create multiple posts within a single WordPress website. It means, that if you need to bulk copy posts between different sites, you would probably need to take a look at my Simple WP Crossposting plugin (or Simple Multisite Crossposting if you’re working with a WordPress Multisite network).
As for this post, I will show you how to add a button “Generate posts” to the “All posts” or “All pages” page, and when we click that button, multiple posts will be created at one click:

Now, let’s get started.
1. Create a “Generate Posts” Button in the Admin Interface
First things first, let’s add a button because I don’t want to give you a half-ready code which is confusing in terms of where to use it. In other words, we need an interface!
The question is – which WordPress action hook to use to add a button? We can’t use the restrict_manage_posts one, because it will add our button inside a posts filter form (before the “Filter” button) which is not what we need. Luckily, there is another action hook that suits us perfectly – manage_posts_extra_tablenav.
Let’s try it out:
<?php
add_action( 'manage_posts_extra_tablenav', function( $which ) {
if( 'top' !== $which ) {
return;
}
printf(
'<a href="%s" class="button">Generate Posts</a>',
wp_nonce_url(
add_query_arg(
array(
'action' => 'generate_posts',
),
admin_url( 'admin-post.php' )
),
'rudr_generate_posts'
)
);
} );
add_action( 'admin_post_generate_posts', function() {
// check nonces
check_admin_referer( 'rudr_generate_posts' );
//
// a function to bulk create multiple posts goes here
// rudr_bulk_create_multiple_posts();
//
// redirect back to the posts page
wp_safe_redirect(
add_query_arg(
array(
'posts-generated' => true
),
admin_url( 'edit.php' )
)
);
exit;
} );
add_action( 'admin_notices', function() {
if( empty( $_REQUEST[ 'posts-generated' ] ) ) {
return;
}
?>
<div class="notice notice-success is-dismissible">
<p>Multiple posts have been created successfully.</p>
</div>
<?php
} );And it works, though it doesn’t create any posts yet:

A couple of things I’d like to highlight in the code above:
- The
$whichargument of themanage_posts_extra_tablenavhook can have two values –topandbutton, and we check this argument because I would like to display our button only at the top, before the posts table. - To process the button click I’m using a standard WordPress
admin_post_{$action}hook. - After we finish bulk creating posts, we redirect back to the “All posts” page and display a message that multiple posts have been created successfully.
As simple as that.
2. Create Multiple Posts at Once with a PHP Function
The question here is – should we use the wp_insert_post() function for that purpose? This function does a lot of things, so maybe a faster way will be INSERT INTO SQL query?
And what I think here is while wp_insert_post() could be slower than a single SQL query, the things this function does are helpful indeed:
- You will have simpler code, especially, in cases, when you need to add categories and metadata to posts.
- If you have some plugins running on your site, you can be sure they will be compatible with newly created posts (because the
save_posthook is fired correctly and all that).
Ok, let’s dive into a simple example:
function rudr_bulk_create_multiple_posts( $number_of_posts = 10 ) {
for( $i = 0; $i < $number_of_posts; $i++ ) {
wp_insert_post(
array(
'post_title' => 'Article ' . ( $i + 1 ),
'post_content' => 'Some content',
'post_status' => 'draft'
)
);
}
}The result of combining this function with the code above:

In case you decide to run this code without the interface I provided you before, please make sure not to run the wp_insert_post() function straight inside the functions.php file, because it is too early and the function isn’t initialized.
Another example – how to create multiple posts using a list of titles:
function rudr_bulk_create_multiple_posts() {
$titles = array(
'Where to work with a laptop in Kuala Lumpur?',
'Coffee Guide to Yerevan',
'Surfing in Sri Lanka',
'How to bulk publish posts with the WordPress REST API'
);
foreach( $titles as $title ) {
wp_insert_post(
array(
'post_title' => $title,
'post_status' => 'publish', // let's publish posts immediately
)
);
}
}Then we will have a new list of published posts. It seems quite easy, doesn’t it?

Last but not least, let’s make our example a bit more interesting, to do so we will try to add categories, tags, and custom fields to our posts.
$articles = array(
array(
'title' => 'Where to work with a laptop in Kuala Lumpur?',
'city' => 'Kuala Lumpur',
),
array(
'title' => 'Coffee Guide to Yerevan',
'city' => 'Yerevan',
),
array(
'title' => 'Surfing in Sri Lanka',
'city' => 'Weligama',
),
array(
'title' => 'How to bulk publish posts with the WordPress REST API',
),
);
foreach( $articles as $article ) {
$article_id = wp_insert_post(
array(
'post_title' => $article[ 'title' ],
'post_status' => 'publish',
)
);
if( ! empty( $article[ 'city' ] ) ) {
update_post_meta( $article_id, 'city', $article[ 'city' ] );
wp_set_post_terms( $article_id, 'travel', 'post_tag' );
}
}3. Using Custom Content Sources
Using lorem ipsum generators to bulk create multiple posts in WordPress
Let’s now create multiple posts but generate either post content or excerpts with the help of any Lorem Ipsum generator API. I decided to use this one dinoipsum.com it seems not boring.
I am going to use a modified version of the first example here.
function rudr_bulk_create_multiple_posts( $number_of_dinosaurus = 5 ) {
for( $i = 0; $i < $number_of_dinosaurus; $i++ ) {
$request = wp_remote_get(
add_query_arg(
array(
'format' => 'text',
'paragraphs' => 1,
'words' => 15,
),
'https://dinoipsum.com/api/'
)
);
if( 'OK' !== wp_remote_retrieve_response_message( $request ) ) {
continue;
}
wp_insert_post(
array(
'post_title' => 'Dinosaur ' . ( $i + 1 ),
'post_excerpt' => wp_remote_retrieve_body( $request ),
)
);
}
}The only thing I would like to highlight is that it is probably better to run one HTTP request to Lorem Ipsum generate and then split the content between all the posts that we want to bulk create. Actually, it is what I am doing in the next chapter about ChatGPT.
But for now, here is the result:

Using Open AI API (ChatGPT)
But what is the point of using lorem ipsum content if we can use AI-generated content now? Let’s find it out.
In the example below, I will use the Open AI API. Of course, first of all, you have to sign up there and create an API key. Let’s ask Open AI to generate 5 titles about dinosaurs, we are going to use them as our post titles.
$text = 'Write 5 taglines about dinosaurs.';
$password = 'API KEY IS HERE';
$chatgpt_request = wp_remote_post(
'https://api.openai.com/v1/chat/completions',
array(
'timeout' => 30,
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $password
),
'body' => json_encode(
array(
'model' => 'gpt-3.5-turbo',
'messages' => array(
array(
'role' => 'user',
'content' => $text
),
),
'temperature' => 0.7 // randomeness
)
)
)
);
if( 'OK' === wp_remote_retrieve_response_message( $chatgpt_request ) ) {
$body = json_decode( wp_remote_retrieve_body( $chatgpt_request ) );
// by default we have it in a format like
// 1. "First title"
// 2. "Second title"
// 3. ...
// let's do some formatting
$titles = array_map(
function( $choice_text ) {
if( preg_match( '/"([^"]+)"/', $choice_text, $c ) ) {
return $c[1];
}
},
explode( "\n", trim( $body->choices[0]->message->content ) )
);
foreach( $titles as $title ) {
wp_insert_post(
array(
'post_title' => $title
)
);
}
}- As you can see, there is nothing fancy here, I am just using the WordPress HTTP API to make a request to the Open AI API and to process the result from there.
- On line
7I set'timeout' => 30, which is extremely important because today Open AI API is kind of slow, so we have to let our HTTP request wait for the result. - The code on lines
31-43probably is waiting for improvement because I just made some quick formatting to convert the Open AI response into an array of titles that we can use aswp_insert_post()argument.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Hi Misha!
Thank you for your interesting article.
If I want to include a link to an image, I could add an tag to the “content” field?
Is there a way I could set this as a ‘featured_image’?
Thanks again, Tony
Thanks for your article, Misha!
I’m wondering where exactly you place the code above?
functions.php? If so, what hook are you using?
Thanks for a hint!
Hi,
If you insert it to
functions.php, then the posts are going to be generated on every page refresh 🙃You can use the code examples in your custom function and then connect it to the UI, for example.
How to create with post thumbnail?
Thanks