PHPTAL is a templating engine for PHP5 that implements brilliant Zope Page Templates syntax:
<div class="item" tal:repeat="item itemsArray">
<span tal:condition="item/hasDate" tal:replace="item/getDate"/>
<a href="${item/getUrl}" tal:content="item/getTitle"/>
<p tal:content="value/getContent"/>
</div>
PHPTAL is fast thanks to compiled templates and fine-grained caching. Makes it easy to generate well-formed XML/XHTML (protected against XSS attacks). PHPTAL's code is mature and improving. Released free under LGPL.
See the introduction.
require_once and switched to autoloading.try/catch or other handler set.
PHPTAL's handler ensures appropriate HTTP status is set and information is not leaked when display_errors is off.i18n:translate (patch by Daniel Trebbien)Work in progress:
In the meantime, last stable version is still great. If you prefer cutting edge, you can checkout latest not-as-stable SVN version.
On a different note, Per Bernhardt shared his story how he tortured designers before switching to PHPTAL ;)
New addPreFilter() method and PHPTAL_PreFilter base class for filters.
PHPTAL->stripComments() has been implemented as a prefilter. It's smarter now – won't remove contents of comments in <script>.<pre> and supports xml:space="preserve".Old setPreFilter() still works, but hasn't gained any new features.
echoExecute() method for outputting result without buffering.metal:define-slot uses lazy callbacks to avoid buffering.<?xml-stylesheet?> used with PHP short tags (<?) enabled.Dj Gas has supplied CHM build of the English manual. You can now enjoy searchable reference off-line!
Download tarball or ZIP.
<![CDATA[ blocks are added automatically where needed for compatibility with text/html and escaping is CDATA-aware.DOCTYPE is automatically changed to <!DOCTYPE html> and namespace declarations/prefixes are omitted.Instructions for alpha version still apply.
To help you find possible incompatibilities and syntax errors there's phptal_lint.sh script. Install PHPTAL 1.2.0 first (PHPTAL.php must be in include_path, or you'll need to modify the script) and then execute:
chmod a+x phptal_lint.sh ./phptal_lint.sh /path/to/your/templates/directory/
You'll get information which templates failed to parse. Please note that this tool is not 100% accurate, because it does not know about your custom modifiers and prefilters. If your templates require these, you'll need to test them yourself.
New look, bigger text, wider columns, better typography, syntax coloring. Please send complaints/compliments to the mailing list.
A big thanks goes to Levi Stanley from ENE Services LLC who has donated phptal.org domain to the project!
Fresh alpha package. Changes since last one:
PHPTAL_DIR is gone. PHPTAL now temporarily modifies include_path.
DOM-related classes and methods renamed once again.
Re-added few basic methods and properties for compatibility with custom attributes written for older PHPTAL versions.
GetTextTranslator sets locale's LC_MESSAGES only when LC_ALL doesn't work. This way you don't need full locale installed on the system to use gettext() (you should, however). setLanguage() now returns language that has been set.
XML namespace of phptal:* attributes has changed from http://xml.zope.org/namespaces/phptal to http://phptal.org/ns/phptal.
' entity is better supported.
Lots, lots of code formatting changes and doc comments for conformance with PEAR coding standards.
Fixed variable redefinition bug reported by Ciprian Vieru.
Fixed parsing of code with class constants and dynamic property names in php: expressions (bug reported by Bobby).
This is alpha release (don't use it on live sites!). It includes long overdue fixes to XML parser and PHPTAL's internals which may require some cosmetic changes to templates. Please test it and report problems and bugs you find.
The biggest difference is in handling of entities. Entities are now unescaped before passing to expressions, i.e. ${php:strlen('"')} “sees” just the quote character and returns 1. In previous versions entities were passed as-is to the expressions (and that example would return 6).
Newly added unescaping of entities can expose encoding bugs. Make sure your pages declare document encoding:
Content-Type:application/xhtml+xml;charset=UTF-8 or Content-Type:text/html;charset=UTF-8 HTTP headers (here's how.)text/xml MIME type, use application/xml instead.<meta> tag or send Content-Type:text/html;charset=UTF-8 HTTP header.If you're not using UTF-8 encoding, you must set encoding you use via $phptal->setEncoding('ISO-8859-…') (or just switch to UTF-8 already! :)
Only some 8-bit-based encodings are supported. If your encoding is not supported, you may get away with setting ISO-8859-1 instead.
All constants except PHPTAL_VERSION have been removed. Remove any PHPTAL-specific define()s and use class methods for configuration (e.g. $phptal->setPhpCodeDestination('/tmp/phptal/') for custom temp directory.)
Don't include any PHPTAL's files before including PHPTAL.php.
Fixed many quirks related to handling of entities in TALES expressions.
Fixed escaping in CDATA sections: special characters won't be changed to entities, </ and ]]> will be escaped appropriately for output mode used.
Improved XML namespace support. PHPTAL now rejects invalid prefixes and uses namespace URIs internally.
Comments are required to be well-formed (-- is not allowed in comments.)
HTML5 output mode. There's a bit of controversy around HTML5, so let me be clear: this doesn't allow “tagsoup”. PHPTAL still requires templates to be well-formed XML, and the output aims to be clean and conforming HTML5 text/html syntax.
HTML5 output mode is optional and enabled by $phptal->setOutputMode(PHPTAL::HTML5). The default output mode is compatible with XHTML/1.x and XHTML5.
Ability to add source resolvers. You can easily implement a fake filesystem that e.g. reads templates from the database. This is better than simply using $phptal->setSource(), because it allows external macros to work.
Comments starting with <!--! are stripped from output.
${} behaves more like tal:content="".tal:repeat doesn't “leak” variables to outer scope (bug reported by Richard Cernava.)Tetsuya Mito has kindly provided Japanese translation of the PHPTAL manual.
$gotchas--;
PHPTAL::setForceReparse() to temporarily disable caching.)Filter.php before using filters.PHPTAL_Exception.This release improves speed and reliability of PHPTAL. Most notably:
NULL value of attribute added via tal:attributes now omits entire attribute in most cases (no more class=""!)tal:repeat uses Iterator class exactly the same way foreach() (fixes problem reported by Stas Dovgodko)repeat/…/length is read lazily,-' in external and dynamic macro names (bug spotted by Anton),tal:omit-tag executes condition only once,${…} syntax.Tomek Pęszor wrote nice tutorial on integration of PHPTAL with the Zend Framework and started repository of PHPTAL filters.
This release brings sane handling of non-ASCII characters in gettext translation keys. If you use PHPTAL's i18n features and have non-ASCII characters in translation keys (e.g. your application's native language is other than English), you may need to upgrade your .po files or enable backward compatibility mode (see notes below).
Changes:
setCanonicalize(true) method of PHPTAL_GetTextTranslator enables old behaviour.PHPTAL_TranslationService now requires implementation of setEncoding() method. See manual.structure keyword in i18n:translate, which disables escaping of XML entities, allowing use of XHTML in translation strings.__call can now throw BadMethodCallException when they don't handle called method, allowing PHPTAL to handle this gracefully.tal:define “feature” that caused empty elements to be omitted.In 1.1.13 translation key like <p i18n:translate="'żółw'" /> was interpreted as <p i18n:translate="'<C197><C188><C195><C179><C197><C130>w'"> and you had to use msgid "<C197><C188><C195><C179><C197><C130>w" in your .po files.
PHPTAL 1.1.14 stops doing this and keys are now left unchanged. The example above would simply expect msgid "żółw" in the .po file.
If you don't want to change your .po files and want to keep old behaviour, then call setCanonicalize(true) of PHPTAL_GetTextTranslator, e.g.:
$translator = new PHPTAL_GetTextTranslator();
$translator->setLanguage(…);
$translator->setCanonicalize(true); // add this line
$phptal->setTranslator($translator);
To upgrade templates, change <Cxxx> back to bytes. This code snippet will do it:
preg_replace('/<C(\d+)>/e','chr("\1")',$po_file_content)
Eine von Axel Zöllich betreute, deutsche Übersetzung des Handbuchs ist verfügbar.
(Axel Zöllich is working on German translation of the manual!)
During August London Web Standards Meetup I gave presentation about PHPTAL.
The presentation is available for download in Apple Keynote and PDF formats.
<tal:block> element.tal:attributes and tal:define.__isset/__get (problem reported by Anru Chen)New RepeatController by Iván “DrSlump” Montes:
letter and roman properties,first and last properties,PHPTAL is now easier to use as part of a framework or a plug-in:
PHPTAL_DIR constant (it's defined automatically). This makes it easier to use multiple copies of PHPTAL, and eliminates need for include_path.$t = PHPTAL::create('index.xhtml')
->setPhpCodeDestination('application/tmp/')
->setPhpCodeExtension('tmp')
->setForceReparse(true)
->set('title', 'My Title')
->set('heading', 'My Heading');These changes are backwards-compatible: PEAR installations are unaffected, configuration constants are still supported.
Handy feature, less bugs.
nothing or NULL as last alternative in tal:attributes will cause attribute to be omitted entirely,sys_get_temp_dir() does not include trailing slash,Hello! My name is Kornel Lesiński and I'm the new maintaner of PHPTAL.
The latest release adds more robust error handling and integrates PHPTAL a bit better with PHP SPL:
Countable and ArrayAccess SPL interfaces,php: TALES expressions,sys_get_temp_dir() . If this causes trouble, you can override it using define('PHPTAL_PHP_CODE_DESTINATION','/tmp/');PHPTAL_Exception.pear upgrade http://phptal.org/latest.tar.gz
Applied patch from Kornel Lesinski
phptal:cache that caches HTML of any given tag,phptal_tale() which returns chained TAL expressions as a single PHP expression. It's equivalent to phptal_tales(), but can be used in more contexts (i.e. ${foo | bar}),metal:fill-block can fill blocks in parent contexts,Other svn pending fixes:
php:$foo expression which is evaluated to php:${foo} equals $ctx->{$ctx->foo}.As announced on the mailing like I don't have the time to maintain PHPTAL anymore, Kornel Lesinski kindly proposed himself to take the head of the project and we will plan the hand over during the following weeks. It was a pleasure to give this library to the community!
Thanks to all PHPTAL users, Laurent Bedubourg
pear upgrade http://phptal.org/latest.tar.gz
Fix and patch release
tal:repeat patch from Moritz Bechlertales registry patch from Moritz Bechler${structure foo} and ${string:hello world}setTemplate() reset existing prepared template (but not the context)true: modifier supportstructure support to tal:attributespear upgrade http://phptal.org/latest.tar.gz
The 1.1.4 testing is stable and was improved :
PHPTAL_CommentFilter as a simple and useful demonstration filterPHPTAL_PHP_CODE_EXTENSION constant based on William Bailey proposalMyClass.myStatic: custom expression modifiers (patch from William Bailey)local and global keywords
Important: tal:define now fully support global and local take a quick look at the manual for tal:define usage...
pear upgrade http://phptal.org/latest.tar.gz
Many thanks to Dan Sheppard.
The 1.1 branch has finally been released, here are some changes :
global local keywords to tal:definestring: not interpolatedchecked="checked")pear upgrade http://phptal.org/testing.tar.gz
The latest phptal download link was broken and linked to 1.0.9 release, this is now fixed.
pear upgrade http://phptal.org/latest.tar.gz
__toString() methoditem/repeat/odd may require an update)tal:content, tal:replace and tal:attributes chained expression now ignores null, false and ''<!-- --> comments were evaluating ${foo}$${foo} were evaluated inside text nodesfilemtime() warning when using setSource() with no pathpear upgrade http://phptal.org/latest.tar.gz
use-macro and define-macro appear in the same tag, slots are shared between macros to allow macro inheritancePHPTAL::stripComments($bool) which removes xml comments during parsingThe next release will include many refactorings which will allow coders to "easily" insert their own namespaces and attributes into PHPTAL.
Pupeno's (Jose Pablo Ezequiel Fernandez Silva) second article was published on the april 2005 issue of php|architect.
This article explains common PHPTALES usage and goes deep into websites internationalisation using PHPTAL and gettext.
array/0 paths (patch from William Bailey)PHPTAL::setSource($src, $path=false)tal:attributes and zero values errorThe new PHPTAL for PHP5 manual is available. Corrections, remarks and translations are welcome (join the mailing list).
Pupeno's (Jose Pablo Ezequiel Fernandez Silva) first article about PHPTAL was published on the issue 3, volume 4 of php|architect.
This article introduces PHPTAL and explains most common TAL attributes with some good examples.
More articles should follow in next issues concerning advanced PHPTAL usage in daily applications.