I would like to make sure no email address is published in plain. So i developed a plugin that replace all email addresses by a spambot-safe alternative.

But some users put their email address in their blog header, outside the post loop. How can i capture and filter that?

This works:

        add_filter('the_content', array(&$this,"pep_replace"));
        add_filter('the_excerpt', array(&$this,"pep_replace_excerpt"));
        add_filter('the_comments', array(&$this,"pep_replace"));

This does not (it does not capture the email address i've added in my test theme header.php file).

add_filter('template',  array(&$this,"pep_replace"));
add_filter('wp_head',  array(&$this,"pep_replace"));
add_filter('shutdown',  array(&$this,"pep_replace"));

I'm digging into the hook documentation, but i'm out of ideas on what could be the right filter hook. Thank you for your time.

2 Answers 2


You can't protect against everything a user will do. What if they hard-code an email address in the footer/header/sidebar of their theme? The only way to capture and escape that is with output buffering ... and that can become a performance nightmare.

My recommendation would be to do two things:

  1. Hook in to all of the places that make sense.
  2. Provide accessible functions that allow people to escape their own content.

You've already got step 1 pretty much covered. Email addresses most often appear in post content (the_content and the_excerpt) but might also appear in comments. I would also recommend filtering the title and the content of sidebar widgets:

add_filter('the_title', array(&$this,"pep_replace"));
add_filter('widget_content', array(&$this,"pep_replace"));

For step 2, document a generic function that people can use to sanitize their email addresses:

function sanitize_email( $email ) {
    // do stuff
    return $sanitized_email;

Users can then use this rather than hardcoding their email address:

<p>Please contact me at <?php echo sanitize_email( '[email protected]' ); ?>.</p>

If you weren't already filtering the_content, I'd recommend you create a shortcode as well ... but that's a bit redundant.

Be very careful

The other three hooks you've listed aren't actually filters - these are action hooks. They're meant to be places in code where you can hook in your own logical methods. Unlike filters, they don't return anything to PHP ... so they're pretty meaningless when used as filters.

  • Thank you very much for the thorough and speedy answer. I was getting to the same conclusion: controlling the output, which is not wise given the wide WP ecosystem. I have therefore followed your advises and provided a safe_email() function. Thank you!!
    – pixeline
    May 21, 2012 at 22:10
  • If you are interested, you can find the plugin here wordpress.org/extend/plugins/pixelines-email-protector
    – pixeline
    May 21, 2012 at 22:40

Manual method:

add_action('wp_loaded', 'buffer_start');    function buffer_start() { ob_start("myy_callback"); }
add_action('shutdown', 'buffer_end');       function buffer_end()   { ob_end_flush(); }

function myy_callback($buffer) {
  // modify buffer here, and then return the updated code
  $buffer = str_replace('MERCEDES','FERRARI',$buffer);
  return $buffer;

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.