wp_insert_post breaks rewrite rules

I’m using wp_insert_post to programmatically add content to a site. This works fine with posts, categories and tags, but not with pages.

When I attempt to add a page (i.e. post with post_type=page), the rewrite rules do not get properly regenerated (or something happens to them after wp_insert_post). Specifically, rules related to category and tag urls get lost, as listed below:

Read More
[category/(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
[category/(.+?)/(feed|rdf|rss|rss2|atom)/?$] => index.php?category_name=$matches[1]&feed=$matches[2]
[category/(.+?)/page/?([0-9]{1,})/?$] => index.php?category_name=$matches[1]&paged=$matches[2]
[category/(.+?)/?$] => index.php?category_name=$matches[1]
[tag/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$] => index.php?tag=$matches[1]&feed=$matches[2]
[tag/([^/]+)/(feed|rdf|rss|rss2|atom)/?$] => index.php?tag=$matches[1]&feed=$matches[2]

…etc

This means that tag and category archive urls get broken. Just clicking on Settings > Permalinks will repair them. Have tried to fix by using $wp_rewrite->flush_rules() immediately after wp_insert_post but this has not fixed the problem…

Related posts

Leave a Reply

2 comments

  1. Hard to say what your issue is without seeing more code, but I would bet that your issue will be resolved if you add this after inserting your post:

    do_action('save_post', $post_ID, $post);
    

    WordPress uses this action to flush cache, rewrite rules, etc. Make sure to use the appropriate variables for $post_ID and $post, of course. For good measure, you should also add:

    do_action('wp_insert_post', $post_ID, $post);
    

    Just so any plugins, themes, etc. which use this hook will know to do whatever it is they do.

    Cheers~

  2. I’ve encountered the same issue I think. I was using wp_insert_post in an ajax callback. The post_name field was getting blanked out. I eventually traced it back to calling wp_publish_post shortly there after. I commented out the publish and set post_status prior to insert and it all worked better.