<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.aide-de-camp.org/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://fabien.potencier.org/">
  <title>Fabien Potencier</title>
  <link href="http://fabien.potencier.org/" />
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>

      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.aide-de-camp.org/aidedecamp" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="aidedecamp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
  <title>Symfony Live Conference, Symfony 2.0, and Dependency Injection</title>
  <link href="http://fabien.potencier.org/article/41/symfony-live-conference-symfony-2-0-and-dependency-injection" />
  <id>article-41</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2010-02-19T10:02:00+01:00</updated>
  <content type="html">
    &lt;p&gt;This has been an amazing week for me,
&lt;a href="http://www.symfony-project.org/"&gt;Symfony&lt;/a&gt;, and the whole Symfony community.
With more than 350 attendees coming from more than 30 countries, the Symfony
Live &lt;a href="http://www.symfony-live.com/"&gt;conference&lt;/a&gt; was a blast. I want to thank
all attendees, speakers, and the &lt;a href="http://www.sensiolabs.com/"&gt;Sensio Labs&lt;/a&gt;
team for coming to the conference and making it a truly fantastic event.&lt;/p&gt;

&lt;p&gt;If you have not attended the conference, you can still come to the Symfony
Live
&lt;a href="http://www.meetup.com/London-events-by-Boxlight-Media/calendar/12416585/"&gt;After-Party&lt;/a&gt;
next week in London. And don't miss Symfony
&lt;a href="http://www.symfonycamp.com/"&gt;Camp&lt;/a&gt; in June and Symfony
&lt;a href="http://www.symfonyday.com/en/"&gt;Day&lt;/a&gt; in October. If you live far away from
Europe, stay tuned as we have more exciting news to announce in the coming
weeks.&lt;/p&gt;

&lt;p&gt;The conference was also the occasion to unveil the first preview release of
the upcoming &lt;a href="http://www.symfony-reloaded.org/"&gt;Symfony 2&lt;/a&gt; framework. Since
then, the buzz has been great and I have already received a lot of good
comments on it. Of course, I hope that this is just the beginning, and that
more people will provide feedback.&lt;/p&gt;

&lt;h2&gt;On the PHP Community&lt;/h2&gt;

&lt;p&gt;I'm also very proud that people from so many different PHP "sub-communities"
attended the conference: Jon Wage (Doctrine project manager and lead developer of Doctrine 1.x), François
Zaninotto (lead developer of Propel), Nils Adermann (lead developer of PhpBB),
and of course, Matthew Weier O'Phinney (Zend Framework lead).&lt;/p&gt;

&lt;p&gt;I like to see the whole PHP community as a big unified group of developers
trying to promote the same platform. And I do my best to be a good "PHP
citizen". I try to innovate by adapting concepts from other languages. But I
also try to not reinvent the wheel when it's not mandatory. The symfony 1
framework uses a lot of third-party libraries like Propel and Doctrine. And
for Symfony 2, I'm proud to have replaced our own Logger and Cache system by
the equivalent components from the Zend Framework. And you can imagine that it
was not an easy decision to take. First, because it meant throwing away code
we have written and maintained for years. Then, because the Zend Framework is
our main competitor. But I'm sure we have made the right decision and Matthew
seems to have the same 
&lt;a href="http://weierophinney.net/matthew/archives/232-Symfony-Live-2010.html"&gt;point of view&lt;/a&gt;
 on that matter.&lt;/p&gt;

&lt;h2&gt;On PHP Frameworks&lt;/h2&gt;

&lt;p&gt;People are jealous, so jealous that it makes me really sad. For the last few
years, some PHP framework communities attempted to "kill" Symfony by trying to
demonstrate that it is too slow, too complex, and too bloated. Of course,
that's not true. And the number of
&lt;a href="http://answers.yahoo.com/"&gt;high&lt;/a&gt;-&lt;a href="http://delicious.com/"&gt;traffic&lt;/a&gt;
&lt;a href="http://www.dailymotion.com/"&gt;websites&lt;/a&gt; using symfony 1 speaks for us.&lt;/p&gt;

&lt;p&gt;I get inspiration from many different frameworks from many different
languages. Besides PHP projects, I like to follow the development of Django,
Spring, Rails, Maven, Jinja, Rack, Sinatra, and many others. I try to bring
innovation to the table. And for Symfony 2, I have tried to take into account
the major pain points of symfony 1. The truth is that Symfony 2.0 requires no
configuration. The truth is that Symfony 2 is really fast. Is it the fastest
framework? I don't care. It is probably fast enough for your next website, and
so is symfony 1.&lt;/p&gt;

&lt;p&gt;Now if some people cannot accept that Symfony 2 is really fast and if they
cannot accept that Symfony 2 is great step forward for PHP, that's sad. The
web evolves very fast. Competition is everywhere for PHP. We should all be in
the same boat.&lt;/p&gt;

&lt;p&gt;I would love if people from different framework communities can work together
more often, like what we have done with the PHP 5.3 interoperability group. I
would love if we can share more components. I would love to discuss how we can
make our PHP community grow faster.&lt;/p&gt;

&lt;p&gt;Is it a dream? I hope it's not. And I have a proposal. Let's organize an event
where several PHP framework communities can discuss and share ideas. Anyone?&lt;/p&gt;

&lt;h2&gt;On Dependency Injection&lt;/h2&gt;

&lt;p&gt;The biggest Symfony 2 innovation lies in its low level architecture. And its
flexibility and speed is mainly due to the Symfony Dependency Injection
Container component. Dependency Injection Containers are not widespread in the
PHP world, and I really think that this is a very good approach. That's why I
talk about Dependency Injection at conferences. Next time I will talk about
this topic is during the
&lt;a href="http://confoo.ca/en/2010/session/dependency-injection-in-php-5-2-and-5-3"&gt;ConFoo&lt;/a&gt;
conference in March.&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>The state of YAML in PHP</title>
  <link href="http://fabien.potencier.org/article/40/the-state-of-yaml-in-php" />
  <id>article-40</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-12-21T08:20:00+01:00</updated>
  <content type="html">
    &lt;div style="float: right; padding: 10px"&gt;
  &lt;img src="http://components.symfony-project.org/images/components/yaml/home.png" /&gt;
&lt;/div&gt;

&lt;p&gt;My first exposure to YAML was in 2001, back in the days when I was mainly
working with Perl. Well, I was not using YAML per se at that time, but rather
&lt;a href="http://search.cpan.org/~ingy/Data-Denter-0.15/Denter.pod"&gt;&lt;code&gt;Data::Denter&lt;/code&gt;&lt;/a&gt;, a
Perl library that provides data serialization/deserialization. I used this
library mainly for debugging purposes. From its documentation:&lt;/p&gt;

&lt;p&gt;"It formats nested data structures in an indented fashion. It is optimized
  for human readability/editability, safe deserialization, and (eventually)
  speed."&lt;/p&gt;

&lt;p&gt;At the end of the year 2002, the module was deprecated in favor of a new
serialization language, &lt;a href="http://yaml.org/"&gt;YAML&lt;/a&gt;, with the added bonus of
being programming language independent. I promptly switched to use the Perl
&lt;a href="http://search.cpan.org/~adamk/YAML-0.70/lib/YAML.pm"&gt;YAML&lt;/a&gt; module, and I
never looked back. I used YAML as a mean to debug my Perl programs, but I also
started to use it more and more to store configuration data.&lt;/p&gt;

&lt;p&gt;When I started to use PHP at the end of 2004, one of the first thing that
quickly bothered me was the poor support for YAML in the PHP world.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  By the way, if symfony uses YAML a lot, it has nothing to do with Ruby on
  Rails ;) It just happens that Ruby also has some Perl heritage!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;But first, what is YAML?&lt;/h2&gt;

