PHPackages                             torbenkoehn/php-xtpl - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. torbenkoehn/php-xtpl

ActiveLibrary[Templating &amp; Views](/categories/templating)

torbenkoehn/php-xtpl
====================

A Template Engine for PHP

381[10 issues](https://github.com/TorbenKoehn/php-xtpl/issues)PHP

Since Jun 26Pushed 5y ago3 watchersCompare

[ Source](https://github.com/TorbenKoehn/php-xtpl)[ Packagist](https://packagist.org/packages/torbenkoehn/php-xtpl)[ RSS](/packages/torbenkoehn-php-xtpl/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependenciesVersions (1)Used By (0)

What is XTPL?
=============

[](#what-is-xtpl)

XTPL is a **template system for PHP** that doesn't use any fancy, new syntax, but plain old HTML, or rather, XML.

How does it work?
=================

[](#how-does-it-work)

The XTPL **Parser** parses the XTPL file and handles specific nodes, if found. The node plugins are loaded dynamically, which means features like mapping a whole extension over your HTML code that handle new and existing HTML elements are easily possible.

The output you get is **PHTML** which you can include in PHP. PHTML is just **PHP with HTML**, which renders a dynamic, server-side processed HTML page.

If you don't want to handle the PHTML stuff by yourself, XTPL includes a Renderer that also caches for you, if you like.

How to install?
===============

[](#how-to-install)

You can install either via downloading the [ZIP from GitHub](https://github.com/TorbenKoehn/php-xtpl/archive/master.zip) or by using [Composer](http://getcomposer.org/)

To install using composer, you need to add the following info in your `composer.json`

```
{
    "minimum-stability": "dev",
    "require": {
        "php": ">=5.3.0",
        "torbenkoehn/php-xtpl": "*"
    }
}
```

After that just run

```
$ composer install
```

to install the XTPL library and make it available for you to use.

How to use?
===========

[](#how-to-use)

You can either let the XTPL Renderer handle all the work or you can get your hands dirty and do it with the raw API.

The most easy way:

```
    $xtpl = new Xtpl\Renderer;

    $xtpl->displayFile( 'your/path/to/the/xtpl/file', array(
        'title' => 'My Page Title',
        'posts' => array(
            0 => array(
                'title' => 'Some post title',
                'content' => 'bla bla bla bla bla'
            )
        )
    ) );
```

It doesn't matter if you use the `.xtpl`-Extension or not.

Using display like that will `eval()` the code, and as we all know, eval is evil. You better give the renderer a caching directory as the first argument

```
    $xtpl = new Xtpl\Renderer( __DIR__.'/cache' );
```

This directory of course needs to be writable, but this will improve the performance of the system **greatly**.

Using this way, the renderer will handle all the caching on its own, you don't need to do a thing.

If you want to dig in the dirt you can also use the system in a more raw manner, like this:

```
    $xtpl = $xtpl->renderFileToFile( 'your/xtpl', './phtml/your/xtpl.phtml' );
    extract( $yourTemplateArgs );
    include './phtml/your/xtpl.phtml';
```

**Note:** *For anything else, just look the codes above and in the docs below.*

Basic Features
==============

[](#basic-features)

Blocks
------

[](#blocks)

You can define a block and let other blocks add or replace content in it. This works recursively, this means that you can define blocks in a layout template, extend from that and just define the block contents. You can also define blocks and then include the templates that specify the block content.

**my-page.xtpl**

```

	        XTPL is awesome!

	            I'm some placeholder content, I won't stay here.

        My current content

            This might be some static or dynamic content, whatever you prefer.

        	It actually doesn't matter what's in here, you can include stuff, you can have sub-blocks and sub-sub-blocks, XTPL can handle all of it.

```

**Note**: *Indeed, you don't need to close script elements anymore.*

The resulting HTML will be this:

```

        XTPL is awesome!

        My current content

            This might be some static or dynamic content, whatever you prefer.

        	It actually doesn't matter what's in here, you can include stuff, you can have sub-blocks and sub-sub-blocks, XTPL can handle all of it.

```

Notice that the script block got appended, the style block got prepended and the content block replaced the previous content.

The target block is always the first block with its name that the parser finds, all other blocks will add to it (or not)

People who played with Jade already should know this kind of template mechanism.

Extend
------

[](#extend)

Templates can extend other templates. Again, if you're coming from Jade, you should already know the way it works. This does nothing more than putting your current template DOM inside the extended template DOM, but allows for recursive block usage, global main-layouts and stuff like that.

Imagine you have a great main-layout

**layout.xtpl**

```

	        XTPL is awesome!

	            I'm some placeholder content, I won't stay here.

```

and you render a template that extends it

**my-page.xtpl**

```

        My current content

            This might be some static or dynamic content, whatever you prefer.

        	It actually doesn't matter what's in here, you can include stuff, you can have sub-blocks and sub-sub-blocks, XTPL can handle all of it.

```

The resulting HTML will be this:

```

        XTPL is awesome!

        My current content

            This might be some static or dynamic content, whatever you prefer.

        	It actually doesn't matter what's in here, you can include stuff, you can have sub-blocks and sub-sub-blocks, XTPL can handle all of it.

```

There actually is no programatic limitation on how many levels you can extend, how many blocks there are or anything like that. You can extend layouts as many levels deep as you like, even in included XTPLs.

Just try to avoid recursion

**Note**: *No really, recursion will fuck everything up right now I guess.*

Includes
--------

[](#includes)

Include a sub-template. In the sub-template you got access to the template variables as well as the attributes of the include-element.

**my-page.xtpl**

```

```

**navigaton.xtpl**

```

            Home
            About me
            Blog
            Portfolio

    	My Page Header

```

To use the `orientation` attribute in the included template (or any of its extended templates), you use `[[orientation]]` in any attribute or text node, take a look at the `class=""` attribute of the `` element. This also works on templates, that the included template extended. `orientation` is just an example, you can use any attribute name or value you like (You could even load the value of the `file` attribute)

The interpolation with `[[attributeName]]` works on attribute values and plain text nodes.

Variables
---------

[](#variables)

What else, one of the most important parts. There are two ways to use variables inside templates, there is a `` element and you can use interpolation.

### The `` element

[](#the-var-element)

```

```

is the same as

```

```

You can also set

```

```

and you can use default values if the variable isn't set (Which does an automatic `!empty()` check)

```

```

**But this uses the official `` tag, doesn't it?**

Yes it does, but it won't affect it in any way. VarElement only reacts if there is at least a `name` attribute existent (And there is no reason to set one on a normal `` element). Everything else stays plain HTML.

### Interpolation

[](#interpolation)

Variable interpolation works on attribute values and text nodes. Something like `` isn't possible and probably never will be.

```

		Hey, this is some text and I don't want to use a tag now so I just {{output}} my variable named "output" here.

```

**Note**: *If you think it makes sense using interpolation in `` nodes, you can do it, but honestly, it makes no sense. You have access to the variables using plain `$varName` anyways. Even though, in some cases it may make sense, so it works.*

As for attributes, if the variable is the only thing you have in your attribute value and the variable is null or false, it won't render the attribute itself. This is useful for optional classes

```
    My link!
```

if `$link->active` is `null` or `false`, this will render

```
    My link!
```

Actually, this was a lie, it doesn't do this right now, but it will soon.

You can also use default values and callbacks/filters in the expression-way of calling variables.

```

		HEY, THE NEXT TEXT SHOULD ALSO BE {{someText(I dont have a Text):strtoupper:SomeClass.doSomeStaticStuff}}

```

Loops
-----

[](#loops)

There are for and foreach-loops right now. Both work with the `` element.

A simple foreach-loop works like this:

```

                {{post.title}}

                {{item.content}}

```

You might also get the key as a variable with

```

```

The for loops is just a counter currently, you can do something for a limited amount of times and specify a start-point. This is pretty useless right now, since you can't use interpolation for the `times` attribute, but this will surely be changed in the future.

A for-loop works like this:

```

    ({{i}}): Hey, this should happen 5 times!

```

Conditions
----------

[](#conditions)

Yes, they are in now! XTPL supports ``, `` and `` blocks. The latter two always need to be **inside** the `if` element they refer to.

Possible checks via attribute are `empty`, `not-empty`, `set`, `not-set`, `cond` and `not-cond`

`cond` and `not-cond` just translate into plain PHP, it's like defining what's between the `(...)` of the if statement in PHP.

```

    Heeey, we made sure that {{myVar}} is not empty!

```

```

    This gets printed if the condition is true

```

```

    myVar is not set

        myVar is set!

```

It doesn't matter where in the node you put the else/else-if tags, they will always be rendered at the end automatically. This is useful if you want to put your else-block at the top of a large if-block to improve readability.

```

    myVar is not set

        myVar is set!

    and here is some more content
    but this will only be rendered, if the if-block is true!

```

```

    myVar is not set

        myVar is set

        This won't ever be printed.

```

Play with it, get a feeling for it, it actually works!

Inline PHP
----------

[](#inline-php)

You can use PHP-HTML-Tags to use plain PHP inside your template. Through the XML restrictions you have to put complex code into `` tags.

```
	echo $someVariable;

	while( $i < 10 ):
		{{i}}
		$++;
	endwhile;

		//Here you can use any kind of complex PHP code

		class SomeClass {}

		$instance = new SomeClass;
		$instance->something = 'SomeValue';

		var_dump( $instance );

	]]>
```

Processing Instructions
-----------------------

[](#processing-instructions)

You've already seen you can do inline PHP with a tag. Actually, you can also just use the `` syntax in any XTPL file. These are handled as **processing instructions** and are directly converted into elements.

The following processing instructions are available right now:

``Renders into a `` element, which renders a real PHP block in the PHTML file.

``Renders into a valid `` element

``Renders into a valid `` element

Extensions
----------

[](#extensions)

XTPL can be extended in a really easy way.

The parser takes specific namespaces where it gets its nodes from. You can add any namespace you like to provde new or existing, reworked elements to the parser.

Imagine you use a `` tag inside your XTPL file.

The parser goes and looks for a `My\Custom\TagElement` class inside one of its extension namespaces If found, it processes it and renders it as a valid XTPL Node.

Since newly added namespaces always get read first, it's easy to remove complete element namespaces this way. The Bootstrap Extension you read about in the next chapter will give a good example to that.

The default namespaces are the following

`Xtpl\Nodes``Xtpl\Extensions`

To include a new namespace, you can either call `$renderer->addExtension( 'Your\\Extension\\Namespace' );` on the `Xtpl\Renderer`or `$parser->addElementNamespace( 'Your\\Extension\\Namespace' );` on the `Xtpl\Parser`

To enable a XTPL Extension, you call `$renderer->addXtplExtension( 'ExtensionName' )` on the `Xtpl\Renderer`or `$parser->addElementNamespace( 'Xtpl\\Extensions\\ExtensionName' );` on the `Xtpl\Parser`

Usually you should be working with the `Xtpl\Renderer`, just so you know.

Default Extensions
------------------

[](#default-extensions)

While surely you can develop extensions by yourself easily, you don't have to. XTPL actually brings a whole set of new elements into HTML.

You can either activate them by calling them by their complete namespace or you can include a single namespace to map them over your existing HTML.

### Single Extensions (`Xtpl\Extensions`)

[](#single-extensions-xtplextensions)

Single Extensions are simple, single elements that just provide some utility features.

#### Email

[](#email)

The tag `someone@example.com` will be converted into `someone@example.com`

#### Html

[](#html)

The `` tag has a new attribute called `version`. Right now it only supports the value `5`, which makes it automatically add `` in front of your ``-tag.

#### Head

[](#head)

The `` Extension actually just adds the UTF-8 charset by default, if you didn't add one manually.

#### Br

[](#br)

The ``-tag provides a new attribute `repeat`, that does exactly what you think it does. `` will render to ``

This is useful for layouts more often than one might think.

### The Bootstrap Extension (`Xtpl\Extensions\Bootstrap`)

[](#the-bootstrap-extension-xtplextensionsbootstrap)

The Bootstrap Extension is a full set of new HTML elements that provide the whole functionality of Twitter's Bootstrap framework with the easiest markup you've ever seen.

**Note:** *You don't have to load bootstrap by yourself! XTPl actually takes care of that and handles script and CSS requirements for bootstrap automatically. This means, you also got jQuery once you have one bootstrap element in your code. Watch the generated DOM!*

There are two ways to use the bootstrap-extension.

#### Direct Calling

[](#direct-calling)

You can directly call bootstrap extensions by using their namespace. Remember, the `Xtpl\Extensions` namespace is always loaded. With `My shiny button!` you get a fully working Bootstrap-Button that automatically handles anything you do with it.

#### Extension Mapping

[](#extension-mapping)

If you use Bootstrap for your whole project anyways, you can also just map the whole extension namespace over your XTPL file. You can do this by enabling the Bootstrap Extension. Just call `$renderer->addXtplExtension( 'Bootstrap' );` on your `Xtpl\Renderer`

The Bootstrap Extension brings **78 new elements** into your XTPL templates. To see what they can you, you should better check out the following XTPL Templates

\[[https://github.com/TorbenKoehn/php-xtpl/tree/master/templates/bootstrap-extension\](Bootstrap](https://github.com/TorbenKoehn/php-xtpl/tree/master/templates/bootstrap-extension](Bootstrap) Extension Example Templates)

Develop your own extensions
---------------------------

[](#develop-your-own-extensions)

There actually is no documentation on how extension elements work right now. You may just look at the existing Bootstrap-Extension to get a full view of how they are made.

[Boostrap Extension PHP Files](https://github.com/TorbenKoehn/php-xtpl/tree/master/library/Xtpl/Extensions/Bootstrap)

Planned features and fixes
==========================

[](#planned-features-and-fixes)

- Less and CoffeeScript integration
- Markdown Integration
- More dynamic processing instructions
- Improved DOM management in Nodes
- Improved interpolation on fixed value attributes (e.g. `` doesn't work right now)
- Twitter Bootstrap Collapse (Accordion), Carousel and Affix
- More Doc-Types
- More intelligent encoding detection and auto-generation
- More intelligent and nifty single extension elements

Why is it called XTPL?
======================

[](#why-is-it-called-xtpl)

Honestly, because I didn't find any fancy, fitting name yet. Maybe it will always be XTPL, maybe I change it at some time, I don't know

XTPL comes from XML and Template (TPL), which makes it XTPL. Nifty, I know.

I'm open for name suggestions.

I have feedback, I'm interested, I want to contribute, I have a new name for this?
==================================================================================

[](#i-have-feedback-im-interested-i-want-to-contribute-i-have-a-new-name-for-this)

Please send an email to  and inform me.

I'm looking forward to talk to interested people :)

###  Health Score

14

—

LowBetter than 2% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 Bus Factor1

Top contributor holds 66.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/75a80e0830e63c723808d021d3a1648a2643db60f4ac2e40842da05f227f956b?d=identicon)[TorbenKoehn](/maintainers/TorbenKoehn)

---

Top Contributors

[![fellwell5](https://avatars.githubusercontent.com/u/4845418?v=4)](https://github.com/fellwell5 "fellwell5 (2 commits)")[![TorbenKoehn](https://avatars.githubusercontent.com/u/1403556?v=4)](https://github.com/TorbenKoehn "TorbenKoehn (1 commits)")

### Embed Badge

![Health badge](/badges/torbenkoehn-php-xtpl/health.svg)

```
[![Health](https://phpackages.com/badges/torbenkoehn-php-xtpl/health.svg)](https://phpackages.com/packages/torbenkoehn-php-xtpl)
```

###  Alternatives

[mustache/mustache

A Mustache implementation in PHP.

3.3k44.6M291](/packages/mustache-mustache)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[whitecube/nova-flexible-content

Flexible Content &amp; Repeater Fields for Laravel Nova.

8053.0M25](/packages/whitecube-nova-flexible-content)[mopa/bootstrap-bundle

Easy integration of twitters bootstrap into symfony2

7042.9M33](/packages/mopa-bootstrap-bundle)[limenius/react-bundle

Client and Server-side react rendering in a Symfony Bundle

3871.2M](/packages/limenius-react-bundle)[nicmart/string-template

StringTemplate is a very simple string template engine for php. I've written it to have a thing like sprintf, but with named and nested substutions.

2101.7M30](/packages/nicmart-string-template)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
