Updating the TwigBundle Recipe

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

The updated framework-bundle recipe gave us this new routing file: config/routes/dev/framework.yaml:

_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error

Which loads a /_error/{statusCode} route where we can test what our production error pages look like.

This feature used to live in TwigBundle... which is why twig.yaml has basically the exact same import:

_errors:
resource: '@TwigBundle/Resources/config/routing/errors.xml'
prefix: /_error

This is a minor problem. In your terminal, run:

php bin/console debug:router

and scroll up to the top. Yep! We have two routes for the exact same URL. The first one - which by chance is the one from FrameworkBundle - would win, but we still don't want the old one sitting there. Plus, it's deprecated and will disappear in Symfony 5.

We need to delete this twig.yaml file. But... we probably also need to update the TwigBundle recipe... which will probably delete it for us. Run:

composer recipes

Yep! The recipe for symfony/twig-bundle has an update.

Updating symfony/twig-bundle Recipe

Get some info about it:

composer recipes symfony/twig-bundle

Then copy the recipes:install command and run it:

composer recipes:install symfony/twig-bundle --force -v

Perfect! It looks like it modified three files. Let's start walking through them:

git add -p

The first change is inside the twig.yaml config file. If you ignore the stuff that it's removing - that's all our custom code - it looks like the updated recipe added a line: exception_controller: null.

Ok, so we definitely want to keep our custom changes... and we probably want to keep this new line... except that we don't really know why it was added.

Checking CHANGELOGs

Let's go do some digging! But this time, instead of checking the recipe commit history, let's try something different. Because this is a config change for TwigBundle, let's go see if they mention this in a CHANGELOG.

Google for "GitHub TwigBundle" to find its GitHub page. Scroll down and... yea! It has a CHANGELOG.md file.

Open it up and look at the 4.4.0 changes. Actually, this exception_controller change could even be from an earlier version - but we'll start here. And... yea, it does talk about it:

deprecated twig.exception_controller configuration option, set it to "null" and use framework.error_controller configuration instead.

The deprecated twig exception_controller Option

This is another feature that was deprecated inside TwigBundle and moved to FrameworkBundle. The exception, or "error", controller is the controller that's responsible for rendering an error page.

To disable - basically "stop using" the deprecated old code - we need to set exception_controller to null. That is why the recipe added this change. This is a good change. Of course, if your config file already has an exception_controller option... because you're using a custom exception controller, you'll need to move that value to framework.error_controller and do some reading to see if your controller code needs any other updates.

So we do want this change... but we can't accept this patch without killing our custom code. Copy the new config, hit "q" to quit this mode, and then... let's see - undo those changes by running:

git checkout config/packages/twig.yaml

Oh, and I guess I should spell "checkout" right.

Now, spin back over, open that file - config/packages/twig.yaml - and add exception_controller: null:

twig:
... lines 2 - 9
exception_controller: null

Nice! Let's... keep going: start the git add -p system again:

git add -p

This time we do want to accept the change to twig.yaml - "y" - and the next change is inside symfony.lock. Accept that too.

base.html.twig and the new test/twig.yaml

The last updated file is templates/base.html.twig and we definitely do not want to accept this change and kill our custom layout. Looking at the new code... I don't see anything super important that we might want to add. In fact, if you checked the recipe history, there haven't been any updates to this file in years. Hit "n" to ignore this.

Run:

git status

to see how things look. Oh! A new file: config/packages/test/twig.yaml - a config file that's only loaded in the test environment. Before we see what's inside it, let's revert the changes we don't want:

git checkout templates/base.html.twig

Go open the new file: config/packages/test/twig.yaml:

twig:
strict_variables: true

Ah, super minor: it sets strict_variables to true for our tests. This settings tells Twig to throw an exception if we try to use an undefined variable in a template. If we ever did that, we probably would want Twig to explode in our tests so we know about it. That's a good change. Add that file:

git add config/packages/test/twig.yaml

Manually Deleting config/routes/dev/twig.yaml

We're done! But... wait a second. We expected that the updated recipe would delete the extra config/routes/dev/twig.yaml file... but it didn't. Hmm... is it still in the recipe for some reason? Run:

