paneric/twig-builder


README

Tiny and handy Twig's Environment instance builder with integrated clone of Slim 3 TwigExtension library.

Required

  • PHP 7.1+

File structure

  • twig-builder
    • src
      • Extension
        • TwigExtension.php (clone of Slim\Views\TwigExtension)
      • Interfaces
        • RouteParserInterface.php (clone of Slim\Interfaces\RouteParserInterface)
      • TwigBuilder.php

composer

composer require paneric/twig-builder:1.0.0

Integration

Slim Framework example (ver.4)

configuration

Below, there is presented configuration/settings pattern required for a proper integration. As you can see it consists of two sections:

return [
    'twig_settings' => [
        'templates_dirs' => [
             APP_FOLDER . 'templates/',
             'home' => APP_FOLDER . 'HOME/templates/',
             ...
        ],
        'options' => [
            'debug' => false,
            'charset' => 'UTF-8',
            'strict_variables' => false,
            'autoescape' => 'html',
            'cache' => ROOT_FOLDER.'/var/cache/twig', // define('APP_ROOT', dirname(__DIR__)); (index.php)
            'auto_reload' => null,
            'optimizations' => -1,
        ],
    ]
];

As its name says, templates_dirs section delivers information on location of our templates directories within a project. By default, existing keys will be treated by Twig as possible namespaces.

APP_FOLDER and ROOT_FOLDER global constants are mentioned as an example of course, so you should manage your paths at your best convenience. It means you can set template_dirs as relative paths, but you need to remember to pass basePath parameter value while calling build method of Twig Builder.

Section options contains Twig's default options values.

front controller

You can find below some very, very, very ugly, but sufficient for a demonstration purpose, example of integration within a front controller:

use DI\ContainerBuilder;
use Slim\Factory\AppFactory;
use Slim\Routing\RouteParser;
use Paneric\Twig\TwigBuilder;
use Twig\Environment;
use DI\Container;

define('ENV', 'dev');

define('ROOT_FOLDER', dirname(__DIR__) . '/');
define('APP_FOLDER', ROOT_FOLDER . 'src/');

require ROOT_FOLDER . 'vendor/autoload.php';

try{
    $settings = ...;

    $builder = new ContainerBuilder();
    $builder->addDefinitions(array_merge(
        $settings,
        [
            'twig_environment'=> function (Container $container): Environment
             {
                 $twigBuilder = new TwigBuilder(
                     $container->get(RouteParser::class),
                     $container->get(Uri::class)
                 );
                  
                 return $twigBuilder->build($container->get('twig_settings'));
             },
        ]
    ));
    $container = $builder->build();

    AppFactory::setContainer($container);
    $app = AppFactory::create();

    $container->set(RouteParser::class, $app->getRouteCollector()->getRouteParser());

    $app->run();
} catch (Exception $e) {
   echo $e->getMessage();
}

As I mentioned, it is horrible, but shows an idea straight forward.

If you need to add other extensions to the Twig Environment (for example Symfony Translation Component) you just have to modify slightly the manner of instantiation. For example as below:

            'twig_environment'=> function (Container $container): Environment
             {
                 $twigBuilder = new TwigBuilder(
                     $container->get(RouteParser::class),
                     $container->get(Uri::class)
                 );
                  
                 $environment = $twigBuilder->build($container->get('twig_settings'));
                 $environment->addExtension($container->get('some_extension'));
                 $environment->addExtension($container->get('another_extension'));

                 return $environment;
             }