&lt;p&gt;According to the official YAML website, YAML (YAML Ain't Markup Language), is
a &lt;strong&gt;human friendly&lt;/strong&gt; data serialization standard for &lt;strong&gt;all programming
languages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;YAML can be used to describe both simple and complex data structures. It's an
easy to learn language that describes data. As PHP, it has a syntax for simple
types like strings, booleans, floats, integers, arrays, and even more complex
ones like objects.&lt;/p&gt;

&lt;p&gt;Nowadays, YAML is a heavily used format for &lt;strong&gt;configuration files&lt;/strong&gt;, mainly
because even non programmers are able to understand and modify YAML files
easily.&lt;/p&gt;

&lt;p&gt;To sum up the benefits of YAML, I often say that &lt;strong&gt;YAML files are as
expressive as XML files and as readable as INI files&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  Since the creation of YAML, another lightweight data-interchange format has
  come to life: &lt;a href="http://json.org/"&gt;JSON&lt;/a&gt;. JSON is quite similar to YAML (and as
  a matter of fact, JSON is a subset of YAML); but even if it is easy for humans
  to read and write, I think it is not as readable as YAML, and a bit too
  verbose.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;YAML&lt;/h2&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  If you already know what is YAML and how to use it to describe your data
  structures, just skip this section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Besides strings, Booleans, and numbers, let's have a look at one of the
simplest configuration structure you can describe with YAML:&lt;/p&gt;

&lt;pre&gt;key: value
foo: bar
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;The above snippet is the simplest way to express key/value pairs in YAML. The
&lt;code&gt;foo&lt;/code&gt; key has a &lt;code&gt;bar&lt;/code&gt; value. The equivalent PHP code would be:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;a href="http://www.php.net/array"&gt;&lt;span class="kw3"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'key'&lt;/span&gt; =&amp;gt; &lt;span class="st0"&gt;'value'&lt;/span&gt;, &lt;span class="st0"&gt;'foo'&lt;/span&gt; =&amp;gt; &lt;span class="st0"&gt;'bar'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;And that's pretty much covers what you can do with ini files. Speaking of ini
files, you can also group key/values under "sections". Here is how this is
possible with YAML:&lt;/p&gt;

&lt;pre&gt;section1:
  foo: bar
&amp;nbsp;
section2:
  bar: foo
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;The equivalent PHP code reads as follows:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;a href="http://www.php.net/array"&gt;&lt;span class="kw3"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;
  &lt;span class="st0"&gt;'section1'&lt;/span&gt; =&amp;gt; &lt;a href="http://www.php.net/array"&gt;&lt;span class="kw3"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'foo'&lt;/span&gt; =&amp;gt; &lt;span class="st0"&gt;'bar'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,
  &lt;span class="st0"&gt;'section2'&lt;/span&gt; =&amp;gt; &lt;a href="http://www.php.net/array"&gt;&lt;span class="kw3"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'bar'&lt;/span&gt; =&amp;gt; &lt;span class="st0"&gt;'foo'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;,
&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;That does the trick because there is several ways to describe key/value pairs.
The short notation (&lt;code&gt;foo: bar&lt;/code&gt;), and the expanded one, where you use
indentation to describe nested structures as above.&lt;/p&gt;

&lt;p&gt;The same data structure can also be described as follows:&lt;/p&gt;

&lt;pre&gt;section1: { foo: bar }
section2: { bar: foo }
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;{}&lt;/code&gt; is how you enclose a hash. That's one of the greatest benefit of YAML
as a description format: you can &lt;strong&gt;visually organize&lt;/strong&gt; your data by using one
of the three possible notations.&lt;/p&gt;

&lt;p&gt;Unlike PHP, YAML makes a difference between hashes (mappings) and arrays
(sequences):&lt;/p&gt;

&lt;pre&gt;[1, 'a string', &amp;quot;another string&amp;quot;]
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;The above snippet, a YAML sequence, is the equivalent of the following PHP
code:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;a href="http://www.php.net/array"&gt;&lt;span class="kw3"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="nu0"&gt;1&lt;/span&gt;, &lt;span class="st0"&gt;'a string'&lt;/span&gt;, &lt;span class="st0"&gt;&amp;quot;another string&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;If you mix and match mappings and sequences, short and verbose notations, you
can describe very complex data structures:&lt;/p&gt;

&lt;pre&gt;section1:
  foo: { bar: foo }
  bar: [1, 2]
  foobar:
    - 'a string'
    - 'another one'
&amp;nbsp;&lt;/pre&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  This section has barely scratched the surface of what you can express with
  YAML. If you want to learn more, you will find plenty of
  &lt;a href="http://components.symfony-project.org/yaml/trunk/book/02-YAML"&gt;documentation&lt;/a&gt;
  on the Internet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;YAML in PHP&lt;/h2&gt;

&lt;p&gt;YAML is human-friendly, but not so developer-friendly for someone willing to
write a parser for it. The YAML specification is really huge. If you
&lt;a href="http://www.yaml.org/spec/1.2/spec.html"&gt;read&lt;/a&gt; it carefully, you can easily
imagine that writing a YAML parser is not an easy task. As I mainly use YAML
as a configuration format like many other developers, I'm more looking for a
fast, incomplete but correct library, instead of a fat, spec-compliant one.&lt;/p&gt;

&lt;p&gt;Back in 2005, I was looking for such a YAML parser and dumper for PHP. Chris
&lt;a href="http://ozmm.org/"&gt;Wanstrath&lt;/a&gt;, who will eventually create
&lt;a href="http://github.com/"&gt;Github&lt;/a&gt; some years later, wrote one such limited parser
and dumper, &lt;a href="http://code.google.com/p/spyc/"&gt;Spyc&lt;/a&gt;, specifically to be used as
a simple configuration library.&lt;/p&gt;

&lt;p&gt;I used it for &lt;a href="http://symfony-project.org/"&gt;symfony&lt;/a&gt; 1.0. I fixed some bugs
from time to time, but as time passed, I found many limitations and became
more and more frustrated about it. One day, I eventually decided to write a
more robust and stable YAML parser and dumper for symfony.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  Since then, Alexey Zakhlestin created a
  &lt;a href="http://pecl.php.net/package/syck"&gt;PECL&lt;/a&gt; extension that wraps the Syck
  library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the beginning of 2009, I decided to release this library as a standalone
library, with no dependency whatsoever. It means that you can start using it
&lt;a href="http://components.symfony-project.org/yaml/"&gt;today&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;The YAML Symfony Component&lt;/h2&gt;

&lt;p&gt;Released under the MIT license, the YAML Symfony Component can be used in any
application, even commercial ones.&lt;/p&gt;

&lt;p&gt;When I created this YAML library for PHP, I had several goals in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Ease of use&lt;/em&gt;: Installation should be easy and fast. Install it via PEAR,
download an archive, or checkout the SVN or Git repository, and you are
ready to go. No configuration. Drop the files in a directory and start
using it right away.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Fast&lt;/em&gt;: One of the main goal of Symfony YAML was to find the right balance
between speed and features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Unit tested&lt;/em&gt;: The library is unit-tested (with more than 400 unit tests
as of today).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;"Real" Parser&lt;/em&gt;: To correctly handle a large subset of the YAML
specification, a dedicated and hand-written parser has been written. The
parser is robust, easy to understand, and simple enough to extend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Clear error messages&lt;/em&gt;: Whenever you have a syntax problem with your YAML
files, the library should output helpful messages with the filename and
the line number where the problem occurred. It eases debugging a lot.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And of course, YAML being not so well-known in the PHP world, the YAML
component also comes with a full
&lt;a href="http://components.symfony-project.org/yaml/documentation"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The easiest way to
&lt;a href="http://components.symfony-project.org/yaml/installation"&gt;install&lt;/a&gt; the Symfony
YAML Component is probably to use the PEAR installer:&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ pear channel-discover pear.symfony-project.com
$ pear install symfony/YAML
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Using YAML in your Projects&lt;/h2&gt;

&lt;p&gt;The Symfony YAML library consists of two main classes: one to parse YAML
strings, and the other to dump a PHP variable to a YAML string. On top of
these two core classes, the main &lt;code&gt;sfYaml&lt;/code&gt; class acts as a thin wrapper and
simplifies common uses:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="co1"&gt;// loading a YAML file or a YAML string&lt;/span&gt;
&lt;span class="re0"&gt;$var&lt;/span&gt; = sfYaml::&lt;span class="me2"&gt;load&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'/path/to/file.yml'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span class="co1"&gt;// Dumping a PHP variable to YAML&lt;/span&gt;
&lt;span class="re0"&gt;$yaml&lt;/span&gt; = sfYaml::&lt;span class="me2"&gt;dump&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$var&lt;/span&gt;, &lt;span class="re0"&gt;$inline&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;&lt;/pre&gt;

&lt;h2&gt;YAML for PHP 5.3&lt;/h2&gt;

&lt;p&gt;The previous sections use the PHP 5.2 compatible version of the library. If
you have already switched to use PHP 5.3, the good news is that the YAML
Component is already available for that version too. For now, it is only
available on the Symfony 2 Subversion repository:&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ svn co http://svn.symfony-project.com/branches/2.0/lib/Symfony/Components/YAML/ YAML
&lt;/code&gt;&lt;/pre&gt;



&lt;pre class="php"&gt;use Symfony\Components\YAML\YAML;
&amp;nbsp;
&lt;span class="co1"&gt;// loading a YAML file or a YAML string&lt;/span&gt;
&lt;span class="re0"&gt;$var&lt;/span&gt; = YAML::&lt;span class="me2"&gt;load&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'/path/to/file.yml'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span class="co1"&gt;// Dumping a PHP variable to YAML&lt;/span&gt;
&lt;span class="re0"&gt;$yaml&lt;/span&gt; = YAML::&lt;span class="me2"&gt;dump&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$var&lt;/span&gt;, &lt;span class="re0"&gt;$inline&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;This version can be autoloaded with any autoloader that follows the
&lt;a href="http://groups.google.com/group/php-standards/web/psr-0-final-proposal"&gt;standards&lt;/a&gt;
discussed by some PHP developers. Symfony 2 provides such an autoloader:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw1"&gt;require_once&lt;/span&gt; __DIR__.&lt;span class="st0"&gt;'/lib/Symfony/Foundation/ClassLoader.php'&lt;/span&gt;;
&amp;nbsp;
use Symfony\Foundation\ClassLoader;
&amp;nbsp;
&lt;span class="re0"&gt;$loader&lt;/span&gt; = &lt;span class="kw2"&gt;new&lt;/span&gt; ClassLoader&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'Symfony'&lt;/span&gt;, __DIR__.&lt;span class="st0"&gt;'/lib'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&lt;span class="re0"&gt;$loader&lt;/span&gt;-&amp;gt;&lt;span class="me1"&gt;register&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;The YAML Symfony Component is already used by and bundled with many popular
Open-Source PHP software like symfony, Doctrine, and PHPUnit. Other frameworks
like the upcoming &lt;a href="http://okapi.liip.ch/"&gt;Okapi2&lt;/a&gt; framework and the
&lt;a href="http://mootools.net/forge/"&gt;mootools&lt;/a&gt; plugins repository,
&lt;a href="http://mootools.net/blog/2009/12/10/the-official-mootools-plugins-repository-is-here/"&gt;announced&lt;/a&gt;
some days ago, make a heavy use of YAML and also use the YAML Symfony
Component.&lt;/p&gt;

&lt;p&gt;Next time you look for a flexible mean to store or share data, consider using
YAML!&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>2009 Conferences Wrap-up</title>
  <link href="http://fabien.potencier.org/article/39/2009-conferences-wrap-up" />
  <id>article-39</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-12-15T11:09:00+01:00</updated>
  <content type="html">
    &lt;p&gt;This year, I traveled in 7 countries for PHP conferences, giving a total of 12
talks. It has been a very exiting year of conferences for me. I met old and
new friends, I learned a bunch of new things (not always related to PHP) and I
had of course very interesting conversations about PHP 5.3, symfony, Twig, the
Zend Framework, and various other topics.&lt;/p&gt;

&lt;p&gt;In March, I went to the PHP Quebec conference. Three years ago, this was my
first PHP conference, and as such it's always a very special event for me.
This was also the first conference where I gave a talk about Symfony 2.&lt;/p&gt;

&lt;p&gt;In May, I had the pleasure to go to the PHP Day in Italy. This was probably
one of the most convivial conference of the year. Italian people are very
friendly, and the food is always amazing.&lt;/p&gt;

&lt;p&gt;In June, it was the first Symfony Live conference. I was one of the organizer,
and also a speaker of course. This was a great success and I had a wonderful
time talking with so many symfony users.&lt;/p&gt;

&lt;p&gt;In September, I went to Japan for their 10th PHP conference. This was my first
time in Japan, and I'm eager to come back someday. This was also the first
time I worked with a professional translator.&lt;/p&gt;

&lt;p&gt;In October, thanks to Zend, I went to the Zend PHP Conference in San Jose.
Needless to say that this was an amazing experience. I have also kind of
officially "launched" &lt;a href="http://www.twig-project.org/"&gt;Twig&lt;/a&gt; at this conference,
and created &lt;a href="http://www.pirum-project.org/"&gt;Pirum&lt;/a&gt; during a night thanks to
the &lt;a href="http://twitter.com/fabpot/status/4969508481"&gt;jetlag&lt;/a&gt;. This is also where
I decided that Symfony 2 would only support PHP 5.3. At the end of October, I
also went to the PHP Barcelona conference for the first time.&lt;/p&gt;

&lt;p&gt;In November, after the Forum PHP conference in Paris, where I talked about PHP
5.3, my new friend, I went to the IPC conference in Karlsruhe. Two great
conferences, where I always meet a lot of friends.&lt;/p&gt;

&lt;p&gt;Thanks to all conference organizers for giving me these great opportunities.&lt;/p&gt;

&lt;p&gt;All my slides are available in the &lt;a href="http://fabien.potencier.org/talks"&gt;talk&lt;/a&gt;
section of this website, and also on
&lt;a href="http://www.slideshare.net/fabpot"&gt;Slideshare&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a list of the most interesting/up-to-date talks I gave this year:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://fabien.potencier.org/talk/30/dependency-injection-ipc-2009"&gt;Dependency Injection with PHP and PHP 5.3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://fabien.potencier.org/talk/29/symfony-components-ipc-2009"&gt;Symfony Components: What's in for you?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://fabien.potencier.org/talk/28/playing-with-PHP53"&gt;Jouons avec PHP 5.3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://fabien.potencier.org/talk/33/php-barcelona-symfony-2-0-on-PHP-5-3"&gt;Symfony 2.0 on PHP 5.3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://fabien.potencier.org/talk/27/symfony-and-zend-framework-together-2009"&gt;Using Zend Framework and Symfony Together&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://fabien.potencier.org/talk/31/twig-zend-unconference-2009"&gt;Twig, the flexible, fast, and secure template language for PHP&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2009 is coming to an end, and 2010 is already almost here. I'm going to be
doing a fair bit of traveling early next year as I will speak at least at
these conferences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://conference.phpbenelux.eu/schedule/#talk1"&gt;Dependency Injection in PHP 5.2 and 5.3&lt;/a&gt;: PHPBenelux conference (January 30, 2010 - Antwerp, Belgium)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.symfony-live.com/schedule#session-fp1"&gt;Playing with the symfony components&lt;/a&gt;: Symfony Live Conference (February 16, 2010 - Paris, France)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.symfony-live.com/schedule#session-fp2"&gt;Symfony 2 revealed&lt;/a&gt;: Symfony Live Conference (February 17, 2010 - Paris, France)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.phpconference.co.uk/schedule"&gt;PHP 5.3 in practice&lt;/a&gt;: PHP UK Conference (26 February, 2010, London, England)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://confoo.ca/en/2010/session/symfony-components-what-s-in-for-you"&gt;Symfony Components: What's in for you?&lt;/a&gt;: ConFoo (March 10, 2010, Montreal, Canada)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://confoo.ca/en/2010/session/dependency-injection-in-php-5-2-and-5-3"&gt;Dependency Injection in PHP 5.2 and 5.3&lt;/a&gt;: ConFoo (March 10, 2010, Montreal, Canada)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you next year at one of the PHP conference!&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>Pirum, the Simple PEAR Channel Server Manager</title>
  <link href="http://fabien.potencier.org/article/38/pirum-the-simple-pear-channel-server-manager" />
  <id>article-38</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-11-28T08:50:00+01:00</updated>
  <content type="html">
    &lt;p&gt;Some weeks ago during the Zend Conference, I
&lt;a href="http://twitter.com/fabpot/status/4969508481"&gt;quietly&lt;/a&gt; released
&lt;a href="http://www.pirum-project.org/"&gt;Pirum&lt;/a&gt;, a simple PEAR channel server manager.
As some people talk about it on "social
&lt;a href="http://twitter.com/s_bergmann/statuses/6121431277"&gt;networks&lt;/a&gt;", I thought I
should write an official announcement on my blog to explain where I come from.&lt;/p&gt;

&lt;p&gt;A PEAR channel server allows you to install PEAR packages with the PEAR
command line. You are probably already familiar with it as it comes bundled
with most PHP installations:&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ pear install ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pirum comes from my frustration with the current state of PEAR channel
servers. Beside big Open-Source projects like
&lt;a href="http://www.symfony-project.org/"&gt;symfony&lt;/a&gt;, I'm also responsible for smaller
projects (like &lt;a href="http://www.twig-project.org/"&gt;Twig&lt;/a&gt;, or &lt;a href="http://www.swiftmailer.org/"&gt;Swift Mailer&lt;/a&gt;).
But for all my software, I like to provide different way
of installing them: directly from SVN via &lt;code&gt;svn:externals&lt;/code&gt;,
from my &lt;a href="http://www.github.com/fabpot"&gt;Git&lt;/a&gt; mirrors, from an
archive to download, or with the PEAR command line.&lt;/p&gt;

&lt;p&gt;Except for the PEAR package installation, the other ones are quite easy to
setup and automate. But providing a PEAR channel proves to be more involving.
The only serious PEAR channel server I'm aware of is
&lt;a href="http://greg.chiaraquartet.net/archives/123-Setting-up-your-own-PEAR-channel-with-Chiara_PEAR_Server-the-official-way.html"&gt;Chiara_PEAR_Channel&lt;/a&gt;
from Greg Beaver. This is the software I used for symfony for four years. It
works really well, but is a bit cumbersome to setup for smaller projects (it
needs a database, and you need to configure some categories, the contributors
for the project, and more). That's fine for &lt;a href="http://pear.php.net"&gt;PEAR&lt;/a&gt;
itself, but frankly, for the rest of us, that's just too much.&lt;/p&gt;

&lt;p&gt;As a matter of fact, hosting a PEAR channel server is super simple. It's all
about static files. That's right, even if you need some sort of PHP scripts to
maintain a PEAR channel server, the frontend used by the PEAR command line
tool can only be static files (mainly XML ones). And &lt;code&gt;Chiara_PEAR_Server&lt;/code&gt;
works exactly like this. The backend, done in PHP, is where you maintain your
packages, and it generates the frontend, a bunch of static files for the
frontend. That's a really great architecture as it allows to scale very
easily. For instance, you should probably be able to host a PEAR channel
server on a CDN line Amazon S3 in a matter of minutes.&lt;/p&gt;

&lt;p&gt;Thanks to this decoupled and simple architecture, I wrote some PHP scripts to
manage a PEAR channel server for the symfony
&lt;a href="http://www.symfony-project.org/plugins/"&gt;plugins&lt;/a&gt; two years ago.&lt;/p&gt;

&lt;p&gt;The idea for Pirum came when I started the
&lt;a href="http://www.twig-project.org/"&gt;Twig&lt;/a&gt; project. Obviously, I wanted a PEAR
channel server for Twig, but I really did not want to use
&lt;code&gt;Chiara_PEAR_Server&lt;/code&gt;. So I started to hack my own and Pirum was born.&lt;/p&gt;

&lt;p&gt;Pirum lets you setup PEAR channel servers in a matter of minutes. Pirum is
best suited when you want to create small PEAR channels for a few packages
written by a few developers.&lt;/p&gt;

&lt;p&gt;Pirum consists of just one file, a command line tool, written in PHP. There is
no external dependencies, no not need for a database, no need to setup
credentials, and nothing need to be installed or configured.&lt;/p&gt;

&lt;p&gt;Installing Pirum is as simple as downloading the
&lt;a href="http://github.com/fabpot/Pirum/raw/master/pirum"&gt;pirum&lt;/a&gt; file and saving it
where you see fit.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  Of course, Pirum itself uses Pirum to provide a PEAR channel
  &lt;a href="http://pear.pirum-project.org/"&gt;server&lt;/a&gt; for itself!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even if Pirum only consists of just one file, it comes with a lot of great
features:&lt;/p&gt;

&lt;p&gt;Besides its size and simplicity, Pirum is packed with a lot of features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It creates a full-featured PEAR channel server useable by any PEAR CLI;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each channel has an HTML page describing the server and the packages it
hosts;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New releases can be tracked by subscribing to an Atom feed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, it also comes with some limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No support for fallback PEAR channel servers;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No category management (all packages are under a "default" category);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No web interface for managing the packages.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find more information about using Pirum on its official
&lt;a href="http://www.pirum-project.org/"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pirum is already used by the following Open-Source projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.symfony-project.org/"&gt;Symfony&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://pear.phpunit.de/"&gt;PHPUnit&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.swiftmailer.org/"&gt;Swift Mailer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.twig-project.org/"&gt;Twig&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.fluentdom.org/"&gt;FluentDOM&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.pirum-project.org/"&gt;Pirum&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope that with Pirum, more Open-Source projects will start providing a PEAR
channel as a mean to install their software. If you start using Pirum for your
project, please send me an email so that I can update the list on the Pirum
website.&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>PHP 5.3.0 on Mac OS 10.6 (Snow Leopard)</title>
  <link href="http://fabien.potencier.org/article/37/php-5-3-0-on-mac-os-10-6-snow-leopard" />
  <id>article-37</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-11-05T09:40:00+01:00</updated>
  <content type="html">
    &lt;p&gt;Recently, I started to use PHP 5.3.0 extensively, thanks to the
&lt;a href="http://www.symfony-project.org/blog/2009/10/27/why-will-symfony-2-0-finally-use-php-5-3"&gt;move&lt;/a&gt;
of Symfony 2 to PHP 5.3. To do my work, I need to have several different
versions of PHP at hand, with different configurations, and so I always
compile my own PHP and Apache binaries on my Mac. But as Snow Leopard comes
bundled with PHP 5.3.0, I started some PHP 5.3.0 experiments with the bundle
version and everything went well for a couple of days.&lt;/p&gt;

&lt;p&gt;Now that I use PHP 5.3.0 more and more, I decided it was time to compile my
own version. As it turns out, compiling PHP 5.3.0 on Snow Leopard is a bit
involving. As I loose some time before finding the right
&lt;a href="http://bugs.php.net/bug.php?id=49267"&gt;solution&lt;/a&gt;, here is what I did step by
step (I have just followed the tips referenced in the
&lt;a href="http://bugs.php.net/bug.php?id=49267"&gt;ticket&lt;/a&gt; opened for the issue on
php.net, so all credits go to them).&lt;/p&gt;

&lt;p&gt;First, I ran the configure script with my usual options and added
&lt;code&gt;--with-iconv-dir=/usr&lt;/code&gt; at the end:&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ ./configure ... --with-iconv-dir=/usr
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  If you have upgraded your Mac to Snow Leopard, you should know that everything
  must now be compiled for 64 bits. It means that you might need to recompile extra
  libraries needed by PHP like libjpeg or libpng, or even re-install a 64 bits version
  of MySQL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I then patched the &lt;code&gt;iconv.c&lt;/code&gt; file the same way
&lt;a href="http://opensource.apple.com/source/apache_mod_php/apache_mod_php-53/patches/iconv.patch"&gt;Apple&lt;/a&gt;
did for their own version:&lt;/p&gt;

&lt;pre class="php"&gt;--- php&lt;span class="nu0"&gt;-5.3&lt;/span&gt;&lt;span class="nu0"&gt;.0&lt;/span&gt;/ext/&lt;a href="http://www.php.net/iconv"&gt;&lt;span class="kw3"&gt;iconv&lt;/span&gt;&lt;/a&gt;/&lt;a href="http://www.php.net/iconv"&gt;&lt;span class="kw3"&gt;iconv&lt;/span&gt;&lt;/a&gt;.c &lt;span class="nu0"&gt;2009&lt;/span&gt;&lt;span class="nu0"&gt;-03&lt;/span&gt;&lt;span class="nu0"&gt;-16&lt;/span&gt; &lt;span class="nu0"&gt;22&lt;/span&gt;:&lt;span class="nu0"&gt;31&lt;/span&gt;:&lt;span class="nu0"&gt;04.000000000&lt;/span&gt; &lt;span class="nu0"&gt;-0700&lt;/span&gt;
+++ php/ext/&lt;a href="http://www.php.net/iconv"&gt;&lt;span class="kw3"&gt;iconv&lt;/span&gt;&lt;/a&gt;/&lt;a href="http://www.php.net/iconv"&gt;&lt;span class="kw3"&gt;iconv&lt;/span&gt;&lt;/a&gt;.c   &lt;span class="nu0"&gt;2009&lt;/span&gt;&lt;span class="nu0"&gt;-07&lt;/span&gt;&lt;span class="nu0"&gt;-15&lt;/span&gt; &lt;span class="nu0"&gt;14&lt;/span&gt;:&lt;span class="nu0"&gt;40&lt;/span&gt;:&lt;span class="nu0"&gt;09.000000000&lt;/span&gt; &lt;span class="nu0"&gt;-0700&lt;/span&gt;
@@ &lt;span class="nu0"&gt;-51&lt;/span&gt;,&lt;span class="nu0"&gt;9&lt;/span&gt; &lt;span class="nu0"&gt;+51&lt;/span&gt;,&lt;span class="nu0"&gt;6&lt;/span&gt; @@
 &lt;span class="co2"&gt;#include &amp;lt;gnu/libc-version.h&amp;gt;&lt;/span&gt;
 &lt;span class="co2"&gt;#endif&lt;/span&gt;
&amp;nbsp;
-&lt;span class="co2"&gt;#ifdef HAVE_LIBICONV&lt;/span&gt;
-&lt;span class="co2"&gt;#undef iconv&lt;/span&gt;
-&lt;span class="co2"&gt;#endif&lt;/span&gt;
&amp;nbsp;
 &lt;span class="co2"&gt;#include &amp;quot;ext/standard/php_smart_str.h&amp;quot;&lt;/span&gt;
 &lt;span class="co2"&gt;#include &amp;quot;ext/standard/base64.h&amp;quot;&lt;/span&gt;
@@ &lt;span class="nu0"&gt;-182&lt;/span&gt;,&lt;span class="nu0"&gt;9&lt;/span&gt; &lt;span class="nu0"&gt;+179&lt;/span&gt;,&lt;span class="nu0"&gt;6&lt;/span&gt; @@
 &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
 &lt;span class="coMULTI"&gt;/* }}} */&lt;/span&gt;
&amp;nbsp;
-&lt;span class="co2"&gt;#ifdef HAVE_LIBICONV&lt;/span&gt;
-&lt;span class="co2"&gt;#define iconv libiconv&lt;/span&gt;
-&lt;span class="co2"&gt;#endif&lt;/span&gt;
&amp;nbsp;
 &lt;span class="coMULTI"&gt;/* {{{ typedef enum php_iconv_enc_scheme_t */&lt;/span&gt;
 typedef enum _php_iconv_enc_scheme_t &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;To apply the patch, save the above text in a file (&lt;code&gt;patch&lt;/code&gt;) and from the root
source of PHP, type the following command:&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ patch -p1 &amp;lt; patch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, add &lt;code&gt;-lresolv&lt;/code&gt; to the &lt;code&gt;EXTRA_LIBS&lt;/code&gt; variable:&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ export EXTRA_LIBS=-lresolv 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Eventually, run the usual &lt;code&gt;make&lt;/code&gt; commands&lt;/p&gt;

&lt;pre class="command-line"&gt;&lt;code&gt;$ make
$ make install
&lt;/code&gt;&lt;/pre&gt;
  </content>
</entry>
      <entry>
  <title>My first Zend Conference was a blast</title>
  <link href="http://fabien.potencier.org/article/36/my-first-zend-conference-was-a-blast" />
  <id>article-36</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-10-24T00:05:00+02:00</updated>
  <content type="html">
    &lt;p&gt;This was my first Zend Conference, and I must say I had a great time there.
The organization was top notch, there were plenty of good sessions, and the
unconference topics proved to be very interesting.&lt;/p&gt;

&lt;p&gt;I've also met and talked with a lot of great people. I have particularly
enjoyed the talks I had with the Zend team, and with all the people I had
email conversations with in the past but never had the chance to meet in
person.&lt;/p&gt;

&lt;p&gt;Beside my
&lt;a href="http://www.slideshare.net/fabpot/symfony-and-zend-framework-together-2009"&gt;talk&lt;/a&gt;
about how to use symfony within a Zend Framework project, I have also held an
uncon session about
&lt;a href="http://www.slideshare.net/fabpot/twig-the-flexible-fast-and-securetemplate-language-for-php"&gt;Twig&lt;/a&gt;,
and took part in a roundtable about Dependency Injection.&lt;/p&gt;

&lt;p&gt;If you have not attended Zend Con this year, most of the presentations are now
available online on both
&lt;a href="http://www.slideshare.net/tag/zendcon09?sort=views"&gt;slideshare&lt;/a&gt; and
&lt;a href="http://joind.in/event/view/44"&gt;joind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last but not the least, I have been invited yesterday by the San Francisco symfony user group to talk
about &lt;a href="http://www.slideshare.net/fabpot/symfony2-san-francisco-meetup-2009"&gt;Symfony 2&lt;/a&gt;,
and I had a great time talking with SF symfony users.&lt;/p&gt;

&lt;p&gt;Thanks again Zend for inviting me this year, and I hope to come back next
year.&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>Templating engines in PHP - Follow-Up</title>
  <link href="http://fabien.potencier.org/article/35/templating-engines-in-php-follow-up" />
  <id>article-35</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-10-09T15:10:00+02:00</updated>
  <content type="html">
    &lt;p&gt;My post about
&lt;a href="http://fabien.potencier.org/article/34/templating-engines-in-php"&gt;template engines in PHP&lt;/a&gt;
received more than &lt;em&gt;70 comments&lt;/em&gt; as of now, and counting.
That's a lot considering most of them are really well thought out, and backed with solid
counter-arguments. Thanks everybody for taking the time to participate
constructively to the discussion. I'm really proud that the PHP community (or
at least the small part which reads my blog) is
able to discuss such a touchy topic without immediately starting a flame war!
I'm also impressed about how many people need to promote their own template
engines ;)&lt;/p&gt;

