Florent Destremau

Upgrade your Twig "includes" syntax with a simple regex

I tinkered with ChatGPT and ended up with a pretty simple regex that you can use on your Twig project to upgrade to the syntax from this:

{% include 'template.html.twig' with { var: myVar } %}

To this:

{{ include('template.html.twig', { var: myVar }) }}

Here's the script below, update it to your needs. The function include() is available for all Twig versions, and it is recommended to migrate away from the tag, as told in the docs.

Note #1: it handles the line breaks pretty okay. To use it, create a upgrade.php file at the root of your project, and run it with php upgrade.php. If your Twig templates are not in the templates/ dir, you might want to adjust.

Note #2: it handles empty params as well!

<?php
$directory = 'templates/'; // Set the correct path to your templates directory
$patternWithParams = '/{%\s+include\s+\'([^\']+?)\'\s+with\s+\{([^}]+?)\}\s+%}/';
$patternWithoutParams = '/{%\s+include\s+\'([^\']+?)\'\s+%}/';

// Scan the directory for Twig files
$twigFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));

foreach ($twigFiles as $twigFile) {
    // Check if the file is a .twig file
    if ($twigFile->isFile() && strtolower($twigFile->getExtension()) === 'twig') {
        // Read the content of the file
        $originalContent = file_get_contents($twigFile->getRealPath());
        $content = $originalContent;

        // Perform the replacement for includes with parameters
        if (preg_match_all($patternWithParams, $content, $matchesWithParams, PREG_SET_ORDER)) {
            foreach ($matchesWithParams as $match) {
                $params = isset($match[2]) ? trim(preg_replace('/\s+/', ' ', $match[2])) : '';
                $replacement = "{{ include('{$match[1]}', { $params }) }}";
                $content = str_replace($match[0], $replacement, $content);
            }
        }

        // Perform the replacement for includes without parameters
        $content = preg_replace($patternWithoutParams, "{{ include('$1') }}", $content);

        // Check if any changes were made
        if ($content !== $originalContent) {
            // Save the updated content back into the file
            file_put_contents($twigFile->getRealPath(), $content);
        }
    }
}