nongbit/codeigniter-twig

Integrate Twig to CodeIgniter 4

Maintainers

Package info

github.com/nongbit/codeigniter-twig

Homepage

pkg:composer/nongbit/codeigniter-twig

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-05-13 11:06 UTC

This package is auto-updated.

Last update: 2026-05-13 11:08:28 UTC


README

Integrate Twig template engine into CodeIgniter 4.

Requirements

  • PHP 7.4 or 8.0+
  • CodeIgniter 4.4+
  • Composer

Installation

composer require nongbit/codeigniter-twig

Setup

1. BaseController

You can use the package either by directly accessing the Twig singleton or by using the provided trait.

Option A: Direct access (without trait)

use Nongbit\Twig\Twig;

abstract class BaseController extends Controller
{
    protected $twig;

    protected function initController(RequestInterface $request, ...$params)
    {
        parent::initController($request, ...$params);
        $this->twig = Twig::getInstance();
    }
}

Option B: Using the TwigTrait (recommended for simplicity)

use Nongbit\Twig\Traits\TwigTrait;

abstract class BaseController extends Controller
{
    use TwigTrait;

    protected function initController(RequestInterface $request, ...$params)
    {
        parent::initController($request, ...$params);
        $this->initTwig();
    }
}

2. Optional Configuration

Create app/Config/Twig.php to override defaults:

<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

class Twig extends BaseConfig
{
    public $autoescape = 'name';
    public array $paths = [APPPATH . 'Views'];
    public string $fileExtension = 'html';
}

Note about autoescape: See Twig documentation for details.

Usage

Basic Rendering

Without trait (direct singleton access):

public function index()
{
    return $this->twig->render('hello', ['title' => 'Acme']);
}

With trait (using display() method):

public function index()
{
    $this->display('hello', ['title' => 'Acme']);
}

The display() method outputs directly to the browser, so you don't need to return anything.

Adding View Paths

By default, Twig looks for templates inside APPPATH/Views. To add more locations:

$this->twig->addPath(ROOTPATH . 'templates');

Globals

// Single global
$this->twig->addGlobals('appName', 'MyApp');

// Multiple globals
$this->twig->addGlobals([
    'appName' => 'MyApp',
    'version' => '1.0'
]);

In template:

{{ appName }} - {{ version }}

Filters

$this->twig->addFilters('rot13', 'str_rot13');

// With closure
$this->twig->addFilters('reverse', function($string) {
    return strrev($string);
});

// Multiple filters
$this->twig->addFilters([
    'rot13' => 'str_rot13',
    'reverse' => fn($s) => strrev($s)
]);

In template:

{{ 'Hello'|rot13 }}

Functions

Function behaves similarly to a filter.

$this->twig->addFunctions('now', function() {
    return date('Y-m-d H:i:s');
});

In template:

{{ now() }}

Built-in Functions

  • site_url() – generates a site URL (CI4 URL helper)
  • base_url() – generates a base URL (CI4 URL helper)
  • d() – dumps variable using Kint (debug mode only)
  • dd() – dumps and dies using Kint (debug mode only)

These are automatically available in all templates.

Singleton Pattern

This package uses the singleton pattern for the Nongbit\Twig\Twig class. Only one instance exists throughout the application.

Why singleton?

  • Twig environment (loader, cache, extensions) is initialized only once per request.
  • Compiled templates are reused efficiently.
  • Better memory usage and performance.

Drawback

  • Hard to reset the instance when needed, especially in unit testing (one test may affect another).

Resetting for Tests

Call \Nongbit\Twig\Twig::reset() to create a fresh instance.

You can place this call either:

  • In setUp() (before each test) – recommended to ensure every test starts with a clean state.
protected function setUp(): void
{
    \Nongbit\Twig\Twig::reset();
}
  • In tearDown() (after each test) – useful if you want to clean up after tests that may have modified the singleton.
protected function tearDown(): void
{
    \Nongbit\Twig\Twig::reset();
}

Choose the option that best fits your test structure. The reset() method is intended for testing only and should never be used in production code.

Development vs Production

The environment is automatically detected using the ENVIRONMENT constant (set in .env or index.php).

Environment Debug Mode Cache
development ON (DebugExtension added) OFF
production OFF ON (stored in writable/twig)

In development, you can use {{ dump(var) }} (from DebugExtension) as well as {{ d(var) }} and {{ dd(var) }}.

License

MIT