&lt;p&gt;Before I try to answer some questions, I'd like to reinstate that I like PHP
templates. And you should remember that symfony has only used plain old PHP
templates since the beginning. As a matter of fact, I'm been advocating about
using PHP templates since my first PHP project, and I have never used any
other PHP template engines. So, I'm not against PHP templates; I just find
that some PHP limitations as a template language are more and more irritating
for me.&lt;/p&gt;

&lt;p&gt;And as
&lt;a href="http://eliw.wordpress.com/2009/10/07/in-response-to-fabien-potencier-twig-php-templating/"&gt;Eli&lt;/a&gt;
has pointed out, "[I probably have] grossly undersold PHP-as-template in [my]
enthusiasm to promote [my] new templating language that [I] created".&lt;/p&gt;

&lt;p&gt;I also like Tchalvak comment: "The question of PHP vs a templating engine
isn't the essential one, the essential (and easily answerable one) is
templates vs. no templates. Templates - and the separation of display vs.
application logic that they bring with them - are a necessity. What form they
come in is much less important.". He sums up really well the question. More on
that later on.&lt;/p&gt;

&lt;p&gt;I understand all the points raised in the comments, and I basically agree with
most of them. Now, let me answer some of the more interesting questions.&lt;/p&gt;

&lt;h2&gt;Twig Background&lt;/h2&gt;

