A Complete List of PHP Template Engines?

Outstanding post.

Does anyone have any criteria to add to this?

A couple of good points there. For the most part, I have already developed the core interfaces. This has been a very evolutionary process based on “how I wanted to use a simple API” as you say.

As mentioned in the SF.net application form, XAO can be used in framework mode, or simply as a library of convenience.

In framework mode, you could have this.


include_once "classes/XAO_DomDoc.php";
$objAppDoc = new DomDoc("xhtml.xsl"); // optional param
$objAppDoc->ConsumeFile("article.docbook.xml");
$objAppDoc->TransformSend();

This is it’s simplest form. In reality, you would inherit the DomDoc class and set up all your application initialisation in the constructor - including an application-wide xslt file if applicable.

note that docbook is a readily available schema you could use for writing articles or whatever other content management (see http://www.docbook.org/ for free online oreilly book)

or how about…


include_once "classes/MyApp.php";
include_once "classes/StarWriter.php";

$objAppDoc = new MyApp();
$objStarDoc = new StarWriter("OpenOfficeRocks.xxx");
$objAppDoc->ConsumeDoc($objStarDoc->objGetDomDoc);
$objAppDoc->TransformSend();

how you like them bickies? :cool:

BTW. Open Office docs (star office) are just zipped XML files. Gee, those “standards” keep popping up everywhere…

You can see why I call it XML Application Objects.

I should call this the “gravity” pattern - if it doesn’t already exist.

Your XML application object ($objAppDoc) sucks up the content from all the other XML objects.

The other XML objects can optionally all be children of the DomDoc class (which the application object is also a child of). In this case, DomDoc class is the single fundamental building block of the app. This is what I meant earlier about centralisation through inheritance. Using an MVC is an purely optional. YOU DON’T HAVE TO USE IT THIS WAY, IT IS ALL OPTIONAL.

here is a very simplistic controller for those who don’t mind being resticted to an MVC request protocol.


include_once "classes/MyApp.php";
$objAppDoc = new MyApp();
if(file_exists("articles/".$_GET["article"].".xml")){
    $objAppDoc->ConsumeFile("articles/".$_GET["article"].".xml");
}
else {
    $objAppDoc->Throw("This page requires a valid request for an article.");
}
$objAppDoc->TransformSend();

you could hide the controller stuff inside the MyApp constructor’


include_once "classes/MyApp.php";
$objAppDoc = new MyApp($_GET);
$objAppDoc->TransformSend();

As far as reinventing the wheel is concerned, I don’t see anything wrong in having 50, 60, or even 100 templating engines/languages out there. So what? How does that hurt us? I guarantee if all those developers got together, it wouldn’t make a difference. Each one developed their template engine for a reason. Whether that reason was to learn how to make one, just for fun, because they couldn’t find features in another one and it was too difficult to modify, or maybe they even thought they could do it better.

No it doesn’t hurt but I think when a particular wheel gets re-invented as many times as the template engine, it’s interesting to ask why. More to the point, while building the list, I took a quick look at the examples and off the top of my head, at least 70% are “Smarty style” in that they have some kind of imperative syntax. Another 20%ish use HTML comments. In other words people are coming up with the same solution to the problem. Also the word “simple” appears with great frequency…

My guess as to why most of these template engines came into being is the authors took a look at what was already available and found it too complex / difficult to use then though “How hard can it be to replace a variable marker?” and wrote their own. But any template system that stays the course then needs to find some way to introduce “loops” and possibly conditional elements to the template syntax. Then perhaps they start introducing some kind of macro to allow for “re-usable HTML” and possibly re-invent the include statement and pretty soon it’s as complex as the template system they were originally trying to avoid using.

So the question is can a template engine be designed that will suit everyone (or at least the majority) - one which offers such “value” that people no longer feel the need to re-invent it?

One area where I do see as a problem is, aside from PHP itself and Interakts Dreamweaver add ons, none of these template engines is supported by a deskop design tool. Being more specific, the “macro” features delivered by some like Smarty (e.g. the table function) are not supported. When you compare that something like ASP.NET’s [url=http://www.asp.net/webmatrix]webmatrix, you’ve got a drag and drop editor which allows you to drag something like a Calendar onto your page (the Calendar perhaps being made up of a particular table structure).

Personally I think that’s important because the “weight” of any PHP application is not the PHP code itself but the markup used for the user interface. If you look at the various petstore debates the equation was the same - most of the “lines of code” were in the templates; i.e. the HTML.

Not quite sure how to phrase it but perhaps a point add to the list of what a good template engine should do is something like;

  1. Reduces the effort required build the templates.

The might also be re-phrased as “allows for re-usable user interface components”.

In other words rather than;


<table>
<caption>{month} {year}</caption>
<tr>
<th>{1stDayOfWeek}</th>
<th>{2ndDayOfWeek}</th>
<th>{3rdDayOfWeek}</th>

etc. etc.

Instead you just have;


<calendar />

First, #8 is covered under Simplicity. If the template engine makes something simple, it’s also reducing the effort. If it’s difficult to do something, even if the syntax is simple, the template is not simple. At least, that’s my take, and how I interpret what I wrote, heh.

In response to your first paragraph, you make an interesting statement regarding how template languages look. Some using an imperative syntax, and some using HTML comments.

However, I believe both approaches are wrong.

A better way would be something like this:


<!-- IF isFormError -->
        <dl>
        <!-- LOOP ON FormErrors FOR EACH Error -->
                <dt>{Error.Name}</dt>
                <dd>{Error.Description}</dd>
        <!-- END LOOP -->
        </dl>
<!-- END IF -->

It mixes the two together. It passes the Dreamweaver test, it’s simple. I haven’t tested it, but it should validate. Assuming the template engine would compile this down to PHP (that sounds funny, compiling ‘down’ to PHP), it’s cacheable. As far as being self-inspecting, secure, and flexible, well that’s more an engine implementation.

However, some potential problems arrise:


<!-- IF isFormError -->
        <dl>
        <!-- LOOP ON FormErrors FOR EACH Error -->
                <!-- ALTERNATE color BETWEEN 'red' AND 'blue' -->
                <dt style="color: {color}">{Error.Name}</dt>
                <dd>{Error.Description}</dd>

        <!-- END LOOP -->
        </dl>
<!-- END IF -->

Okay, pretty straight forward, and something that is easily parsed and compiled. Howver, you run into a problem with the use of color: {color}.

Simply put, it fails the Dreamweaver test.

Hrm… got me thinking though.

Having gained some experience from being on the XSL mailing list, I should point out that XSLT processor performance is also greatly affected by the XSL code itself. For instance, you can create ineficient XPath queries very easily if you are an XSL newbie. Of course this usually only comes into play if your XML datasources become large.

That is very true.

This is getting to be a hot topic although I think a lot of people taking part forget the point to XSL ?

Okay, XSL-T isn’t an applied Templating mechanism though with XML you can implement it as one, regardless of the definition of what an actual Template is…

But my point is that XSL was not originally meant for templating - it was meant to transform one form of data to another and it does it well, in an easy and structured manner.

Okay, some folks have great difficulty in learning XSL-T but so what ? This isn’t to say there is a problem with the technology just because Job Blogs on Floor 14 can’t understand the process of using XML and XSL for example is it ?

Folks… We need XML and XSL-T. Simple as that really, regardless of what you use it for or how, we need this technology.

As stated earlier as well I can agree that there are badly design XSL stylesheets out there, though you need to remember that there is usually more than one solution to the same problem in the sense of how you design a stylesheet ?

:smiley:

HarryF

In other words rather than;
Code
<table> <caption>{month} {year}</caption> <tr> <th>{1stDayOfWeek}</th> <th>{2ndDayOfWeek}</th> <th>{3rdDayOfWeek}</th>
etc. etc.

Instead you just have;
Code
<calendar />


Exactly :slight_smile: Instead then of referring to a variable or data, you refer to the actual script which displays the calendar ?

I had done the same thing myself. I would put a well formed XML tag in the XML template and once my script found this tag, it’d create the compontent dynamically, not based on data from the template but from script.

About both the same idea I think ?

How about ColdFusion’s take on this issue? OK, it’s not MVC pure, but it does seem designer friendly. That said, I’m currently developing a conceptually similar approach with PHP. At the moment I use SAX to parse the XML template file and take the appropriate actions. Eventually I’ll use HTMLSax (thanks HarryF)…

Some might argue that this approach will mix logic with presentation, they’re right… but imo it all depends on how you allow this and how ‘designer friendly’ it is. If you look at Smarty for example, it clearly lets you mix logic in there, furthermore imo not at all in a nice way…

I guess my approach is a mixture syntacticly somewhere between ColdFusion CFML and XSLT…

  • prefab

<!-- example of assoc array iteration -->
<ff_loop sid="arrayloop" src="myArray" scope="special"/>

<!-- applies to all -->
<ff_outputfilter sid="arrayloop" filter="substr" offset="0" length="4"/>

<ff_filterset sid="arrayloop" prop="name">
	<ff_outputfilter _assign="testing" filter="substr" offset="2" length="10"/>
	<ff_outputfilter filter="format" format="value %s"/>
	<ff_outputfilter filter="upper"/>
</ff_filterset>

<ul>
<ff_output sid="arrayloop" alternate="red|orange|green" offset="#get.offset#" limit="5">
	 <li style="color: #_alternate_#">#_counter_# #_key_# #_value_# #_alternate_#</li>
</ff_output>

<ff_outputelse sid="arrayloop">
	 <li>no results</li>
</ff_outputelse>
</ul>

Jason - have to refer you to the WACT Wiki on the TemplateView which is turning out to be the most insightful study of templates I’ve seen. Also, hope you don’t mind but added you template criteria as [url=http://wact.sourceforge.net/index.php/GoodTemplateSmells]Good Template Smells.

Although templates and the word “simple” often appear in the same sentence, think this discussion is already proving (as has been done before) that there’s no simple answers and many different points of view. Hopefully the TemplateView is starting to identify the “problem” precisely, which is important step towards a better solution.

Some might argue that this approach will mix logic with presentation, they’re right…

Have to pick that one up - this is one of the “fine details” of discussing template which is too easy to describe carelessly.

Put simply all templates have logic - i.e. there is always logic in the presentation logic. Whether it’s imperative (PHP control structures / Smarty logic etc.) or declarative with the logic being “disguised” by an XML tree structure (like ASP.NET), it’s still logic. There’s no getting away from it.

Put practically the moment you want to generate the rows of a table, you need some form of “loop” which gets “repeated” whether it’s;


<table>
{loop:results}
<tr>
<td>{data}</td>
</tr>
{/loop:results}
</table>


<table>
<!-- Loop:results -->
<tr>
<td><!--data--></td>
</tr>
<!-- EndLoop:Results -->
</table>

Or


<table>
<tr id="results" runat="server">
<td><%=data%></td>
</tr>
</table>

Not a problem. Actually, I have been looking at that wiki for a few days, just didn’t read the section that described the method I discussed (I just read over it…go figure).

Also, no problem in adding it to the Good Template Smells section. I am glad to see other people find it useful. =)

This is a good way to illustrate the difference between an imperative and declarative custom tag approach to embedding presentation logic in a template.

Here is the declarative equivalent from WACT:

<ErrorSummary>
    <ul>
        <list:ListItem>
            <li>{$ErrorMessage}
        </list:ListItem>
    </ul>
</ErrorSummary>

Advantages

  • The custom ErrorSummary tag helps to capture more of the semantics of the template fragment. ErrorSummary captures the purpose or intent of what is being done. Programming code elsewhere determines the how.
  • Reduces duplication of effort in templates. (as procedures or classes do in programming code.)
  • The ErrorSummaryComponent that this tag is attached to provides a centralized place to attach logic for that purpose. This means that for some changes, you can make a change in one place instead of everywhere the template fragment is used.
  • Descriptive declarative tags are easier to global search and replace on.
  • This approach limits what it is possible for the html designer to do.
  • Syntax is simpler for complex examples.

Disadvantages

  • It is more difficult to create a new tag or new component than it is to put another IF or LOOP into the template.
    (although with WACT, you can create a new tag and use it in an application’s templates without changing either the framework or the application in any way. Unfortunately this currently takes more programming skill than few simple IF or LOOP statements.)
  • Immaturity of PHP component based libraries means few existing tags and components to choose from.
  • This approach limits what it is possible for the html designer to do.
  • Feels constraining to programmers.

Hope I’m not getting too far off topic.

As long as you are already intent on re-inventing the wheel again :wink:

May I make a suggestion…

instead of using ff_ as a prefix, why not use a valid namespace such as


<ff:outputelse>

namespaces in XML were designed to provide the sort of scope management you are trying to achieve. If you do it the standards way, there will likely be more opportunities to enhance the technology.

You’re right Harry, this really is a problem - FOR PROPRIETARY TEMPLATE SYSTEMS. As I’ve mentioned before, there are already many WYSIWYG tools for working with content in XML/XSLT.

So far, all this talk about DreamWeaver support has centrered around the ability for a content editor to use DreamWeaver to edit the content without the proprietary template system being affected - “the dreamweaver test”. How come everyone is ignoring the fact that there are already many content editors (such as XMetal) that allow you to edit your content as WYSIWYG with your standards based XSLT template applied.

The editor loads the XSLT template in the background to determin the WYSIWYG at runtime.

There are waaayyyyy to many to list all of them…

So far I’ve just been talking about content authoring. Well how about developing new templates? How many of you can claim that even one software package out there helps users develop templates in your syntax - ie. generate your proprietary format?
Well since XSLT is a standard, some XSLT creation tools already exist. The best one I know of is by altova. There’s bound to be more as time goes by. That is because XSLT has a future unlike the 70 odd non-standard attempts out there.

Talk about tools!

Ain’t no problem for people who use XSLT as their templating system.

Ahem… and who designs the calendar widget???


<s:call-template name="calendar"/>

The designer designs the calendar widget.

nuff said.

An excellent, excellent point my friend. I’m glad you pointed this out.

There is no way I’m going to pretend that XSLT does not have the potential to be complex/sophisticated. But I will say this.

The difficulty level for the average sight-designer is “scalable”. That is to say, they can bite off as much as they feel that they can chew. This is how I started. It’s the same with everything. You begin with “Hello World” and then you learn only the bits that you need. This is not a new concept and XSLT is no different.

I think the problem for XSLT, in PHP specifically, is more one of infrastructure. “How do I integrate it easily into the flow of my program and deal with potential exceptions.” It’s only a matter of time before that problem is overcome (if it isn’t already).

I’ve registered a project on sf.net to address this and should have an intro page up by the end of the day.

Well not entirely - we had an example of how an ASP.NET Calendar and how it might “bind” to an underlying PHP class here while looking at [url=http://www.sitepointforums.com/showthread.php?threadid=112379]Parsing ASP.NET templates with PHP.

Looking at that example, the “template” was;


<asp:Calendar
    id="cal"
    SelectionMode="DayWeekMonth"
    ShowGridLines="true"
    ShowNextprevMonth="true"
    CellPadding="7"
    CellSpacing="5"
    DayNameFormat="FirstTwoLetters"
    FirstDayOfWeek="Monday"
    NextPrevFormat="CustomText"
    NextMonthText="Next
    >"
    PrevMonthText="<
    Prev"
    onSelectionChanged="SelectionChanged"
    onDayRender="DayRender"
    onVisibleMonthChanged="VisibleMonthChanged"
    DayHeaderStyle-BackColor="Black"
    DayHeaderStyle-ForeColor="White"
    DayHeaderStyle-Font-Name="Arial
    Black"
    runat="server">

    <DayStyle
    BackColor="White"
    ForeColor="Black"
    Font-Name="Arial"
    />

    <NextPrevStyle
    BackColor="DarkGray"
    ForeColor="Yellow"
    Font-Name="Arial"
    />

    <OtherMonthDayStyle
    BackColor="LightGray"
    ForeColor="White"
    Font-Name="Arial"
    />

    <SelectedDayStyle
    BackColor="CornSilk"
    ForeColor="Blue"
    Font-Name="Arial"
    Font-Bold="true"
    Font-Italic="true"
    />

    <SelectorStyle
    BackColor="CornSilk"
    ForeColor="Red"
    Font-Name="Arial"
    />
</asp:Calendar>

Now that’s fairly verbose but there’s still no need to get bogged down in HTML tables - as you can see it’s fairly “readable” - from the tag and attribute names it should be fairly clear how it effects the output. That’s all a designer needs to do to customize the appearance of a “calendar widget” (plus they’d be using webmatrix or Visual Studio so be able to drag and drop anyway).

There’s a tutorial on O’Rielly about creating custom ASP.NET controls which might give a feel for how it works.

Actually, I think the main attraction to leveraging the XSLT standard for your templating system is if you work in a team. As the backend PHP developer, you can easily implement something like XML Application Objects (in framework mode) to aggregate content and your own objects to process imput (XAO may eventually get a form input parser object). Then your gumby graphic designers can use a tool like stylevision ( http://www.altova.com/products_xsl.html ), if they are not already XHTML markup savvy, to design the stylsheets. All you have to do is point to the stylsheets.

If you’re really clever, you’ll have one stylsheet (the controller for your presentation logic) which calls/applies templates from other IMPORTed template definitions. But you don’t have to do this if you feel it is too complicated. You have the choice to KISS.

Now this is how you build enterprise applications - using standards.

BTW. You can use the same library (XAO) to aggregate content from a variety of sources (as illustrated in my actual code examples which everyone seems to have no comment on) - including DBMS (using the DB2XML class), RSS, XML-RPC (SOAP), Xindice (pure XML databse), and good 'ol flat files (includung Open Office documents). What more do you want???

And then one day when you have to migrate all your stuff to Java or .NET (because it’s trendy), you can keep all those XSL files and re-use them (and possible do an object-for-object code port for the backend). Or better yet, use an XSLT file to export SOAP packets so they can access your PHP app via XML-RPC rather than port the whole app across. In this case, the XSLT will save you from having to write more code to produce payload for a different kind of client (which is the remote app). How good is that???

Dr Livingston is right - “we need this people”.

OK, I see how this works.

What is hidden [from this post] is the details for how your .NET library (or your PHP alternative) will build the layout.

You are claiming that I don’t have to stuff around with tables and what not. Well this may be true but someone has built this in a library on the backend somwhere - this is a backend widget designed by a programmer.

What’s to stop an XSLT person from utilising a library which included a calendar template? Then they woudln’t have to stuff around with tables either. All they would have to do is call it using <lalala:call-template name=“myCalendarWidgetV3”/>

Now, wouldn’t it be nicer if mr designer had access to the source of the widget if they needed to tweak it? Also, they would then see that the widget used class attributes in the XHTML literals so the developer could quickly make a CSS file which is how the styles should be applied.

Now when the designer calls the template, the only parameters they will need to pass are logical ones like which day/week/month to display as current. The APPEARANCE attributes (as opposed to the display semantics) can be left to the CSS file - which I do believe is another standard (that XSLT does not impinge on).


<l:call-template name="myCalendarWidgetV3">
    <l:param name="scope" select="'month'"/>
    <l:param name="current" select="'august'"/>
</l:call-template>

now the colours and font sizes are dependent on the rendering platform. In this case, the rendering platform is HTML based. So for HTML, the correct way to specify these details is CSS.

The DreamWeaver test applies to editing the templates in a WYSIYWG editor, not the content.

Well how about developing new templates? How many of you can claim that even one software package out there helps users develop templates in your syntax - ie. generate your proprietary format?

Well, I’ve used the “Edit Tag Library…” command of DreamWeaver to enter the custom tags and attributes from WACT (via a GUI). Now when I edit WACT templates in DW, it can autocomplete closing tags and attribute values for the custom tags. I also entered formatting rules for the custom tags so the “Apply Source Formatting” command understands the new tags. My new tags appear in DW’s 'Insert Tag…" command. I can also highlight my custom tags from the little tag breadcrumbs widget at the bottom of the editing window.

ASP.NET and Java Server Pages both allow you to create custom tags. I expect that editor support for custom tags will only improve in the future.

A little googling turned up a dreamweaver custom tag library for Xaraya.

Well DW “understands” your new tags to a point but it’s not going to have your template engine built into the editor so that it can fully translate tags such as the <calendar/> example. The other content authoring tools (like XMetal and Authentic) actually do have an XSLT processor built into them so they can translate the WYSIWYG in real-time while you edit. What you are talking about is not the same thing.

also, in terms of getting DW to insert custom tags, I can do that with a non-gui text editor too like Homesite. Just because DW can insert those tags doesn’t mean it can translate it to look how it will end up on the finished rendered page - otherwise what is a WYSIWYG editor like DW good for?

Stylevision on the other hand can do exactly this. It can generate XSLT and it can also WYSIWYG it in real-time.

bully for them. Using custom tags for display widgets just means you lose your decoupling between the domains (display and content generation). Using custom tags to encapsulate server-side business functionality is a different thing, and in that case, it’s not even applicable as layout/design templates.

Here’s an example of where a custom tag would be useful. You make a custom tag, say <faqItem id=“foo”/> which fetches the content of an FAQ record in the database. Now to avoid having this tangled up in the database, your templating engine does NOT render this as some pre-set, inflexible, encased, hard-coded, dead-end HTML. Your template parser produces something like the following instead:


<faqItem id="foo">
    <faq>Why are there so many template languages for PHP?</faq>
    <answer>Sadly, many PHP developers haven't taken the time to understand XML.</answer>
</faqItem>

then you use arbitary (NOT(pre-set, inflexible, encased, hard-coded, dead-end)) XSLT to produce whatever the hell output THE DESIGNER wants.

Now you might say doing this just adds another layer. Well, you’d be right. Which is why I tend to get all the conent I need in one hit (without parsing some external file for custom tags) and then sending it through the transformer (format router) consumption by the client. But hey, if you chose to use custom tags, that’s cool, choice is good. But try not to let them muck up your abstraction layers by confusing them with display logic. Using them for content expansion is fine, but they are not a solution for display logic abstraction.