I would like to run a filter on post content after it has been created or updated.

I would like this to occur after the user has submitted the post, as it may be a bit of a lengthy process (a find/replace to search for glossary terms and replace them with links).

What's the most efficient and reliable way to achieve this?

Thanks in advance,

  • 1
    Does this have to occur immediately on publish? Or could it occur...say...once every hour or something like that? – mor7ifer Feb 17 '12 at 15:26
  • That would be absolutely fine :) – dunc Feb 17 '12 at 15:44

Alright, here's some code I just whipped up. Completely untested, just wrote it right off the cuff...so don't expect it to work 100% when you drop it in, but the core concept is there, as is a decent amount of the legwork

add_action( 'my_filter_posts_content', 'my_filter_content' );
add_action( 'save_post', 'my_set_content_filter' );

if( !wp_next_scheduled( 'my_filter_posts_content' ) ) {
    wp_schedule_event( time(), 'hourly', 'my_filter_posts_content' );

function my_filter_content() {
    //check to see if posts need to be parsed
    if( get_option( 'my_updated_posts' ) == false )
        return false;

    //parse posts
    $ids = unserialize( get_option( 'my_updated_posts' ) );
    foreach( $ids as $v ) {
        YOUR_FUNCTION_HERE( $v );

    //make sure no values have been added while loop was running
    $id_recheck = unserialize( get_option( 'my_updated_posts' ) );
    my_close_out_filter( $ids, $id_recheck );

    once all options, including any added during the running of what
    could be a long cronjob are done, remove the value and close out
    delete_option( 'my_updated_posts' );
    return true;

function my_set_content_filter( $post_id ) {
    //get the previous value
    $ids = unserialize( get_option( 'my_updated_posts' ) );

    //add new value if necessary
    if( !in_array( $post_id, $ids ) ) {
        $ids[] = $post_id;
        update_option( 'my_updated_posts', serialize( $ids ) );

function my_close_out_filter( $beginning_array, $end_array ) {
    $diff = array_diff( $beginning_array, $end_array );
    if( !empty ( $diff ) ) {
        foreach( $diff as $v ) {
            YOUR_FUNCTION_HERE( $v );
    my_close_out_filter( $end_array, unserialize( get_option( 'my_updated_posts' ) ) );
| improve this answer | |
  • Thanks for that, I'll give it a go now. Is YOUR_FUNCTION_HERE( $v ); where I'd put my filtering code? – dunc Feb 17 '12 at 16:17
  • Yup, you've got it...let me know how that works, I'm interested as to what stupid error(s) I made :D – mor7ifer Feb 17 '12 at 16:19
  • You know...thinking about it, I bet you could do some pretty powerful filtering if you based a class off that code... – mor7ifer Feb 17 '12 at 16:23
  • One thing.. how do I go about seeing whether or not the cron job has actually been scheduled? – dunc Feb 17 '12 at 16:26
  • 1
    There are plugins that will do that for you, I think Cron View is the one that I use, but I cannot remember. – mor7ifer Feb 17 '12 at 16:44

Please see my answer here. It's a proof-of-concept for running a native crontab in Linux with your WP installation.

As for WP-Cron functionality, beware of these caveats:

  • WP-Cron is a pseudo cron that is runs when WP is loaded. WP checks if a WP-Cron is scheduled or behind schedule to run and then executes the cron script.
  • If there is not adequate traffic, your cron might run really late.
  • Scheduling a WP-Cron to run during peak hours might cause some performance issues if it's a large, intensive script.

If you choose to go the WP-Cron route, here's a great article to show you how to use it. You can also check out the WP functions in the Codex here.

I prefer the reliability of a Linux crontab, especially for integral, heavy-weight cron scripts. For extremely lightweight scripts, I do use WP-Cron at times.

Hope this helps!

| improve this answer | |
  • Hi Brian. I was under the impression that WP had built-in features for setting up cron jobs? – dunc Feb 17 '12 at 16:15
  • 1
    Well, it's a psuedo-cron which depends on people visiting your site. It could create a performance issue for the unlucky user who hits your site when it's time to run the wp-cron. The more reliable approach to make sure the cron runs at scheduled intervals is to use crontab. You can see the wp-cron functions here: codex.wordpress.org/Category:WP-Cron_Functions – Brian Fegter Feb 17 '12 at 16:22
  • Thanks Brian. Site gets enough traffic (30,000 unique visitors/week) so I think we'll be OK in those terms. The script isn't absolutely massive and there'll very rarely be more than one post at a time updated. – dunc Feb 17 '12 at 16:33

Would the save_post action work for you?

add_action( 'save_post', 'wp_save_post' );
function wp_save_post()
    // do stuff

You might also consider edit_post or publish_post

You can view other actions in the Codex

| improve this answer | |
  • Hi Kyle. Thanks, I understand the workings of save_post :) What I'm trying to do is run this filter in the background. If I run the filter on save_post, it'll take quite some time for the post to save, which is an annoyance for my authors that I'd like to avoid. – dunc Feb 17 '12 at 16:09
  • Oh, gotcha. Didn't realize the background requirement. – Kyle Feb 17 '12 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.