&lt;p&gt;I started to look for a template engine a few months ago. People who know me
also know that I don't like to reinvent the wheel. So, I didn't want to create
a new library from scratch.&lt;/p&gt;

&lt;p&gt;I looked for a good template engines, I tried some of them, and finally found
Twig. But as soon as I started to use it, I found that it was exactly what the
gem I was looking for (because of the features it already had and also because
of its clean and beautiful architecture). As Twig was not a standalone
project, but rather an embedded project, I started to hack it a bit, and after
I made several enhancements like the sandboxing feature, I decided to contact
Armin to discuss the future of Twig.&lt;/p&gt;

&lt;h2&gt;So, you are not sold... yet?&lt;/h2&gt;

&lt;p&gt;Even if you don't buy my arguments, that's fine. I don't want
&lt;a href="http://www.twig-project.org/"&gt;Twig&lt;/a&gt; to become the universal template language
for PHP, far from it. I really think there is a market for template engines
like Twig, but I'm the first to recognize that it won't be used for all PHP
projects to come!&lt;/p&gt;

&lt;p&gt;If you are looking for a templating engine that only uses PHP and have
built-in support for template inheritance, blocks, helpers, and some more, the
good news is that I have coded one some weeks ago under the Symfony
&lt;a href="http://components.symfony-project.org/templating/"&gt;Templating&lt;/a&gt; Component
name. It's a standalone component, which has no other dependencies, and I'm
sure most people wanting to use plain PHP for their projects will love this
project.&lt;/p&gt;

&lt;p&gt;And better yet, you can use both Twig and the Symfony Templating component to
have the best of both worlds. Use the component for all your templates and
Twig if you need the sandboxing feature.&lt;/p&gt;

&lt;h2&gt;About the Syntax&lt;/h2&gt;

&lt;p&gt;Lots of comments about the &lt;em&gt;syntax&lt;/em&gt;, and the problem I raised about the PHP
syntax. It's not about having a prettier syntax and if you think that the
syntax issues I mentioned are mostly
&lt;a href="http://www.freebsd.org/doc/en/books/faq/misc.html#BIKESHED-PAINTING"&gt;bikeshed&lt;/a&gt;
color arguments, think again.&lt;/p&gt;

