3

I used Twig with Symfony and I really loved it. I now have a CodeIgniter project and I want to integrate Twig with it.

I installed the latest versions of CodeIgniter and Twig via Composer and and followed this tutorial but I believe the code in the tutorial is for CI v3.

Could anyone who has integrated Twig with CI v4 help me with the proper code please.

UPDATE

solution below!

Jolan
  • 681
  • 12
  • 39
  • 2
    Your tutorial is indeed for CI3 and won't really help you integrate Twig into your application. What problem are you facing? What did you try out? Help us helping you. Also take a look at this thread which might guide you a bit : https://forum.codeigniter.com/thread-66519.html – ViLar Jul 30 '20 at 13:45
  • Look for it: https://github.com/daycry/twig – adampweb Dec 22 '20 at 10:42

3 Answers3

8

Try this I hope it will help you

Install Composer and run the following command to get the latest version:

composer require "twig/twig:*"

Then after installation add this line of code to the Services.php file in the config folder, that is, app => Config => Services.php, just like the code below

    ....

    public static function twig($viewDir = null, $getShared = true)
    {
        if ($getShared) {
            return static::getSharedInstance('twig', $viewDir);
        }

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

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

        return new \Twig\Environment($loader, [
            'cache' => WRITEPATH.'/cache/twig',
        ]);
    }
    ....

**Then in your controller call the services method you just created, just like this

namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use Config\Services; // Add the services namespace 

class BaseController extends Controller
{
    protected $helpers = [];
    protected $twig;

    // protected $helper = [];
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);

        $this->twig = Services::twig(); // call the twig service you just created

    }
}

So with this now you can call the view files in other controllers extends to parent controller BaseController e.g


namespace App\Controllers;


class Home extends BaseController
{
    public function index ()
    {
        // To load a template from a Twig environment, call the load() method which returns a \Twig\TemplateWrapper instance:

       $template = $this->twig->load('index.html');

       // To render the template with some variables, call the render() method:

       return $template->render(['the' => 'variables', 'go' => 'here']);

       // The display() method is a shortcut to output the rendered template.
       // OR You can also load and render the template in one fell swoop:

       return $this->twig->render('index.html', ['the' => 'variables', 'go' => 'here']);

       // If a template defines blocks, they can be rendered individually via the renderBlock() call:

       return $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);

       // Note any of them above will work
    }
}

If you still want to use view() with twig like codeigniter 4 default view function you can modify the Common.php file in app directory by adding this block of code below.


if (!function_exists('view'))
{
    function view($tpl, $data = []) {

        $twig = \Config\Services::twig(); // call the twig service you just created

        return $twig->render($tpl, $data);
    }
}

Then in controller call it like this


return view('index', ['name' => 'Chibueze Agwu'])

Then in view file index.twig

<!DOCTYPE html>
<html>
  <head>
    <title>My Webpage</title>
  </head>
  <body>
    <h1>My Webpage</h1>
    {{ name }}
  </body>
</html>

This will output

My Webpage
Chibueze Agwu

I haven't test this code but I hope it will work. If not call my attentions. In order to obey the the rule of DRY (DO NOT REPEAT YOURSELF), you can go ahead to improve the code I will do that later

Chibueze Agwu
  • 910
  • 5
  • 12
2

I found the solution some time ago and I'm posting it in case some people stumble across the question.

  1. First of all, all your controllers must extend BaseController; this controller is available by default when you install CodeIgniter 4.

  2. Create a custom helper file and put in [project-name]/appstarter/app/Helpers.

IMPORTANT

  • the name of your helper must be [name]_helper.php or it will not work!

for example mine is called custom_helper.php

  1. Create the following function in the custom helper you just created:

     use Twig\Environment;
     use Twig\Extension\DebugExtension;
     use Twig\Loader\FilesystemLoader;
     use Twig\TwigFilter;
    
     if (!function_exists('twig_conf')) {
         function twig_conf() {
             // the follwing line of code is the only one needed to make Twig work
             // the lines of code that follow are optional
             $loader = new FilesystemLoader('Views', '../app/');
    
             // to be able to use the 'dump' function in twig files
             $twig = new Environment($loader, ['debug' => true]);
             $twig->addExtension(new DebugExtension());
    
             // twig lets you create custom filters            
             $filter = new TwigFilter('_base_url', function ($asset) {
                 return base_url() . '/' . $asset;
             });
             $twig->addFilter($filter);
    
             return $twig;
         }
     }
    

NOTE

  • before creating any custom filter, make sure Twig doesn't already has one built-in.
  1. Now in the BaseController you'll find an empty array called $helpers. You must put the name of your custom helper in it. Mine is called custom_helper.php; so the code looks like this for me:

    protected $helpers = ['custom'];
    
  2. Just below the array you'll find the constructor for BaseController and this is where the Twig library will be initialized; by calling the function you created in your custom helper:

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) {      
        parent::initController($request, $response, $logger);
    
        $this->twig = twig_conf();
    }
    
  3. Now you are good to go! To render your twig files in any controller:

    return $this->twig->render('twig_name', $dataArray);
    
Jolan
  • 681
  • 12
  • 39
1

Try this I hope it will help you.

Install Composer and run the following command to get the latest version:

composer require "twig/twig:^3.0"