gigablah / silex-view
Engine-agnostic view component for Silex
Requires
- silex/silex: ~1.0
Requires (Dev)
- aura/view: ~1.2
- mustache/mustache: ~2.4
- phpunit/phpunit: ~3.7
- smarty/smarty: ~3.1
- twig/twig: ~1.0
This package is auto-updated.
Last update: 2024-11-24 04:21:40 UTC
README
The ViewServiceProvider gives engine-agnostic templating capabilities to your Silex application.
Installation
Use Composer to install the gigablah/silex-view library by adding it to your composer.json
. You'll also need a rendering engine, such as Mustache.
{ "require": { "silex/silex": "~1.0", "mustache/mustache": "~2.4", "gigablah/silex-view": "~0.0.1" } }
Usage
Just register the service provider and optionally pass in some defaults.
$app->register(new Gigablah\Silex\View\ViewServiceProvider(), array( 'view.globals' => array('foo' => 'bar'), 'view.default_engine' => 'mustache' ));
The provider registers the ArrayToViewListener
which intercepts the output from your controllers and wraps it with a View
object. For it to work, you have to return an array of data from your controller function.
Views
Normally you do not need to instantiate any view entities on your own; the listener will convert your controller output. If you wish to do it manually, the syntax is as follows:
$view = $app['view']->create($template = '/path/to/template', $context = array('foo' => 'bar'));
Views can be rendered by calling the render()
function, or casting to string:
$output = $view->render(); $output = (string) $view;
Again, you should not need to render your views manually since they will be handled by the Response
object.
View Context
The view entity is simply an instance of ArrayObject
, so you can use regular array notation to set the context, along with convenience functions like with()
:
$view['foo'] = 'bar'; $view->with(array('foo' => 'bar'));
To insert into the global context, use share()
:
$view->share(array('foo' => 'bar'));
You can initialize the global context by overriding view.globals
.
Resolving Templates
How does the listener know which template to use? By default it reads the _route
attribute from the request entity in lowercase, and appends the extension based on the value of view.default_engine
. Some examples:
$app->get('/foobar', function () {}); // get_foobar.mustache $app->get('/', function () {}); // get_.mustache $app->match('/', function () {}); // _.mustache
Since you probably want more descriptive template names, you can use named routes:
$app->match('/', function () {})->bind('home'); // home.mustache
You can also set the _template
attribute in the request, or as part of the controller output:
$app->get('/foo', function (Symfony\Component\HttpFoundation\Request $request) { $request->attributes->set('_template', 'foo.html'); }); $app->get('/bar', function () { return array('_template' => 'bar.html'); });
If you need custom logic for generating template paths, you can create your own class that implements TemplateResolverInterface
and override view.template_resolver
.
Engines
This library does not handle any actual view rendering; that task is delegated to the templating library of your choice. Currently adapters are provided for:
There is a special DelegatingEngine
which acts as a registry for multiple different engines, selecting the appropriate one based on the template file extension. Since Aura.View, Plates and Raw PHP all use the same default file extension (.php), you will need to manually configure the extension mapping as follows:
$app->register(new Gigablah\Silex\View\ViewServiceProvider(), array( 'view.default_engine' => 'php', 'view.engines' => array( 'php' => 'view.engine.plates' ) ));
Composite Views
Views can be nested inside another:
$view->nest($app['view']->create('foobar.html'), 'section');
For a single view, it is equivalent to:
$view['section'] = $app['view']->create('foobar.html');
However, the difference lies in nesting multiple views in the same location. Doing this will place the child views adjacent to each other rather than overwriting:
$view->nest($app['view']->create('foobar.html'), 'section'); $view->nest($app['view']->create('foobar.html'), 'section'); // foobar.html is now repeated twice
What's more, you can mix and match different engines:
$mustacheView = $app['view']->create('foo.mustache'); $smartyView = $app['view']->create('bar.tpl')->nest($mustacheView, 'section');
Nested views will inherit the context of their parent views.
Exception Handling
All rendering exceptions are captured and stored in a shared ExceptionBag
.
To access the last thrown exception, or return all of them:
$exception = $app['view']->getExceptionBag()->pop(); $exceptions = $app['view']->getExceptionBag()->all();
More Examples
You can view a code sample of various usage scenarios in the demo application.
License
Released under the MIT license. See the LICENSE file for details.