PHPackages                             snicco/templating - 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. snicco/templating

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

snicco/templating
=================

Provides a unified API for various templating engines.

v1.10.1(1y ago)016.6k4LGPL-3.0-onlyPHPPHP ^7.4|^8.0

Since Apr 17Pushed 1y ago1 watchersCompare

[ Source](https://github.com/snicco/templating)[ Packagist](https://packagist.org/packages/snicco/templating)[ RSS](/packages/snicco-templating/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (35)Used By (4)

Snicco-Templating: A uniform API around various PHP template engines.
=====================================================================

[](#snicco-templating-a-uniform-api-around-various-php-template-engines)

[![codecov](https://camo.githubusercontent.com/a99e6ec528fffd1664e95534f9a09a4a09d2afe62799ff0d8774dc22d8453f6c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f7665726167652d3130302532352d73756363657373)](https://codecov.io/gh/snicco/snicco)[![Psalm Type-Coverage](https://camo.githubusercontent.com/c12cfed65c7da16501f7a84e7861b8c4757fc30e9dc00bb2983783dbb3f3f84c/68747470733a2f2f73686570686572642e6465762f6769746875622f736e6963636f2f736e6963636f2f636f7665726167652e7376673f)](https://shepherd.dev/github/snicco/snicco)[![Psalm level](https://camo.githubusercontent.com/c5e90ffcf3a5aa1f78f93bddde5db7627b114329393aa87697df8cedc7f5391a/68747470733a2f2f73686570686572642e6465762f6769746875622f736e6963636f2f736e6963636f2f6c6576656c2e7376673f)](https://psalm.dev/)[![PhpMetrics - Static Analysis](https://camo.githubusercontent.com/364ffb28ea219affd0fed2e99cc046bac0bf41da3f1d3814e0cbe4a4bb54c994/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5068704d6574726963732d5374617469635f416e616c797369732d326561343466)](https://snicco.github.io/snicco/phpmetrics/Templating/index.html)[![PHP-Versions](https://camo.githubusercontent.com/241a10d25aa09d5e8a82ebd2b55780a63dd43736d958d4004c3166e650874aca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545372e34253743253545382e30253743253545382e312d626c7565)](https://camo.githubusercontent.com/241a10d25aa09d5e8a82ebd2b55780a63dd43736d958d4004c3166e650874aca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545372e34253743253545382e30253743253545382e312d626c7565)

The **Templating** component of the [**Snicco** project](https://github.com/snicco/snicco) provides a simple, object-oriented API around popular **PHP** template engines.

Table of contents
-----------------

[](#table-of-contents)

1. [Installation](#installation)
2. [Usage](#usage)
    1. [Overview](#usage)
    2. [Creating a view](#creating-a-view)
    3. [Directly render a view](#directly-rendering-a-view)
    4. [Finding the first existing view](#finding-the-first-existing-view)
    5. [Referencing nested directories](#referencing-nested-directories)
    6. [Global context / View composers](#global-context--view-composers)
    7. [View factories](#using-view-factories)
    8. [The PHPViewFactory](#the-phpviewfactory)
        1. [Instantiation](#instantiation)
        2. [Template inheritance](#template-inheritance)
3. [Contributing](#contributing)
4. [Issues and PR's](#reporting-issues-and-sending-pull-requests)
5. [Security](#security)

Installation
------------

[](#installation)

```
composer require snicco/templating
```

Usage
-----

[](#usage)

This package consists of the following main components:

- An **immutable** [`View`](src/ValueObject/View.php) object, which can be rendered to its string representation with a given `context`.
- The [`TemplateEngine`](src/TemplateEngine.php), which is a facade class used to create and render [`View`](src/ValueObject/View.php) objects.
- The [`ViewFactory` interface](src/ViewFactory/ViewFactory.php), which abstracts away implementation details of how a `View` instance is rendered. See [Using view factories](#view-factories);
- The [`ViewContextResolver`](src/Context/ViewContextResolver.php), which is responsible for adding global `context` and view composer `context`to a view that is being rendered.

The following directory structure is assumed for the examples in this README:

```
your-project-root
├── templates/
│   ├── users/
│   │   ├── profile.php
│   │   └── ...
│   └── hello-world.php
└── ...

```

```
// ./templates/hello-world.php

echo "Hello $first_name";
```

---

### Creating a view

[](#creating-a-view)

An instance of [`View`](src/ValueObject/View.php) is always created by a call to `TemplateEngine::make()`.

Context can be added to a [`View`](src/ValueObject/View.php) instance which will be available to the underlying template once the [`View`](src/ValueObject/View.php) is rendered.

```
use Snicco\Component\Templating\TemplateEngine;

// The TemplateEngine accepts one or more instances of ViewFactory.
// See #Using view factories for available implementations.
$view_factory = /* */

$engine = new TemplateEngine($view_factory);

// hello-world is relative to the root directory "templates"
$view = $engine->make('hello-world');

$view1 = $view->with('first_name', 'Calvin');
$output = $engine->renderView($view1);
var_dump($output); // Hello Calvin

$view2 = $view->with('first_name', 'Marlon');
$output = $engine->renderView($view2);
var_dump($output); // Hello Marlon

// Views can also be created by passing an absolute path
$view = $engine->make('/path/to/templates/hello-world.php');
```

---

### Directly rendering a view

[](#directly-rendering-a-view)

If you want to render a template right away you can use the `render` method on the [TemplateEngine](src/TemplateEngine.php).

```
use Snicco\Component\Templating\TemplateEngine;

$view_factory = /* */

$engine = new TemplateEngine($view_factory);

$output = $engine->render('hello-world', ['first_name' => 'Calvin']);
var_dump($output); // Hello Calvin
```

---

### Finding the first existing view

[](#finding-the-first-existing-view)

Both the `make` and `render` method of the [TemplateEngine](src/TemplateEngine.php) accept an `array` of strings in order to use the first existing view.

```
use Snicco\Component\Templating\TemplateEngine;

$view_factory = /* */

$engine = new TemplateEngine($view_factory);

$view = $engine->make(['hello-world-custom', 'hello-world']);

$output = $engine->render(['hello-world-custom', 'hello-world'], ['first_name' => 'Calvin']);
var_dump($output); // Hello Calvin
```

If no view can be found, a [`ViewNotFound`](src/Exception/ViewNotFound.php) exception will be thrown.

---

### Referencing nested directories

[](#referencing-nested-directories)

Both the `make` and `render` method of the [TemplateEngine](src/TemplateEngine.php) will expand dots to allow directory traversal. This works independently of the concrete [ViewFactory](#usage) that is being used.

```
use Snicco\Component\Templating\TemplateEngine;

$view_factory = /* */

$engine = new TemplateEngine($view_factory);

$view = $engine->make('users.profile');

$output = $engine->render('users.profile', ['first_name' => 'Calvin']);
```

---

### Global context / View composers

[](#global-context--view-composers)

Before a view is rendered, it's passed to the [`ViewContextResolver`](src/Context/ViewContextResolver.php), which is responsible for applying:

1. global `context` that should be available in all views
2. `context` provided by view composers to **some views**

A view composer can be a `Closure` or class that implements [`ViewComposer`](src/Context/ViewComposer.php).

The [`ViewContextResolver`](src/Context/ViewContextResolver.php) will be needed to instantiate the concrete implementations of the view factory interface.

**Adding global context:**

```
use Snicco\Component\Templating\Context\ViewContextResolver;
use Snicco\Component\Templating\Context\GlobalViewContext;

$global_context = new GlobalViewContext()

// All templates now have access to a variable called $site_name
$global_context->add('site_name', 'snicco.io');

// The value can be a closure which will be called lazily.
$global_context->add('some_var', fn() => 'some_value');

$context_resolver = new ViewContextResolver($global_context);
```

If you pass an `array` as the second argument to `GlobalViewContext::add` you can reference nested values in your views like so:

```
use Snicco\Component\Templating\Context\ViewContextResolver;
use Snicco\Component\Templating\Context\GlobalViewContext;

$global_context = new GlobalViewContext()
$global_context->add('app', [
   'request' => [
       'path' => '/foo',
       'query_string' => 'bar=baz'
   ]
]);

// Inside any template
echo $app['request.path']
echo $app['request.query_string']
```

**Adding view composers:**

```
$context_resolver = /* */

// Using a closure
$context_resolver->addComposer('hello-world', fn(View $view) => $view->with('foo', 'bar'));

// Using a class that implements ViewComposer
$context_resolver->addComposer('hello-world', HelloWorldComposer::class);

// Adding a composer to multiple views
$context_resolver->addComposer(['hello-world', 'other-view'], fn(View $view) => $view->with('foo', 'bar'));

// Adding a composer by wildcard
// This will make the current user available to all views inside the templates/users directory.
$context_resolver->addComposer('users.*', fn(View $view) => $view->with('current_user', Auth::user()));
```

---

### Using view factories

[](#using-view-factories)

All view factories implement the [`ViewFactory`](src/ViewFactory/ViewFactory.php) interface.

They are used by the `TemplateEngine` and contain the underlying logic to render a `View` instance to its string representation.

It's possible to use multiple view factories together in which case the first factory that can render a given `View`will be used.

The following view factories are currently available:

- [`PHPViewFactory`](src/ViewFactory/PHPViewFactory.php), included in this package. A bare-bones implementation that works great for small projects with only a handful of views.
- `BladeViewFactory`, included in a [separate package](https://github.com/snicco/blade-bridge). Integrates Laraval's **Blade** as a standalone template engine with this package, while retaining all features of both.
- `TwigViewFactory` - coming soon.

---

### The `PHPViewFactory`

[](#the-phpviewfactory)

The [`PHPViewFactory`](src/ViewFactory/PHPViewFactory.php) is a bare-bones implementation that is great for small projects where you might only have a handful of views.

#### Instantiation

[](#instantiation)

The [`PHPViewFactory`](src/ViewFactory/PHPViewFactory.php) takes a [`ViewContextResolver`](#global-context--view-composers)as the first argument and an `array` of **root** template directories as the second argument.

If a view exists in more than one template directory, the first matching one will be used. This is great for allowing certain templates to be overwritten by templates in another (custom) template directory.

```
use Snicco\Component\Templating\TemplateEngine;
use Snicco\Component\Templating\ViewFactory\PHPViewFactory;

$context_resolver = /* */

$php_view_factory = new PHPViewFactory(
    $context_resolver,
    [__DIR__.'/templates']
);

$template_engine = new TemplateEngine($php_view_factory);
```

#### Template inheritance

[](#template-inheritance)

The [`PHPViewFactory`](src/ViewFactory/PHPViewFactory.php) allows for very basic template inheritance.

**Assuming that we have the following two templates:**

```

        Head content goes here