&lt;p&gt;One of the key point of my reasoning is that a good template language should
aim to find the &lt;strong&gt;sweet spot&lt;/strong&gt;. The template language should find the best
compromise about too many and not enough features. As I said in my previous
post, the template language is all about &lt;em&gt;presentation logic&lt;/em&gt;. And of course,
simple conditions and loops are part of the presentation logic. But do you
want to use &lt;code&gt;array_chunk()&lt;/code&gt; in a template? Probably not. This call belongs to
the controller or the model, depending on what you want to do.&lt;/p&gt;

&lt;p&gt;Also, templates are about &lt;em&gt;a lot&lt;/em&gt; of HTML with &lt;em&gt;some&lt;/em&gt; PHP. So, this kind of
code snippet is a big no-no for me in a template:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class="kw1"&gt;if&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$items&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
        &lt;span class="kw1"&gt;foreach&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$items&lt;/span&gt; &lt;span class="kw1"&gt;as&lt;/span&gt; &lt;span class="re0"&gt;$item&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
            &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="st0"&gt;&amp;quot;* {$item}&lt;span class="es0"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;;
        &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
    &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt; &lt;span class="kw1"&gt;else&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
        &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="st0"&gt;&amp;quot;No item has been found.&lt;span class="es0"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;;
    &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;Many people seem to like the PHP short tags. First, about the math. If you
compare &lt;code&gt;&amp;lt;?= $var ?&amp;gt;&lt;/code&gt; with &lt;code&gt;&amp;lt;?php echo $var ?&amp;gt;&lt;/code&gt;, the difference is &lt;strong&gt;7&lt;/strong&gt;
characters, not 2. But that's really not the main problem.&lt;/p&gt;

&lt;p&gt;Apart from problems like XML support, the &lt;code&gt;short_open_tag&lt;/code&gt; setting, the shared
hosts configuration issue, and some more, it's also about coding standards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PEAR&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;"Always use &lt;code&gt;&amp;lt;?php ?&amp;gt;&lt;/code&gt; to delimit PHP code, not the &lt;code&gt;&amp;lt;? ?&amp;gt;&lt;/code&gt; shorthand. This is
   required for PEAR compliance and is also the most portable way to include PHP
   code on differing operating systems and setups."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zend&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;"Short tags are never allowed."&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Pear and Zend projects are serious, so there should have some reasons to
disallow short tags, no?&lt;/p&gt;

&lt;p&gt;But as Eli mentioned in his post, I would also like to see a PHP evolution to
take this problem into account: "... there are a number of people (including
myself [Eli]), who have been tossing around the idea of proposing a new option
to the &lt;code&gt;short_tags&lt;/code&gt; directive for PHP, allowing not just having them turned on
or off. But allowing a 3rd option, that would enable &lt;code&gt;&amp;lt;?= ?&amp;gt;&lt;/code&gt; while disabling
&lt;code&gt;&amp;lt;? ?&amp;gt;&lt;/code&gt;"&lt;/p&gt;

&lt;h2&gt;About Web Designers&lt;/h2&gt;

&lt;p&gt;The debate is not about if web designers should understand PHP or not. And
it's certainly not about web designers not being smart enough. Of course web
designers can learn a bit of PHP... until they learn too much and start
getting stuff that do not belong to the template in their templates (like
getting records directly from the database, anyone?) Oh, of course, they won't
do such a mistake it they have also learned about the MVC pattern. But then,
they are not web designers anymore, they are web developers.&lt;/p&gt;

&lt;p&gt;Finding this good balance is all about providing a tool that tries to help web
designers not to shoot themselves in the foot. And I think everybody will be
with me if I say that PHP does a poor job setting the limits.&lt;/p&gt;

&lt;h2&gt;Output Escaping&lt;/h2&gt;

&lt;p&gt;Some commenters advocate that output escaping should be done in the
controllers. That cannot work. As John Campbell writes: "The problem is that
the controller can't possibly be aware of the context of the output, nor
understand which type of escaping is correct."&lt;/p&gt;

&lt;p&gt;The issue is therefore not that simple. On the one hand, developers should
take care of output escaping, but it cannot be done in controllers. On the
other hand, web designers should not have to take care about output escaping,
but templates is the only place where you have enough context information to
apply sensible escaping. That's why automatic output escaping seems the best
compromise to me, plus the fact that being "almost" secure by default is a big
advantage.&lt;/p&gt;

&lt;p&gt;Speaking of automatic escaping, I'm probably someone who knows a lot about it
as symfony has this feature since early 2006. I can tell you that the
performance overhead of such a feature is very high. In Twig, it is added
during compilation, so there is no overhead whatsoever.&lt;/p&gt;

&lt;h2&gt;About Sandboxing&lt;/h2&gt;

&lt;p&gt;The sandbox feature is not targeted at web designers. It is mainly useful for
situation where external people can change the templates (think of webmasters
able to configure their CMS or blogging platform templates from a backend
interface).&lt;/p&gt;

