Twig integration with Codeigniter

PHP templates for pages (aka views) have evolved in the last decade however, in the current MCV widely used project structure, Twig has provided a simplified, fast, secure and reliable solution to writing code. It has been my number one choice for a very long time.

In this article:

Why choose Twig over the default Views in Codeigniter?

Codeigniter (currently version 4) is one of the best PHP frameworks out there and it comes with it’s well known structure which includes Views (which are normally saved in the app/Views directory.

The views can then take parameters so it displays the page according to the template. Here is a sample controller and it’s corresponding view:

app/Controllers/Site.php

<?php

namespace App\Controllers;
use CodeIgniter\Controller;

class Site extends BaseController
{
    public function index()
    {
        $data['title']   = 'My Title';
        $data['heading'] = 'My Heading';

        return view('sample_view', $data);
    }
}

app/Views/sample_view.php

<html>
    <head>
        <title><?= esc($title) ?></title>
    </head>
    <body>
        <h1><?= esc($heading) ?></h1>
    </body>
</html>

If you were using Twig, the view would use a lot simpler markup language and thus, the view would look like this:

app/Views/sample_view.html.twig

<html>
    <head>
        <title>{{ title }}</title>
    </head>
    <body>
        <h1>{{ heading }}</h1>
    </body>
</html>
Installing TWIG into your Codeigniter project

Preferred method for installing Twig into your CodeIgniter project is via composer:

$ composer require twig/twig 

This should add Twig to your project and into your composer.json file:

"require": {
        "php": "^7.4 || ^8.0",
        "codeigniter4/framework": "^4.0",
        "twig/twig": "^3.4",
    }
Configuring Codeigniter to use Twig

It’s now time to load Twig into CodeIgniter and prepare for being able to serve the twig templates. The only change you need to do is in the BaseController class:

app/Controllers/BaseController.php

<?php

namespace App\Controllers;

....
abstract class BaseController extends Controller
{
    ...

    protected $twig;
    protected $twig_data = array();

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        // Do Not Edit This Line
        parent::initController($request, $response, $logger);

        $appPaths = new \Config\Paths();
        $appViewPaths = $appPaths->viewDirectory;

        $loader = new \Twig\Loader\FilesystemLoader($appViewPaths);

        $this->twig = new \Twig\Environment($loader, [
            'cache' => WRITEPATH.'/cache/twig',
            'auto_reload'=> true
        ]);

        $this->twig_data['base_url'] = base_url().'/';
    }
}

That’s it! You now are ready to use Twig. One can tell that the templates (aka views) will reside in the previously used Views directory in the project. This makes it more convenient for maintaining the proper project structure.

In our previous controller app/Controllers/Site.php you need to change the rendering method:

<?php

namespace App\Controllers;
use CodeIgniter\Controller;

class Site extends BaseController
{
    public function index()
    {
        $this->twig_data['title'] = 'My Title';
        $this->twig_data['heading'] = 'My Heading';

        return $this->twig->render("sample_view.html.twig", $this->twig_data);
    }
}

Note that now we are referencing the global protected variable $this->twig_data which is now available throughout any class that extends BaseController.

Basic Example using a FOR LOOP

Let’s review a simple example for using Twig in a loop.

First, let’s load the data from DB. Let’s say you have a table with the structure [‘id’, ‘name’, ’email’, ‘age’] and the proper model built in app/Models/Users.php

app/Controllers/Site.php

<?php

namespace App\Controllers;
use App\Models\Users;

class Site extends BaseController
{

    public function index()
    {

        $users_model = new Users();
        $users = $user_model->findAll();
        $this->twig_data['users']=$users;

        $this->twig_data['Title']='Example FOR loop';
        $this->twig_data['gen_date']=date("Y-m-d H:i:s", strtotime('now'));

        return $this->twig->render("users.html.twig",$this->twig_data);
    }
}

Now let’s go ahead and build the view. I’ve gone ahead and added a bit of spice as to add some variable filters (like escape or date filters). More variable filters can be found on the Twig Filters page

app/Views/users.html.twig

<html>
    <head>
        <title>{{ title | escape }}</title>
    </head>
    <body>
        <h1>This sample page was generated at {{ gen_date | date("m/d/Y H:i:s")}}</h1>
        <table>
                 <thead>
                            <tr>
                                   <td>Id</td>
                                   <td>Name</td>
                                   <td>Email</td>
                                   <td>Age</td>
                            </tr>
                 </thead>
                 <tbody>
                      {% for user in users %}
                            <tr>
                                   <td>{{ user.id }}</td>
                                   <td>{{ user.name }}</td>
                                   <td>{{ user.email }}</td>
                                   <td>{{ user.age }}</td>
                            </tr>
                      {% endfor %}
                 </tbody>
        </table>
    </body>
</html>

Go ahead and try it!

For more information here are some relevant links:


Posted

in

,

by