1

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,

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

3 Answers 3

1

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' ) ) );
}
11
  • Thanks for that, I'll give it a go now. Is YOUR_FUNCTION_HERE( $v ); where I'd put my filtering code?
    – turbonerd
    Commented Feb 17, 2012 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
    Commented Feb 17, 2012 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
    Commented Feb 17, 2012 at 16:23
  • One thing.. how do I go about seeing whether or not the cron job has actually been scheduled?
    – turbonerd
    Commented Feb 17, 2012 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
    Commented Feb 17, 2012 at 16:44
1

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!

3
  • Hi Brian. I was under the impression that WP had built-in features for setting up cron jobs?
    – turbonerd
    Commented Feb 17, 2012 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 Commented Feb 17, 2012 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.
    – turbonerd
    Commented Feb 17, 2012 at 16:33
0

Would the save_post action work for you?

<?php
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

2
  • 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.
    – turbonerd
    Commented Feb 17, 2012 at 16:09
  • Oh, gotcha. Didn't realize the background requirement.
    – Kyle
    Commented Feb 17, 2012 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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