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…