Prev |  | Next

## interface `PHPTAL_Trigger`

The `phptal:id` attribute was added into the PHPTAL for the PHP5 version to replace the old `PHPTAL_Cache` interface and to abstract it a little more.

When a `phptal:id` is reached, PHPTAL will look in its triggers list for a matching id and will invoke the trigger `start()` and `end()` methods before entering the element, and just after it.

If the `PHPTAL_Trigger::start()` method returns `PHPTAL_Trigger::SKIPTAG`, PHPTAL will ignore the element and its content ( `start()` may echo something to replace it).

If your trigger wants the element and its content to be executed, you'll have to return `PHPTAL_Trigger::PROCEED`.

The `PHPTAL_Trigger::end()` will be called after the element (whether it has been executed or not). This allows you to build cache systems using `ob_start()` in `start()` and `ob_get_contents()`, `ob_end_clean()` in `end()`.

              <html>
      …
      <div>
        …
        foo bar baz <span tal:replace="id"/> foo bar baz
        …
      </div>
      …
    </html>

For some reason we decide the `<div>` block requires to be cached. We introduce a `phptal:id` into the template:

              <html>
      …
      <div phptal:id="somePossiblyUniqueKeyword">
        …
        foo bar baz <span tal:replace="id"/> foo bar baz
        …
      </div>
      …
    </html>

Then we write our trigger which will cache the `<div>` content:

              <?php

    class CacheTrigger implements PhpTal\TriggerInterface
    {
        public function start($phptalid, $tpl)
        {
            // this cache depends on 'id' which must appears in
            // the template execution context
            $this->_cachePath = 'cache.' . $tpl->getContext()->id;

            // if already cached, read the cache and tell PHPTAL to
            // ignore the tag content
            if (file_exists($this->_cachePath)){
                $this->_usedCache = true;
                readfile($this->_cachePath);
                return self::SKIPTAG;
            }

            // no cache found, we start an output buffer and tell
            // PHPTAL to proceed (ie: execute the tag content)
            $this->_usedCache = false;
            ob_start();
            return self::PROCEED;
        }

        // Invoked after tag execution
        public function end($phptalid, $tpl)
        {
            // end of tag, if cached file used, do nothing
            if ($this->_usedCache){
                return;
            }

            // otherwise, get the content of the output buffer
            // and write it into the cache file for later usage
            $content = ob_get_contents();
            ob_end_clean();
            echo $content;

            $f = fopen($this->_cachePath, 'w');
            fwrite($f, $content);
            fclose($f);
        }

        private $_cachePath;
        private $_usedCache;
    }
    ?>

The key here is to return from `start()` with either `SKIPTAG` or `PROCEED`.

When `SKIPTAG` is returned, PHPTAL will just ignore the tag and call end(). This usually means that the trigger takes the hand in deciding what to show there.

When `PROCEED` is returned, PHPTAL will execute the tag and its content as usual, then call `end()`. This allows our cache class to play with output buffers to execute the tag once and to store the result in a file which will be used in later calls.

To install our trigger we use:

              <?php

    $trigger = new CacheTrigger();

    $tpl = new PhpTal\PHPTAL('test.xhtml');

    // this trigger will only be called for phptal:id="triggerId"
    $tpl->addTrigger('somePossiblyUniqueKeyword', $trigger);

    $tpl->id = 1;

    echo $tpl->execute();

    ?>

You can add as many triggers as you like to your templates. A generic cache trigger may also handle more than one `phptal:id`… etc…

Prev | Up | Next
interface `PHPTAL_Filter` | Home | interface `PHPTAL_TranslationService`