Slim-OO Part 5 – Install and Configure Twig

Part 5. Install and Configure Twig.

Why a template engine.

Slim comes with php-view, a basic renderer for PHP view scripts, by default. This means that all our templates would need to be in straight PHP syntax. There are many arguments for and against template engines. Personally, I like to use them because they give me certain functionality out of the box such as XSS handling and template injection. This saves me time that can be better utilized on other aspects of a project.

Mechanisms for controlling Cross Site Scripting (XSS) are one of the most important pieces of functionality supplied by template engines. PHP-View has no built-in mitigation from XSS attacks and is of the philosophy of “It is the developer’s responsibility”. I don’t want to deal with setting up all the necessary escaping myself. I prefer to leave something that deals with security and hacking to developers who specialize in dealing with this.

Another feature is functionality for adding parent and sub templates easily. You can do things like call reusable sub templates into your current page and make your current page an extension of predefined page layouts. With all the template engines on the market today I see no need to reinvent all this work. I have found from experience that using a template engine will save development time in the long run.

My suggestion is to pick the one you like and run with it. Slim has already added support for Twig. I have used it in the past in Symfony and Silex projects and I really like it, so let’s go ahead and use it here.

Install and configure.

Let’s install Twig-View as we did before with other components, using composer. In addition to the base Twig package, we will also install the Twig Extensions which will give us many of the extra features that make template engines so attractive. While we are at it let’s also create our cache directory.

$ composer require slim/twig-view
$ composer require twig/extensions
$ mkdir cache && chmod 777 cache

Once everything is installed, it’s time to configure the package. Open the configuration/settings.php file and add an entry for a template_cache directory. The template path will not need to change as we will be using the same directory as php-view. While we’re at it let’s also fix the path prefix’s under ‘renderer’ to use our APP_ROOT constant.

'renderer' => [
    'template_path'  => APP_ROOT.'/templates/',
    'template_cache' => APP_ROOT.'/cache/'
],

Now let’s define our service so that it is loaded and accessible. Open the configuration/services/services.php file and add the following code. It grabs the configuration settings, creates an instance of the template engine, and adds some useful extensions. Finally, it returns that instance to our container for use.

// Register component on container
$container['view'] = function ($container) {
    $settings = $container->get('settings');
    $view = new \Slim\Views\Twig($settings['renderer']['template_path'], [
        'cache' => $settings['renderer']['template_cache']
    ]);
    $view->addExtension(new \Slim\Views\TwigExtension(
        $container->get('router'),
        $container->get('request')->getUri()
    ));

    return $view;
};

Finally, now that we have a service entry for it in our container, let’s inject the Twig engine into our default controller via the controller definition. Open our configuration/services/controllers.php definition file and change the passed in renderer parameter to the new view service. Now, whenever the DefaultController is called it will pass in an instance of the Twig service.

$container['DefaultController'] = function($container){
    return new \App\Controller\DefaultController(
        $container->get('logger'),
        $container->get('view')
    );
};

Implementation.

Now that we are done configuring Twig, let’s switch it out in our Controller.

Open the src/App/Controller/DefaultController.php and add a use statement for Slim\Views\Twig. Now change the definition of the constructor to use $view instead of $renderer as the second parameter, don’t forget to type hint the $view parameter as a Twig object. The private $renderer property will need to be refactored to the new $view property throughout the class. Finally, in the index method, change the render calls second parameter from index.phtml to index.html.twig.

As a bit of cleanup let’s also type-hint the parameters of the index method. These will be Psr\Http\Message\RequestInterface, Psr\Http\Message\ResponseInterface, and array.

When completed it should look like this.

namespace App\Controller;

use Psr\Log\LoggerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Views\Twig;

class DefaultController
{
    /** @var LoggerInterface  */
    private $logger;
    /** @var Twig */
    private $view;

    public function __construct(LoggerInterface $logger, Twig $view)
    {
        $this->logger = $logger;
        $this->view   = $view;
    }

    public function index(RequestInterface $request, ResponseInterface $response, array $args)
    {
        $this->logger->info("Slim-Skeleton '/' route");
        return $this->view->render($response, 'index.html.twig', $args);
    }
}

Now let’s convert our HTML template from PHP to Twig. Start by renaming it from index.phtml to index.html.twig. This will allow the Twig template engine to index it when it looks over the configured template_path directory. Then change the central content to use Twig syntax.

from:

<div>
  <?php if (isset($name)) : ?>
    <h2>Hello <?= htmlspecialchars($name); ?>!</h2>
  <?php else: ?>
    Try <a href="/SlimFramework">SlimFramework</a>
  <?php endif; ?>
</div>

to:

<div>
  {%% if name %%}
    <h2>Hello {{ name }}!</h2>
  {%% else %%}
    Try <a href="/SlimFramework">SlimFramework</a>
  {%% endif %%}
</div>
 

Finished.

That’s it, it’s set up. $this->view invoked inside the route method will reference the \Slim\Views\Twig instance returned by the view container service. The \Slim\Views\TwigExtension supplies us with all of the Twig functionality that you would expect in a full-stack framework implementation like Symfony’s. This includes text filters, extending templates, and using slots.

We’ll get more in depth into working with Twig and all of its cool features in another post. For now, you can find more information and complete documentation on Twig on its site.

Twig (http://twig.sensiolabs.org/)

Code.

See the final code for this article on Github. 005 Install and Configure Twig