&lt;p&gt;The Dwoo and Smarty security feature is a right step in that direction, but
not as powerful as a full sandbox feature. As far as I understand, it's mainly
about allowing PHP code or not in the templates, and restricting the PHP
functions you can use (of course, correct me if I'm wrong).&lt;/p&gt;

&lt;p&gt;Sandboxing controls everything, from the tags you can use, to the methods you
can call on the objects (the Twig
&lt;a href="http://www.twig-project.org/book/03-Twig-for-Developers"&gt;documentation&lt;/a&gt;
explains the concept and how it works).&lt;/p&gt;

&lt;h2&gt;About Speed&lt;/h2&gt;

&lt;p&gt;Most template engines compile the templates down to PHP code. So, the speed of
lexing, parsing, and compiling is not that relevant. What matters is the speed
of the evaluation. Here is the compiled version of the &lt;code&gt;Hello {{ name }}&lt;/code&gt;
template:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="coMULTI"&gt;/* Hello {{ name }} */&lt;/span&gt;
&lt;span class="kw2"&gt;class&lt;/span&gt; __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb &lt;span class="kw2"&gt;extends&lt;/span&gt; Twig_Template
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
  &lt;span class="kw2"&gt;public&lt;/span&gt; &lt;span class="kw2"&gt;function&lt;/span&gt; display&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$context&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;
  &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
    &lt;span class="re0"&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class="me1"&gt;env&lt;/span&gt;-&amp;gt;&lt;span class="me1"&gt;initRuntime&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
    &lt;span class="co1"&gt;// line 1&lt;/span&gt;
    &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="st0"&gt;&amp;quot;Hello &amp;quot;&lt;/span&gt;;
    &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://www.php.net/isset"&gt;&lt;span class="kw3"&gt;isset&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$context&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="st0"&gt;'name'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; ? &lt;span class="re0"&gt;$context&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="st0"&gt;'name'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt; : &lt;span class="kw2"&gt;null&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
  &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  Some people were worried about debugging. As you can see, the generated code is
  very lean, and contains the template name and the lines of the original
  template. That should be more than enough to debug all the possible problems
  easily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can find it much more verbose than the PHP version, and of course, for
such a contrived example, the native PHP version is insanely simpler:&lt;/p&gt;

&lt;pre class="php"&gt;Hello &lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="re0"&gt;$name&lt;/span&gt; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;But have a look at the generated code for many template engines and you will
see for yourself that Twig output is one of the cleanest and shortest
one.&lt;/p&gt;

&lt;p&gt;As asked by many people, I have redone my benchmark by bypassing the
compilation phase altogether (the cache has been primed before launching the
benchmark scripts). As I expected, it does not change numbers significantly.
The compilation of such simple templates is insignificant compared to the
rendering of 10,000 compiled templates.&lt;/p&gt;

&lt;p&gt;I have also tested plain PHP templates. So, here is the updated table:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
  &lt;th&gt;Library&lt;/th&gt;
  &lt;th&gt;Time (sec)&lt;/th&gt;
  &lt;th&gt;Memory (Kb)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;Plain PHP&lt;/td&gt;
  &lt;td&gt;2.4&lt;/td&gt;
  &lt;td&gt;114&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Twig&lt;/td&gt;
  &lt;td&gt;3&lt;/td&gt;
  &lt;td&gt;383&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;PHPTAL&lt;/td&gt;
  &lt;td&gt;3.8&lt;/td&gt;
  &lt;td&gt;598&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Dwoo&lt;/td&gt;
  &lt;td&gt;6.9&lt;/td&gt;
  &lt;td&gt;1,645&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Smarty 2&lt;/td&gt;
  &lt;td&gt;12.9&lt;/td&gt;
  &lt;td&gt;610*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Smarty 3&lt;/td&gt;
  &lt;td&gt;14.9&lt;/td&gt;
  &lt;td&gt;799*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Calypso&lt;/td&gt;
  &lt;td&gt;34.3&lt;/td&gt;
  &lt;td&gt;614&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;eZ Templates&lt;/td&gt;
  &lt;td&gt;53&lt;/td&gt;
  &lt;td&gt;2,783&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
&lt;li&gt;Notice that the memory used by Smarty is much lower than the memory used in
my previous benchmark as I wrapped the whole loop with an
&lt;code&gt;ob_start()/ob_end_clean()&lt;/code&gt;, which was not fair comparing to the other
template engines. This was fixed in this new benchmark.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, as expected, PHP is faster than Twig for simple templates. But as
templates become more complex, the difference will be less and less
noticeable, due to the clean code generated by Twig.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  The benchmark scripts are executed on the command line without any PHP
  accelerator. A PHP accelerator in this case does not help as everything
  is done in one single PHP process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can download the benchmark code here: 
http://fabien.potencier.org/benchmarks.tgz&lt;/p&gt;

&lt;h2&gt;Twig and Symfony&lt;/h2&gt;

&lt;p&gt;This section is for people worried about the integration of Twig as the
default template engine in symfony.&lt;/p&gt;

&lt;h3&gt;symfony 1.3/1.4&lt;/h3&gt;

&lt;p&gt;Obvisouly, Twig won't be part of symfony 1.3 as the feature-freeze deadline is
the end of next week and also because we want the symfony 1.3 release to be an
evolution of symfony 1.2, and not a revolution.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  If some people want to create a Twig plugin for symfony 1.3, start the
  discussion on the symfony developer mailing-list, and I will help you
  getting started.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Symfony 2.0&lt;/h3&gt;

&lt;p&gt;As far as Symfony 2 is concerned, nothing is definitive yet, but Twig won't be
the default template language. I &lt;em&gt;think&lt;/em&gt; Twig will be available as an
&lt;em&gt;optional&lt;/em&gt; plugin, well integrated with the core. For instance, it will
probably make sense to use it for the admin generator to provide some specific
tags that will ease the customization of it.&lt;/p&gt;

&lt;p&gt;And thanks to the Symfony
&lt;a href="http://components.symfony-project.org/templating/"&gt;Templating&lt;/a&gt; Component,
developers will be able to mix PHP templates and Twig templates easily in one
project, depending on their needs or the tools they want to use.&lt;/p&gt;

&lt;p&gt;So, if you can't stand template engines, use plain PHP templates; but if you
want to benefit from Twig, use it natively. And of course, if you use plugins
that made the opposite choice, that won't be a problem either.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Hopefully, this new post has answered some of the points raised in the
comments.&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>Templating Engines in PHP</title>
  <link href="http://fabien.potencier.org/article/34/templating-engines-in-php" />
  <id>article-34</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-10-07T23:40:00+02:00</updated>
  <content type="html">
    &lt;blockquote class="caution"&gt;&lt;p&gt;
  This blog post is not for the faint-hearted! Some people will strongly
  disagree with me and some others will probably want to kill me at the
  upcoming &lt;a href="http://www.zendcon.com/"&gt;Zend Conference&lt;/a&gt;. And
  if starting an argument in the comments can help you feel better,
  please feel free to do so. If you want to have a more advanced discussion
  on this topic, vote for my talk at the Zend
  &lt;a href="http://joind.in/talk/view/959"&gt;UnConference&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, you think PHP is a templating engine? So did I... for a very long time.
But recently, I changed my mind. Even if PHP can be used as a templating
engine, the syntax is just plain ugly as a template language.&lt;/p&gt;

&lt;p&gt;For several years now, I have been promoting web development best practices,
and one of them is the separation of concerns. Of course, as the lead
developer of symfony, all the projects we work on at Sensio are modeled after
the MVC architecture. It certainly helps when we have big projects where many
people need to work together. The developers work on the code (the Controllers
and the Model) and the web designers work on the design. And templates are
sometimes written by developers, but more often than not, they need to be
written by web designers or by the webmasters themselves.&lt;/p&gt;

&lt;p&gt;And a template language is something that helps you to write templates that
respects this separation of concerns. A template language should find a good
balance between giving enough features to ease implementing the &lt;em&gt;presentation
logic&lt;/em&gt;, and restricting the advanced features to avoid the &lt;em&gt;business logic&lt;/em&gt; to
cripple your templates.&lt;/p&gt;

&lt;p&gt;So, when I asked a few days ago about the best and popular templating engines
in PHP on &lt;a href="http://twitter.com/fabpot/status/4632858523"&gt;Twitter&lt;/a&gt;, some people
naturally answered "PHP" itself. I was not even surprised as that would
probably have been my answer some weeks ago too.&lt;/p&gt;

&lt;h2&gt;Why PHP is not (anymore) a good template language?&lt;/h2&gt;

&lt;p&gt;Why do people still think PHP is a templating engine? Sure enough, PHP started
its life as a template language, but it did not evolve like one in the recent
years. If you think PHP is still a template language, can you give me just one
recent change in the PHP language which enhanced PHP as a template language? I
cannot think of one.&lt;/p&gt;

&lt;p&gt;Template languages evolved a lot since 1995 and the initial release of
&lt;a href="http://fr2.php.net/manual/en/history.php.php"&gt;PHP/FI&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&amp;lt;!--include /text/header.html--&amp;gt;
&amp;nbsp;
&amp;lt;!--getenv HTTP_USER_AGENT--&amp;gt;
&amp;lt;!--ifsubstr $exec_result Mozilla--&amp;gt;
  Hey, you are using Netscape!&amp;lt;p&amp;gt;
&amp;lt;!--endif--&amp;gt;
&amp;nbsp;
&amp;lt;!--sql database select * from table where user='$username'--&amp;gt;
&amp;lt;!--ifless $numentries 1--&amp;gt;
  Sorry, that record does not exist&amp;lt;p&amp;gt;
&amp;lt;!--endif exit--&amp;gt;
  Welcome &amp;lt;!--$user--&amp;gt;!&amp;lt;p&amp;gt;
  You have &amp;lt;!--$index:0--&amp;gt; credits left in your account.&amp;lt;p&amp;gt;
&amp;nbsp;
&amp;lt;!--include /text/footer.html--&amp;gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;And as a matter of fact, &lt;em&gt;PHP doesn't support many features modern template
languages should have nowadays&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  I will take Django as an example of a modern template language in my examples
  for reasons you will understand later on, and mainly because I think Django
  template language hits that sweet spot I talked about above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following sections describes the main features I want to find in a modern
template language:&lt;/p&gt;

&lt;h3&gt;Concision&lt;/h3&gt;

&lt;p&gt;The PHP language is verbose. You need no less than 14 characters just to
output a simple variable (and no, using the more compact &lt;code&gt;&amp;lt;?=&lt;/code&gt; shortcut is not
an option):&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="re0"&gt;$var&lt;/span&gt; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;And PHP becomes ridiculously verbose when it comes to output escaping (and
yes, escaping variables coming from an unsafe source is mandatory nowadays):&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;a href="http://www.php.net/htmlspecialchars"&gt;&lt;span class="kw3"&gt;htmlspecialchars&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$var&lt;/span&gt;, ENT_QUOTES, &lt;span class="st0"&gt;'UTF-8'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;Compare with the same examples written with the Django template language:&lt;/p&gt;

&lt;pre&gt;{{ var }}
&amp;nbsp;
{{ var|escape }}
&amp;nbsp;&lt;/pre&gt;

&lt;h3&gt;Template oriented syntax&lt;/h3&gt;

&lt;p&gt;This one is mostly a matter of taste, but modern template language have nice
idioms to express common needs. For instance, let's say you want to iterate
over an array and want to display a default text when the array is empty.
That's very common, but the PHP version is not very readable:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="kw1"&gt;if&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$items&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;: &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
  &lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="kw1"&gt;foreach&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$items&lt;/span&gt; &lt;span class="kw1"&gt;as&lt;/span&gt; &lt;span class="re0"&gt;$item&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;: &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
    * &lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="re0"&gt;$item&lt;/span&gt; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
  &lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="kw1"&gt;endforeach&lt;/span&gt;; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="kw1"&gt;else&lt;/span&gt;: &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
    No item has been found.
&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="kw1"&gt;endif&lt;/span&gt;; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;The Django version is much better thanks to the use of an &lt;code&gt;else&lt;/code&gt; clause for
the &lt;code&gt;for&lt;/code&gt; tag:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;% &lt;span class="kw1"&gt;for&lt;/span&gt; item in items %&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
  * &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt; item &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;% &lt;span class="kw1"&gt;else&lt;/span&gt; %&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
  No item has been found.
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;% &lt;span class="kw1"&gt;endfor&lt;/span&gt; %&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;h3&gt;Reusability&lt;/h3&gt;

&lt;p&gt;PHP has greatly evolved over the years as far as reusability is concerned.
Since PHP5, the object implementation is much better, and when
&lt;a href="http://wiki.php.net/rfc/horizontalreuse"&gt;traits&lt;/a&gt; will be supported in the
next version of the language, we will have a solid general purpose language at
our disposal. I'm really happy with all these changes as it helps me write
better programs, but these enhancements are irrelevant when what you want to
do is to mainly write templates.&lt;/p&gt;

&lt;p&gt;Django introduced template
&lt;a href="http://docs.djangoproject.com/en/dev/topics/templates/#id1"&gt;inheritance&lt;/a&gt; some
years ago, as a way to mimic classes but for templates:&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- base.html --&amp;gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;en&amp;quot; lang=&amp;quot;en&amp;quot;&amp;gt;
  &amp;lt;head&amp;gt;
    {% block head %}
      &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;main.css&amp;quot; /&amp;gt;
    {% endblock %}
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    {% block content %}{% endblock %}
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&amp;nbsp;
&amp;lt;!-- index.html --&amp;gt;
{% extends &amp;quot;base.html&amp;quot; %}
&amp;nbsp;
{% block head %}
  {{ block.super }}
  &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;main.css&amp;quot; /&amp;gt;
{% endblock %}
&amp;nbsp;
{% block content %}
  Index content
{% endblock %}
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;It's elegant, easy to understand, and really powerful. It's so powerful that
many template engines now support this feature out of the box.&lt;/p&gt;

&lt;h3&gt;Security&lt;/h3&gt;

&lt;p&gt;I'm not saying PHP is not a secure language, far from it. But needless to say
that escaping a variable in a template is just a nightmare as I have showed
you previously:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;a href="http://www.php.net/htmlspecialchars"&gt;&lt;span class="kw3"&gt;htmlspecialchars&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$var&lt;/span&gt;, ENT_QUOTES, &lt;span class="st0"&gt;'UTF-8'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;Of course, you can create your own function to make it shorter, but that's not
my point:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="kw2"&gt;&amp;lt;?php&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; e&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$var&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="kw2"&gt;?&amp;gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;For me, security should be enabled by default, especially for templates
written by non-developers who are not necessarily aware of the common web
threats like XSS or CSRF.&lt;/p&gt;

&lt;p&gt;As far as I know, symfony was one of the very first web frameworks to have
automatic output escaping for variables used in templates (2006); and in the
recent years, major frameworks followed the same path:
&lt;a href="http://docs.djangoproject.com/en/dev/releases/1.0/#automatic-escaping-of-template-variables"&gt;Django&lt;/a&gt;
has automatic output escaping enabled since 1.0, and Ruby on Rails will also
have it in the upcoming version 3.&lt;/p&gt;

&lt;p&gt;Having output escaping enabled by default also means that auditing an
application is much easier. Just have a look at templates where escaping has
been disabled:&lt;/p&gt;

&lt;pre&gt;{% autoescape off %}
  {{ object.as_html }}
{% endautoescape %}
&amp;nbsp;
{{ object.as_html|safe }}
&amp;nbsp;&lt;/pre&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  Of course, I'm well aware of the automatic output escaping problems.
  You still need to take care of escaping variables in JavaScript tags
  correctly, but that's much easier to remember than just having to
  escape everything by hand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Sandbox mode&lt;/h3&gt;

&lt;p&gt;This one is a must-have when you allow users to edit templates (when
webmasters are allowed to edit some templates from a web backend for
instance). That's not a universal need, but one that needs to be addressed
anyway. Evaluating a template in a sandbox means being able to restrict what
can be done in it. For instance, you should be able to restrict the
methods/functions that can be called, the tags that can be used, ...&lt;/p&gt;

&lt;p&gt;Neither PHP nor Django have a sandbox mode, so keep reading this article to
learn more about this topic.&lt;/p&gt;

&lt;h2&gt;Alternative template languages in PHP&lt;/h2&gt;

&lt;p&gt;So, I started looking for a template engine that has all the features I
mentioned above. I found many different template engines but none satisfied
all my needs. The next sections talk about some of them and some others people
suggested in reply to my tweet.&lt;/p&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  As PHP have a million template engines, I have only tested and benchmarked
  the more "popular" ones. And as I don't use these libraries, the following
  sections can contain wrong information. In such a case, please correct me
  in the comments and I will then fix this post accordingly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Smarty and Smarty 3&lt;/h3&gt;

&lt;p&gt;That's the first one that comes to mind. And Django template language itself
was inspired by &lt;a href="http://www.smarty.net/"&gt;Smarty&lt;/a&gt;. Smarty is the de-facto PHP
standard template engine.&lt;/p&gt;

&lt;pre class="php"&gt;Hello &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="re0"&gt;$name&lt;/span&gt;|escape&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;section name=item loop=&lt;span class="re0"&gt;$items&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
  &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="re0"&gt;$items&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;item&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;|escape&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;/section&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;But Smarty suffers from several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not object oriented&lt;/li&gt;
&lt;li&gt;No template inheritance&lt;/li&gt;
&lt;li&gt;No sandbox mode&lt;/li&gt;
&lt;li&gt;No automatic escaping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As far I understand, Smarty 3 is just around the corner and will improve the
library quite a lot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object oriented architecture&lt;/li&gt;
&lt;li&gt;Auto escaping of variables&lt;/li&gt;
&lt;li&gt;Template inheritance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tested the two versions, but the performance of both are quite bad (see at
the end of this post for more information on the benchmark I did).&lt;/p&gt;

&lt;h3&gt;PHPTAL&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://phptal.org/"&gt;PHPTAL&lt;/a&gt; is a very nice project that implements the Zope
Page Templates syntax. It is very well designed, supports lots of features,
but is unable to render templates besides HTML ones, which can be a problem if
you want to use the same language for emails, RSS feeds, and so on.&lt;/p&gt;

&lt;pre class="xml"&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;?xml&lt;/span&gt; &lt;span class="re0"&gt;version&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;html&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;body&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    Hello &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="re0"&gt;tal:content&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;name&amp;quot;&lt;/span&gt; &lt;span class="re2"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="re0"&gt;tal:repeat&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;item items&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="re0"&gt;tal:content&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/li&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/ul&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/body&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/html&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;Also, I think the syntax is not web designer friendly, especially when you use
advanced features like template inheritance:&lt;/p&gt;

&lt;pre class="xml"&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="re0"&gt;metal:use-macro&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;layout.xml/main&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
 &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="re0"&gt;metal:fill-slot&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
   Hello &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="re0"&gt;tal:content&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;name&amp;quot;&lt;/span&gt; &lt;span class="re2"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
   &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="re0"&gt;tal:repeat&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;a array&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
     &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="re0"&gt;tal:content&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/li&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
   &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/ul&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/body&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/html&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;



&lt;pre class="xml"&gt;&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="re0"&gt;metal:define-macro&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;metal:block&lt;/span&gt; &lt;span class="re0"&gt;define-slot&lt;/span&gt;=&lt;span class="st0"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="re2"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="sc3"&gt;&lt;span class="re1"&gt;&amp;lt;/html&lt;span class="re2"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;One of the biggest selling point of PHPTAL is the autocompletion you can have
in IDEs, and a guarantee that your HTML is well-formed.&lt;/p&gt;

&lt;h3&gt;eZ Components Templates&lt;/h3&gt;

&lt;p&gt;eZ Components &lt;a href="http://www.ezcomponents.org/docs/tutorials/Template"&gt;Template Component&lt;/a&gt;
is also a very nice implementation of a template language. It's probably the
one which have the most features... perhaps too many of them if you ask me:&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;use &lt;span class="re0"&gt;$name&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;use &lt;span class="re0"&gt;$items&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
Hello &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="re0"&gt;$name&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="kw1"&gt;foreach&lt;/span&gt; &lt;span class="re0"&gt;$items&lt;/span&gt; &lt;span class="kw1"&gt;as&lt;/span&gt; &lt;span class="re0"&gt;$item&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
 * &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="re0"&gt;$item&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;/&lt;span class="kw1"&gt;foreach&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;It does not support template inheritance, and my main concern is the
performance. This it is the slowest library I have tested, and by great
margin.&lt;/p&gt;

&lt;h3&gt;Dwoo&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://dwoo.org/"&gt;Dwoo&lt;/a&gt; is an interesting project. It is positioned as an
alternative to Smarty. And they did a great job:&lt;/p&gt;

&lt;pre class="php"&gt;&amp;lt;html&amp;gt;
  &amp;lt;body&amp;gt;
    &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;block &lt;span class="st0"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;/block&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&amp;nbsp;&lt;/pre&gt;



&lt;pre class="php"&gt;&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="kw2"&gt;extends&lt;/span&gt; &lt;span class="st0"&gt;&amp;quot;layout.tpl&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;block &lt;span class="st0"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
  &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;&lt;span class="kw1"&gt;include&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;&amp;quot;basic.tpl&amp;quot;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;/block&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;Dwoo mimics Smarty but with some interesting new features like template
inheritance, and with much better performance than Smarty.&lt;/p&gt;

&lt;p&gt;Unfortunately, Dwoo has no sandbox feature and its core is not flexible
enough.&lt;/p&gt;

&lt;h3&gt;Calypso&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.beberlei.de/calypso/"&gt;Calypso&lt;/a&gt; is an implementation of the Django
Template Language in PHP. I mention it because it's a clone of Django and
because some people mentioned it on Twitter. But, the author himself
acknowledge that the implementation is
&lt;a href="http://www.whitewashing.de/blog/articles/86"&gt;flawed&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Twig&lt;/h2&gt;

&lt;p&gt;When I started looking for a PHP template language, I focused on libraries
trying to mimic the Django template language features. After many hours of
Googling, I found Twig. Twig was written by &lt;a href="http://lucumr.pocoo.org/"&gt;Armin Ronacher&lt;/a&gt;
of &lt;a href="http://jinja.pocoo.org/2/documentation/"&gt;Jinja&lt;/a&gt; fame. Needless to say I
have the uttermost respect for Armin as he does a wonderful job with Jinja.
As a matter of fact, Twig is more similar to Jinja than Django as far as the
&lt;a href="http://lucumr.pocoo.org/2008/9/16/why-jinja-is-not-django-and-why-django-should-have-a-look-at-it"&gt;implementation&lt;/a&gt;
is concerned.&lt;/p&gt;

&lt;p&gt;He wrote &lt;a href="http://github.com/mitsuhiko/twig"&gt;Twig&lt;/a&gt; back in 2008 for
&lt;a href="http://chyrp.net/"&gt;Chypr&lt;/a&gt;, a blogging platform. But he never really developed
it further as he mostly work with Python.&lt;/p&gt;

&lt;p&gt;When I had a look at the code, I was immediately sure it was what I was
looking for. The main difference with Calypso being the fact that Twig
compiles the templates down to plain PHP code. I started to use it a bit and
at the end of last week, I asked Armin if he wouldn't mind letting the project
starts a new life. His answer was enthusiastic, and so I began hacking the
code. My version is much different from that of Armin, but the lexer and
parser are mostly the original ones.&lt;/p&gt;

&lt;p&gt;I have just hacked the code for a few days, but I'm already quite proud of it,
and I think it's time to open it to the public. So, yesterday I wrote some
&lt;a href="http://www.twig-project.org/documentation"&gt;documentation&lt;/a&gt; for it and put up a
simple &lt;a href="http://www.twig-project.org/"&gt;website&lt;/a&gt;. There is still a lot of work
to do like finishing the documentation, adding more unit tests, and PHPdoc,
but the code is already quite solid and feature-full with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Native template inheritance (templates are compiled as classes);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Solid automatic auto-escaping (with no associated runtime overhead as
everything is done during compilation);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Very secure sandbox mode (white-list the tags, filters, and methods that
can be used in templates);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great extensibility: you override everything, even the core features, by
bundling your own tags and filters as an extension; but you can also
manipulate the AST (Abstract Syntax Tree) before compilation. By leveraging
this possibilities, you can even create your own DSL (Domain Specific Language),
targeted at your application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite being one the most full-featured PHP templating engines, Twig is also
the fastest one:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
  &lt;th&gt;Library&lt;/th&gt;
  &lt;th&gt;Time (sec)&lt;/th&gt;
  &lt;th&gt;Memory (Ko)&lt;/th&gt;
  &lt;th&gt;Templates rendered per second&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;Twig&lt;/td&gt;
  &lt;td&gt;3&lt;/td&gt;
  &lt;td&gt;1,190&lt;/td&gt;
  &lt;td&gt;3,333&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;PHPTAL&lt;/td&gt;
  &lt;td&gt;3.8&lt;/td&gt;
  &lt;td&gt;2,100&lt;/td&gt;
  &lt;td&gt;2,632&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Dwoo&lt;/td&gt;
  &lt;td&gt;6.9&lt;/td&gt;
  &lt;td&gt;1,870&lt;/td&gt;
  &lt;td&gt;1,449&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Smarty 2&lt;/td&gt;
  &lt;td&gt;12.9&lt;/td&gt;
  &lt;td&gt;2,350&lt;/td&gt;
  &lt;td&gt;775&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Smarty 3&lt;/td&gt;
  &lt;td&gt;14.9&lt;/td&gt;
  &lt;td&gt;3,230&lt;/td&gt;
  &lt;td&gt;671&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Calypso&lt;/td&gt;
  &lt;td&gt;34.3&lt;/td&gt;
  &lt;td&gt;620&lt;/td&gt;
  &lt;td&gt;292&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;eZ Templates&lt;/td&gt;
  &lt;td&gt;53&lt;/td&gt;
  &lt;td&gt;5,850&lt;/td&gt;
  &lt;td&gt;189&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote class="note"&gt;&lt;p&gt;
  I benchmarked a template that includes a simple template (one output and a for loop on three items) and decorated with a simple layout.
  The times are for the average of ten
  runs; a run consisting of one compilation
  of the template and 10,000 rendering of it. For engines that do not support
  inheritance, I have used a header and a footer instead, and for engines that
  do not support automatic output escaping, escaping has been done by hand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the templates are already compiled, the memory consumption is of course
much better for all template engines, and Twig is the one which uses the less
memory:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
  &lt;th&gt;Library&lt;/th&gt;
  &lt;th&gt;Memory without compilation (Ko)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;Twig&lt;/td&gt;
  &lt;td&gt;383&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;PHPTAL&lt;/td&gt;
  &lt;td&gt;598&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Dwoo&lt;/td&gt;
  &lt;td&gt;1,645&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Smarty 2&lt;/td&gt;
  &lt;td&gt;1,634&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Smarty 3&lt;/td&gt;
  &lt;td&gt;1,790&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Calypso&lt;/td&gt;
  &lt;td&gt;614&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;eZ Templates&lt;/td&gt;
  &lt;td&gt;2,783&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If you want to learn more, please visit the Twig
&lt;a href="http://www.twig-project.org/"&gt;website&lt;/a&gt;, and start discussing Twig on its
dedicated &lt;a href="http://groups.google.com/group/twig-users"&gt;mailing-list&lt;/a&gt;. If you
want to join the team, subscribe to the
&lt;a href="http://groups.google.com/group/twig-devs"&gt;developer&lt;/a&gt; mailing-list&lt;/p&gt;

&lt;p&gt;I have also planned to talk about Twig at the
&lt;a href="http://joind.in/talk/view/959"&gt;Zend UnConference&lt;/a&gt;. Vote for this talk
and see you there for an interesting discussion about templating engines.&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>Swift Mailer Takeover</title>
  <link href="http://fabien.potencier.org/article/33/swift-mailer-takeover" />
  <id>article-33</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-09-16T15:30:00+02:00</updated>
  <content type="html">
    &lt;div style="float: right"&gt;
&lt;img src="http://swiftmailer.org/images/logo.png" alt="Swift Mailer" /&gt;
&lt;/div&gt;

&lt;p&gt;As you might have noticed if you follow me on
&lt;a href="http://www.twitter.com/fabpot"&gt;Twitter&lt;/a&gt;, I'm the new project manager of
&lt;a href="http://www.swiftmailer.org/"&gt;Swift Mailer&lt;/a&gt;, a powerful mailing library for
PHP.&lt;/p&gt;

&lt;p&gt;This is a great honor for me to take over such a project. The Swift Mailer
project has been initiated by Chris Corbyn some years ago. He has done a
wonderful job during the years, trying to find the best way to create a
top-notch emailing solution for PHP. With the release of the 4th version of
Swift Mailer earlier this year, I think we now have a very solid mailing
library. It is one of the most beautiful code I have had the pleasure to read.
Also, the library is feature-rich, object-oriented, and very modular thanks to
its plugin architecture. The good news is that Chris will still work on the
project, so the takeover will be smooth.&lt;/p&gt;

&lt;p&gt;Unfortunately, it seems that Swift Mailer has not been as widespread as it
deserves to be. One of my goal is to spread the word about it, and of course,
if you are looking for a good solution to send emails, try it, you won't be
disappointed. It is already used by companies sending ten of thousands of
emails per hour!&lt;/p&gt;

&lt;p&gt;As a good news never comes alone, as we say in France, Swift Mailer 4 will
also be supported as the default emailing solution as of symfony 1.3.&lt;/p&gt;

&lt;p&gt;I also have lots of ideas to move the project forward. One of them is to
better support the intricacies of Japanese emails. Another one is to have
better documentation, and more people talking about the project.&lt;/p&gt;

&lt;p&gt;Of course I need help. So, if you want to join a great Open-Source project,
visit the Swift Mailer website today, subscribe to the
&lt;a href="http://groups.google.com/group/swiftmailer"&gt;mailing-list&lt;/a&gt;, and help us build
a great PHP library!&lt;/p&gt;
  </content>
</entry>
      <entry>
  <title>Developers should be Artists</title>
  <link href="http://fabien.potencier.org/article/32/developers-should-be-artists" />
  <id>article-32</id>
  <author>
    <name>Fabien Potencier</name>
    <author_email>fabien.potencier@sensio.com</author_email>
  </author>
  <updated>2009-08-25T16:41:00+02:00</updated>
  <content type="html">
    &lt;p&gt;During my holidays, I took the chance to step back a little and think about my
day-to-day work. As the CEO of &lt;a href="http://www.sensiolabs.com/"&gt;Sensio&lt;/a&gt;, I have
the opportunity to do a lot of different jobs. But what I really like to do is
&lt;strong&gt;hacking&lt;/strong&gt;. By hacking, I mean developing software for the fun of it,
software that is not for a "paying" customer. And as such, hacking cannot be a
day job per se. Hacking is something you do on the side. It's a hobby, a
passion. And Open-Source is probably the best way to share your hacks.&lt;/p&gt;

&lt;p&gt;Why do I like hacking so much? Obviously because I'm &lt;em&gt;free&lt;/em&gt; to do whatever I
want, with the tools and the methodology I choose. But more important, because
I have the freedom to do it &lt;em&gt;iteratively&lt;/em&gt; with no schedule pressure. Building
a software is a long iterative process. I love to be able to code something,
forget about it for some time, and come back to it later on to enhance it, or
throw it away altogether. But back to the artist side of things. How much time
do you think Leonardo da Vinci took to paint the Mona Lisa? According to
&lt;a href="http://en.wikipedia.org/wiki/Mona_Lisa"&gt;Wikipedia&lt;/a&gt;, he began painting the
Mona Lisa in 1503 and he is thought to have finished it shortly before he died
in 1519. What? 13 years for just one painting? That's insane. Perhaps, but
that's the way it works for artists. I started developing symfony in 2004, and
it still unfinished in 2009, and probably will never be (and the number of
features has not raised that much in five years). Hacking is an art, and
hackers should act as artists. Hackers and painters have a lot in common but I
won't talk about the analogy too much as Paul Graham wrote an excellent
&lt;a href="http://www.paulgraham.com/hp.html"&gt;essay&lt;/a&gt; and a whole
&lt;a href="http://www.paulgraham.com/hackpaint.html"&gt;book&lt;/a&gt; on this topic. I recommend
you to read both of them if you are a hacker or a developer.&lt;/p&gt;

&lt;p&gt;Hacking is about creating something by using the computer as a medium of
expression. One of the best hacker and artist I know of is &lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff"&gt;&lt;strong&gt;Why the lucky stiff&lt;/strong&gt;&lt;/a&gt;.
From the beautiful camping micro-framework, to the excellent "Poignant Guide
to Ruby" book, he was very prolific and a real artist. I use the past tense,
as he recently &lt;a href="http://ejohn.org/blog/eulogy-to-_why/"&gt;removed&lt;/a&gt; all his online
presence.&lt;/p&gt;

&lt;p&gt;Everyday, I try to learn new ways to write beautiful code in PHP (who's
laughing at me?). You can easily follow my progress by watching the evolutions
of the symfony code, and more recently the
&lt;a href="http://components.symfony-project.org/"&gt;symfony components&lt;/a&gt; code.&lt;/p&gt;

&lt;div style="float: right; padding: 10px"&gt;
  &lt;img src="http://fabien.potencier.org/uploads/stos-punch.jpg" alt="Stos-Punch from ST Magazine page 146" /&gt;
&lt;/div&gt;

&lt;p&gt;If you are looking for more "programming art", I also did some attempts with
&lt;a href="http://twitto.org/"&gt;Twitto&lt;/a&gt; and &lt;a href="http://twittee.org/"&gt;Twittee&lt;/a&gt;, my two
Twitter experiments.&lt;/p&gt;

&lt;pre class="php"&gt;&lt;span class="co1"&gt;// Twitto&lt;/span&gt;
&lt;span class="kw1"&gt;require&lt;/span&gt; __DIR__.&lt;span class="st0"&gt;'/c.php'&lt;/span&gt;;
&lt;span class="kw1"&gt;if&lt;/span&gt; &lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;!&lt;a href="http://www.php.net/is_callable"&gt;&lt;span class="kw3"&gt;is_callable&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$c&lt;/span&gt; = @&lt;span class="re0"&gt;$_GET&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="st0"&gt;'c'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt; ?: &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt; &lt;a href="http://www.php.net/echo"&gt;&lt;span class="kw3"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span class="st0"&gt;'Woah!'&lt;/span&gt;; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;
  throw &lt;span class="kw2"&gt;new&lt;/span&gt; Exception&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="st0"&gt;'Error'&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&lt;span class="re0"&gt;$c&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;&lt;/pre&gt;



&lt;pre class="php"&gt;&lt;span class="co1"&gt;// Twittee&lt;/span&gt;
&lt;span class="kw2"&gt;class&lt;/span&gt; Container &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt;
 protected &lt;span class="re0"&gt;$s&lt;/span&gt;=&lt;a href="http://www.php.net/array"&gt;&lt;span class="kw3"&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;;
 &lt;span class="kw2"&gt;function&lt;/span&gt; __set&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$k&lt;/span&gt;, &lt;span class="re0"&gt;$c&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt; &lt;span class="re0"&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class="me1"&gt;s&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="re0"&gt;$k&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;=&lt;span class="re0"&gt;$c&lt;/span&gt;; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
 &lt;span class="kw2"&gt;function&lt;/span&gt; __get&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$k&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt; &lt;span class="br0"&gt;&amp;#123;&lt;/span&gt; &lt;span class="kw1"&gt;return&lt;/span&gt; &lt;span class="re0"&gt;$this&lt;/span&gt;-&amp;gt;&lt;span class="me1"&gt;s&lt;/span&gt;&lt;span class="br0"&gt;&amp;#91;&lt;/span&gt;&lt;span class="re0"&gt;$k&lt;/span&gt;&lt;span class="br0"&gt;&amp;#93;&lt;/span&gt;&lt;span class="br0"&gt;&amp;#40;&lt;/span&gt;&lt;span class="re0"&gt;$this&lt;/span&gt;&lt;span class="br0"&gt;&amp;#41;&lt;/span&gt;; &lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&lt;span class="br0"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;Back in the early nineties, I did some similar experiments. At that time, the
goal was to do as much as possible in 10 lines of code. I was once published
in the French ST Magazine (August 1990) for a program done is STOS (you can
see the wonderful program in the sidebar).&lt;/p&gt;

&lt;p&gt;If you ask me, a hacker should definitely be an artist. But can a developer
working for a company be an artist? Unfortunately, I don't think so. To be an
artist, you need time and freedom, two essential things you rarely have when
working for a customer.&lt;/p&gt;

&lt;div style="clear: both"&gt;&lt;/div&gt;
  </content>
</entry>
  </feed>
