How to remove the templating component from a Symfony project
With the release of symfony 4 and symfony flex, projects are encouraged to only require the components they need instead of the entire framework.
The templating component adds a layer of abstraction over different templating engines and another format for referencing them. This is useful if your project has templates in multiple languages - such as twig, php, or smarty - but for many projects this abstraction isn’t needed.
In this post we’ll remove the templating component from an existing symfony project and switch to using twig directly.
Step 1 - Update references
With templating enabled, symfony supports different ways of referencing a template:
AppBundle:BlogPost:read.html.twig
@App/BlogPost/read.html.twig
Both of these reference the same file, Resources/views/BlogPost/read.html.twig
inside the AppBundle.
The first method is supported by the templating component, and the second method by twig.
We need to convert all template references to use the second syntax.
Update all calls to render()
in controllers, include
and extends
blocks in twig templates, and any other places in your application you might reference a template:
Before
{% extends 'AppBundle:Something:index.html.twig' %}
After
{% extends '@App/Something/index.html.twig' %}
Under the hood
When you call render()
in a controller, symfony will use the templating
service, an instance of Symfony\Component\Templating\EngineInterface
, to find and render the supplied template.
Usually this engine is the TwigEngine
, which uses twig to render the templates.
To actually find the templates it uses instances of Symfony\Component\Templating\TemplateNameParserInterface
and Symfony\Component\Config\FileLocatorInterface
.
When it encounters a template name it doesn’t understand, it will delegate to the underlying twig environment to find the template instead.
Twig has a concept of namespaces, which is where the @App
template syntax comes from.
Thankfully the twig bundle registers namespaces for us so we don’t have to - a bundle called MySuperBundle
would have the namespace @MySuper
registered automatically.
With templating disabled, a call to render()
will use the twig
service instead, thus only giving access to the @Bundle
syntax.
Step 2 - Rename template files and best practices
The changes in recommended template filenames are best illustrated by looking at what the FrameworkExtraBundle does with the @Template
annotation in version 3 vs version 4:
class HomePageController extends Controller
{
/**
* @Route("/")
* @Template
*/
public function indexAction(Request $request)
{
return [];
}
}
- version 3 -
AppBundle:HomePage:index.html.twig
- version 4 -
@App/home_page/index.html.twig
i.e. lowercase and snake_case. Rename your template files to match this convention.
If you don’t want to do this all at once, you can specify the template in the annotation until you get time to rename the template:
@Template("LegacyBundle:NotConvertedYet:show.html.twig")
or even better:
@Template("@Legacy/NotConvertedYet/show.html.twig")
If your application only has one bundle, you might want to consider moving all the templates to the templates/
directory in the root of your project.
See the best practices documentation for more suggestions.
Step 3 - Turn off and uninstall the component
Finally, remove the templating node from the framework bundle configuration, or disable it explicitly:
framework:
templating: false
and remove the composer package:
composer remove symfony/templating
If your project requires symfony/symfony
, you’ll have to remove that dependency and replace it with the individual components your project needs.
Conclusion
That’s it! We’ve removed a layer of abstraction from our project and made twig the only way to handle templating. This enforces consistency and reduces confusion for new project members.