0

I want to be able to hook into the output buffer flow and add some conditional content to my WP pages.

What I want to do is test cookies and display a semi-transparent screen with a content box based on a cookies' condition.

I know how to construct the html and css to make this happen. I know how write the php to test cookies.

What I don't know is what add_filter() or what add_action() to use to make this hook in my functions.php file.

Can anyone provide direction or point me to the codex? I am just not sure what search arguments to use when I look at the codex.

Thanks

AMENDED

Here is what I want to accomplish:

I want the following to be added to each and every page on my site, regardless whether the page exists today. If I add a new page in the future, I want this to appear as well. (I wil handle all styling and positioning, etc. myself).

<div>something to display</div>

3 Answers 3

1

You can use this class to buffer and filter any output coming from specific hook, or between two hooks.

class HookBuffer {
    private static $buffers = [];
    private $buffer_name = '';
    private $buffer = '';
    private $buffer_status = 'waiting';
    private $priority1;
    private $priority2;
    private $tag1;
    private $tag2;
    private $output=FALSE;
    public function __construct( $buffer_name, $tag1='', $tag2='' ) {
        if ( !( function_exists( 'add_action' ) 
            &&  function_exists( 'remove_action' ) )
            || self::buffer_exists( $buffer_name ) ) {
            throw new Exception;
        }
        $this->buffer_name = (string)$buffer_name;
        $this->tag1 = (string)$tag1;
        $this->tag2 = (string)$tag2;
        $this->init();
        self::$buffers[$buffer_name] = $this;
    }

    public static function buffer_exists( $buffer_name ) {
        return array_key_exists((string)$buffer_name, self::$buffers);
    }

    public static function buffer_ready( $buffer_name ) {
        $b = self::b( (string)$buffer_name );
        return ( $b !== FALSE && $b->get_status() === 'finished' ) ? TRUE : FALSE;
    }

    public static function b( $buffer_name ) {
        $buffer_name = (string)$buffer_name;
        return self::buffer_exists($buffer_name) ? 
                self::$buffers[$buffer_name] : FALSE;
    }

    private function init() {
        $tag1 = $this->tag1;
        $tag2 = $this->tag2;
        if ( $tag1 ) {
            if ( $tag2 ) {
                $this->add_actions( 'last', 'first' );
            } else {
                $this->tag2 = $tag1;
                $this->add_actions( 'first', 'last' );
            }
        } else {
            if ( $tag2 ) {
                $this->tag1 = NULL;
                $this->add_actions( NULL, 'first' );
                $this->start_buffering( );
            } else {
                return;
            }
        }
    }

    private function init_priorities( $position1, $position2 ) {
        if ( $position1 === 'first' ) {
            $this->priority1 = -9999;
        } elseif ( $position1 === 'last' ) {
            $this->priority1 = 9999;
        } else {
            $this->priority1 = NULL;
        }

        if ( $position2 === 'first' ) {
            $this->priority2 = -9999    ;
        } elseif ( $position2 === 'last' ) {
            $this->priority2 = 9999;
        } else {
            $this->priority2 = NULL;
        }
    }

    private function add_actions( $position1, $position2 ) {

        $this->init_priorities($position1, $position2);

        if ( $this->tag1 ) {
            add_action( 
                $this->tag1,
                [ $this, 'start_buffering' ],
                $this->priority1 );
        }
        if ( $this->tag2 ) {
            add_action(
                $this->tag2, 
                [ $this, 'stop_buffering' ],
                $this->priority2 );
        }
        return $this;
    }

    public function start_buffering( ) {
        if ( $this->get_status() === 'waiting' ) {
            $this->buffer_status = 'buffering';
            ob_start();
        }   
        return $this;
    }

    public function stop_buffering( ) {
        if ( $this->get_status() === 'buffering' ) {
            $this->buffer = ob_get_contents();
            ob_end_clean();
            $this->buffer_status = 'finished';
            $this->remove_actions();
            if ( $this->output ) {
                $this->output();
            }
        }
        return $this;
    }

    public function get_status() {
        return $this->buffer_status;
    }

    public function get() {
        return $this->get_status() === 'finished' ? $this->filter() : FALSE;
    }

    protected function filter() {
        return $this->buffer;
    }

    public function output() {
        if ( $this->get_status() === 'finished' ) {
            echo $this->get();
        } else {
            $this->output = TRUE;
        }
        return $this;
    }

    private function remove_actions() {
        remove_action( 
                $this->tag1,
                [ $this, 'start_buffering' ],
                $this->priority1 );
        remove_action(
                $this->tag2, 
                [ $this, 'stop_buffering' ],
                $this->priority2 );
        return $this;
    }
}

You could use it like this:

class MyHookBuffer extends HookBuffer {
    protected function filter() {
        $buffer = $this->buffer;
        // Here you can modify the $buffer
        return $buffer;
    }
} 
(new MyHookBuffer('all_html','template_redirect','shutdown'))->output();
0

Use the action template_redirect. You can still send headers here, be cause there is no output. This is called on front-end only.

add_action( 'template_redirect', function() 
{
    // send headers, call ob_start()
});
2
  • @H.Ferrence No, you have to start an output buffer or find an action that happens in the page after <body>.
    – fuxia
    Commented Oct 12, 2013 at 12:33
  • @H.Ferrence Where exactly do you want to show the new content?
    – fuxia
    Commented Oct 12, 2013 at 12:35
0

You are using the phrase "output buffer" in a confusing way. PHP does not "buffer" output by default. You build strings and echo them. If you want output buffering, you need to start and stop it yourself, but you don't "hook" into it. PHP doesn't have "hooks". That is a WordPress feature.

I think that what you are doing is close to what WordPress does with the admin bar at the top of the screen for logged in users. What WordPress does is hook into wp_footer and print the admin bar content. CSS then positions it at the top of the page.

You should probably do something much like that, though you may need more (aka Javascript) than just CSS to get things the way you want.

1
  • Yes, that is right. Hook your function to wp_footer just like in the comment above. I believe you have an extra { though.
    – s_ha_dum
    Commented Oct 12, 2013 at 15:12

Your Answer

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