Integrating Twig in your legacy code, Part 2: a less wild approach

In my last post I wrote about integrating Twig into your legacy code with a really wild approach.

Today I came up with a better solution that lets you take advantage of Twig full features without any hack (like the partial tag I was talking about in my previous post).

Instead of parsing the generated output as a string with Twig, we can store it into a template, which lets us use features like use, extends, include, thing that is almost impossible – in a clean way – if we use the Twig string loader:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

class Framework_Base_Controller
{
  public function render($templateName, array $parameters = array())
  {
      // ....
      // do stuff to render your template
      // we have the HTML output in the $templateOutput variable
      // ...

        $twig = new Twig_Environment(new Twig_Loader_String(), array(
          'autoescape' => false,
      ));

        return $twig->render($templateOutput, $parameters);
  }
}

Instead of using the Twig_String_Loader we would use an array loader, and store $templateOutput in a unique template, called __MAIN__.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

class Framework_Base_Controller
{
  public function render($templateName, array $parameters = array())
  {
      // ....
      // do stuff to render your template
      // we have the HTML output in the $templateOutput variable
      // ...

      $finder     = new Symfony\Component\Finder\Finder();
      $templates  = array();

      foreach ($finder->in('/path/to/twig/templates') as $file) {
          if (!$file->isDir()) {
              $templates[$file->getRelativePathName()] = $file->getContents();
          }
      }

      $loader = new Twig_Loader_Array($templates);
        $loader->setTemplate('__MAIN__', $templateOutput);

      $twig = new Twig_Environment($loader, array(
          'autoescape' => false,
      ));

      try {
          return $this->twig->render($templateName, array(...));
      } catch (Twig_Error_Loader $e) {
          return $this->twig->render("__MAIN__", array(...));
      }
  }
}

And that’s it!

Now you can write your own $templateName:

/path/to/twig/templates/$templateName
1
2
3
4
5
6
7
{ % extends '__MAIN__' % }

{ % use 'whatever' % }

{ % block somewhat % }
  some content
{ % endblock % }

Hi there! I recently wrote an ebook on web application security, currently sold on leanpub, the Amazon Kindle store and gumroad.

It contains 150+ pages of content dedicated to securing web applications and improving your security awareness when building web apps, with chapters ranging from explaining how to secure HTTP cookies with the right flags to understanding why it is important to consider joining a bug bounty program.

Feel free to skim through some of the free chapters published on this blog and, if the content seems interesting enough to you, grab a copy on leanpub, the Amazon Kindle store, gumroad or simply checkout right down below!

Buy the Web Application Security ebook for $6.99

In the mood for some more reading?

...or check the archives.