I was recently working on a project where the initial mockups were all built using Twig and a light weight Silex backend, but the actual application was built in Yii2. Rather than rebuild all the UI as Yii2 views, I looked into utilising the Twig elements I already had. It was a lot easier than I hoped to integrate Twig into Yii2 and I didn’t loose out on any of Yii2’s powerful view features.
Initially the mockups were built out as a semi-static site using Silex and Twig templates to make it quick to put together a high resolution mock-up and have some fake data passed around to give a feel for the app.
However, the actual app that was being built in-house by my client utilised the Yii2 framework. So, rather than re-do all the work from the mockups, we looked at how we could re-use the Twig templates as the view layer for the Yii2 project.
Requisites
First off you need to add the Yii2 Twig renderer to your composer.json. Go to the root directory (where the composer.json resides) and type
composer require yiisoft/yii2-twig
This assumes you have composer installed globally in your /bin directory
Then you need to tell Yii to use this new renderer.
In the config/web.php
file of your Yii project you need to add the following section to your components
hash
'components' => [
'view' => [
'renderers' => [
'twig' => [
'class' => 'yii\twig\ViewRenderer',
// set cachePath to false in order to disable template caching
'cachePath' => false, //'@runtime/Twig/cache',
// Array of twig options:
'options' => [
'auto_reload' => true,
],
// add Yii helpers or widgets here
'globals' => [
'html' => '\yii\helpers\Html',
]
]
]
]
],
// -- snip
Lastly, and optionally, we wanted to use Twig throughout the application, so we globally replaced the layout for the whole app in the config with a Twig variant.
In the same file, at the route of the $config
array, add a new layout
key
$config = [
'layout' => 'main.twig',
// -- snip -- //
];
This tells Yii to ignore the default views/layouts/main.php
and use the views/layouts/main.twig
instead
Now all the set up is done and Yii knows how to render Twig templates. Now I’ll go through basic usage.
Setting up a Twig Layout
Now we’ve made those changes we need a Twig layout to replace the main.php
.
Create the new file in views/layouts/main.twig
Here is the absolute minimum you need to get started:
{{ this.beginPage() }}
<!doctype html>
<html lang="{{app.language}}">
<head>
<meta charset="{{app.charset}}"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
{{ html.csrfMetaTags() | raw }}
<title>{{ html.encode(this.title) }}</title>
{{ this.head() }}
</head>
<body>
{{ this.beginBody() }}
{{ content | raw }}
{{ this.endBody() }}
</body>
</html>
{{ this.endPage() }}
This is a basic replacement for the default main.php
that comes with Yii2 but in Twig with the Bootstrapped navigation and footer removed. On good thing to note here is that as we are merging in the content
variable, it means that we can use either Twig views, or the normal Yii PHP views. Both will render as HTML that will then be merged in.
Using a Twig Template
Assuming we have a PostsController
to display posts on our Blog application, the actionIndex may look something like this
public function actionIndex()
{
$posts = Posts::find()->where(['published' => Posts::PUBLISHED])->orderBy('published_at');
return $this->render('index.twig', [
'posts' => $posts
]);
}
The important thing to notice here is that you must put the .twig
extension in the $this->render
call, otherwise Yii will attempt to load the normal index.php
view file.
With this in place you can now create your first Twig view file. Start by creating views/posts/index.twig
.
Now you can build the view using all the tools available to you in Twig, and pull in anything you need from Yii.
For (a very basic) example:
{% for post in posts %}
<div class="post">
<h1>{{ post.title }}</h1>
<div class="post-body">
{{ post.body }}
</div>
</div>
{% endfor %}
Resources
You can read up more on Twig itself at the official documentation http://twig.sensiolabs.org/documentation and about the Yii2 Twig Renderer along with some Yii specific syntax at the Github repo