composer recipes symfony/twig-bundle

Copy the URL to the recipe... and paste it in your browser. Huh. No - there is no config/routes directory at all in here. The file is gone! Why wasn't it deleted?

This is a shortcoming of the recipe update system: it's not smart enough. In a perfect world, it would realize that there used to be a config/routes/dev/twig.yaml file in the old version of the recipe... and since it is not there in the new version, it would delete it. But, that does not happen, at least not yet.

So, we need to delete it manually. This doesn't happen very often, but it is something you should be aware of.

Back at the terminal, run:

git status

one more time - things look good - and let's commit:

git commit -m "updating symfony/twig-bundle"

Nice! Now run:

composer recipes

We're getting close! Let's do any easy one next: let's upgrade symfony/mailer and symfony/sendgrid-mailer.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.3.0",
        "ext-iconv": "*",
        "antishov/doctrine-extensions-bundle": "^1.4", // v1.4.2
        "aws/aws-sdk-php": "^3.87", // 3.110.11
        "doctrine/doctrine-bundle": "^2.0", // 2.0.6
        "doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // 2.1.2
        "doctrine/orm": "^2.5.11", // v2.7.2
        "easycorp/easy-log-handler": "^1.0", // v1.0.9
        "http-interop/http-factory-guzzle": "^1.0", // 1.0.0
        "knplabs/knp-markdown-bundle": "^1.7", // 1.8.1
        "knplabs/knp-paginator-bundle": "^5.0", // v5.0.0
        "knplabs/knp-snappy-bundle": "^1.6", // v1.7.0
        "knplabs/knp-time-bundle": "^1.8", // v1.11.0
        "league/flysystem-aws-s3-v3": "^1.0", // 1.0.23
        "league/flysystem-cached-adapter": "^1.0", // 1.0.9
        "league/html-to-markdown": "^4.8", // 4.8.2
        "liip/imagine-bundle": "^2.1", // 2.3.0
        "nexylan/slack-bundle": "^2.1", // v2.2.1
        "oneup/flysystem-bundle": "^3.0", // 3.3.0
        "php-http/guzzle6-adapter": "^2.0", // v2.0.1
        "sensio/framework-extra-bundle": "^5.1", // v5.5.3
        "symfony/asset": "5.0.*", // v5.0.2
        "symfony/console": "5.0.*", // v5.0.2
        "symfony/dotenv": "5.0.*", // v5.0.2
        "symfony/flex": "^1.0", // v1.6.2
        "symfony/form": "5.0.*", // v5.0.2
        "symfony/framework-bundle": "5.0.*", // v5.0.2
        "symfony/mailer": "5.0.*", // v5.0.2
        "symfony/messenger": "5.0.*", // v5.0.2
        "symfony/monolog-bundle": "^3.5", // v3.5.0
        "symfony/security-bundle": "5.0.*", // v5.0.2
        "symfony/sendgrid-mailer": "5.0.*", // v5.0.2
        "symfony/serializer-pack": "^1.0", // v1.0.2
        "symfony/twig-bundle": "5.0.*", // v5.0.2
        "symfony/twig-pack": "^1.0", // v1.0.0
        "symfony/validator": "5.0.*", // v5.0.2
        "symfony/webpack-encore-bundle": "^1.4", // v1.7.2
        "symfony/yaml": "5.0.*", // v5.0.2
        "twig/cssinliner-extra": "^2.12", // v2.12.0
        "twig/extensions": "^1.5", // v1.5.4
        "twig/inky-extra": "^2.12" // v2.12.0
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0", // 3.3.0
        "fzaninotto/faker": "^1.7", // v1.8.0
        "symfony/browser-kit": "5.0.*", // v5.0.2
        "symfony/debug-bundle": "5.0.*", // v5.0.2
        "symfony/maker-bundle": "^1.0", // v1.14.3
        "symfony/phpunit-bridge": "5.0.*", // v5.0.2
        "symfony/profiler-pack": "^1.0", // v1.0.4
        "symfony/var-dumper": "5.0.*" // v5.0.2
    }
}