Skip to content

Instantly share code, notes, and snippets.

@tanakahisateru
Created June 9, 2011 11:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanakahisateru/1016531 to your computer and use it in GitHub Desktop.
Save tanakahisateru/1016531 to your computer and use it in GitHub Desktop.
PHPTAL's attribute extension test
<?php
/*
* This is PHPTAL's attribute extension test.
* pal:content-nl2br : replaces newline to <br/>
* pal:replace-nl2br : replaces newline to <br/>
* pal:attr : shorter version of tal:attributes
* and adds context variable includes original attributes
* named as "attr" inside the tag.
*/
require_once 'PHPTAL.php';
class MyFw_PAL_Namespace extends PHPTAL_Namespace
{
public function __construct()
{
// namespace
parent::__construct('pal', 'http://myfw/ns/pal');
// attributes in namescape
$this->addAttribute(new PHPTAL_NamespaceAttributeContent('content-nl2br', 11));
$this->addAttribute(new PHPTAL_NamespaceAttributeReplace('replace-nl2br', 9));
$this->addAttribute(new PHPTAL_NamespaceAttributeSurround('attr', 9));
}
public function createAttributeHandler(PHPTAL_NamespaceAttribute $att, PHPTAL_Dom_Element $tag, $expression)
{
$attrNames = array(
'content-nl2br' => 'MyFw_PAL_ContentNl2br',
'replace-nl2br' => 'MyFw_PAL_ReplaceNl2br',
'attr' => 'MyFw_PAL_Attr',
);
$class = $attrNames[$att->getLocalName()];
return new $class($tag, $expression);
}
}
// attributes def
class MyFw_PAL_ContentNl2br extends PHPTAL_Php_Attribute_TAL_Content {
protected function doEchoAttribute(PHPTAL_Php_CodeWriter $codewriter, $code)
{
if ($code !== "''") {
if ($this->_echoType === self::ECHO_TEXT) {
$codewriter->flush();
$codewriter->pushCode('echo nl2br('.$codewriter->escapeCode($code).')');
}
else {
$codewriter->pushCode('echo nl2br('.$codewriter->stringifyCode($codewriter->interpolateHTML($code)).')');
}
}
}
}
class MyFw_PAL_ReplaceNl2br extends PHPTAL_Php_Attribute_TAL_Replace {
protected function doEchoAttribute(PHPTAL_Php_CodeWriter $codewriter, $code)
{
if ($code !== "''") {
if ($this->_echoType === self::ECHO_TEXT) {
$codewriter->flush();
$codewriter->pushCode('echo nl2br('.$codewriter->escapeCode($code).')');
}
else {
$codewriter->pushCode('echo nl2br('.$this->stringifyCode($this->interpolateHTML($code)).')');
}
}
}
}
class MyFw_PAL_Attr extends PHPTAL_Php_Attribute_TAL_Attributes {
public function before(PHPTAL_Php_CodeWriter $codewriter)
{
// prepare
$codewriter->pushCode('if(isset($ctx->attr)){$_pal_attr_bak=$ctx->attr;}');
$codewriter->doSetVar('$ctx->attr', 'array()');
$attrs = $this->phpelement->getAttributeNodes();
foreach ($attrs as $attr) {
$qname = $attr->getQualifiedName();
$default_attr = $attr->getValueEscaped();
$codewriter->doSetVar('$ctx->attr[\'' . $qname . '\']', '\''. addcslashes($default_attr, "\\$\'\"\\\0\n\r\t") . '\'');
}
// main
parent::before($codewriter);
// cleanup
$codewriter->pushCode('unset($ctx->attr)');
$codewriter->pushCode('if(isset($_pal_attr_bak)){$ctx->attr=$_pal_attr_bak;unset($_pal_attr_bak);}');
}
}
PHPTAL_Dom_Defs::getInstance()->registerNamespace(new MyFw_PAL_Namespace());
// test
$tpl = new PHPTAL();
$tpl->setPhpCodeDestination(".");
$tpl->setForceReparse(true);
$src = <<<EOT
<html>
<body>
<p id="p1-unexpected" tal:content="text_w_nl">foo</p>
<p id="p2-too-long" tal:content="structure php:nl2br(htmlspecialchars(text_w_nl))">foo</p>
<p id="p3-expected" pal:content-nl2br="text_w_nl">foo</p>
<p id="p4-markdown-like" pal:content-nl2br="structure text_w_nl">foo</p>
<div>
<span pal:replace-nl2br="text_w_nl">foo</span>
</div>
<a href="prev.html" pal:attr="href string:\${urlprefix}\${attr/href}">prev</a>
<a href="next.html" pal:attr="href string:\${urlprefix}\${attr/href}">next</a>
<script src="util.js" type="text/js" pal:attr="
src string:\${urlprefix}js/\${attr/src};
type php:str_replace('js', 'javascript', attr['type']);
"></script>
</body>
</html>
EOT;
$tpl->setSource($src);
$tpl->text_w_nl = "line 1\n<b>line 2</b>";
$tpl->urlprefix = "/base/";
try {
$tpl->echoExecute();
}
catch(Exception $ex) {
echo $ex->getMessage();
}
echo "\n";
// result
/*
<html>
<body>
<p id="p1-unexpected">line 1
&lt;b&gt;line 2&lt;/b&gt;</p>
<p id="p2-too-long">line 1<br />
&lt;b&gt;line 2&lt;/b&gt;</p>
<p id="p3-expected">line 1<br />
&lt;b&gt;line 2&lt;/b&gt;</p>
<p id="p4-markdown-like">line 1<br />
<b>line 2</b></p>
<div>
line 1<br />
&lt;b&gt;line 2&lt;/b&gt;
</div>
<a href="/base/prev.html">prev</a>
<a href="/base/next.html">next</a>
<script src="/base/js/util.js" type="text/javascript"></script>
</body>
</html>
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment