Cannot replace main.php with main.twig or main.html.twig
jblac opened this issue · 3 comments
What steps will reproduce the problem?
Using twig in the backend of the advanced template
using 2.0.13.1 for Yii
and following the instructions at: to setup the base layout.
https://github.com/yiisoft/yii2-twig/blob/master/docs/guide/layouts-and-widgets.md#main-layout
delete the main.php file from the layouts folder
What's expected?
Everything works as expected.
What do you get instead?
The view file does not exist: /var/www/myawesomeapp/backend/views/layouts/main.php
Additional info
Q | A |
---|---|
Yii version | 2.0.13.1 |
Yii Twig version | 2.2.1 |
Twig version | 2.5.0 |
PHP version | 7 |
Operating system | Ubuntu 16.04 |
- I found the description in the guide was not accurate, as some paths were wrong.
- are you sure you do not reference
main.php
in some other places? Make sure to set the layout tomain.twig
in application config.
Hi Cebe,
I did a search of both the backend folder and common folder recursively for anything containing main.php
and the only files referenced were within the config
directories.
My main.php file for backend looks like:
<?php
$params = array_merge(
require __DIR__ . '/../../common/config/params.php',
require __DIR__ . '/../../common/config/params-local.php',
require __DIR__ . '/params.php',
require __DIR__ . '/params-local.php'
);
return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'timezone' => 'UTC',
'modules' => [],
'layout' => 'main.html.twig',
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'/' => 'site/index',
'/login' => 'site/login',
'/logout' => 'site/logout',
],
],
'view' => [
'class' => 'yii\web\View',
'renderers' => [
'twig' => [
'class' => 'yii\twig\ViewRenderer',
'cachePath' => '@runtime/Twig/cache',
'options' => [
'debug' => YII_DEBUG,
'auto_reload' => true,
],
'globals' => [
'html' => ['class' => '\yii\\helpers\Html'],
],
'functions' => [
new Twig_SimpleFunction('is_granted', function($permission) {
return Yii::$app->user->can($permission);
})
],
'filters' => [
new Twig_SimpleFilter('constant', function($argument) {
$arguments = explode('::', $argument);
$class = new $arguments[0];
return $class::$arguments[1];
})
],
'uses' => ['yii\bootstrap'],
],
],
],
'request' => [
'csrfParam' => '_csrf-backend',
'cookieValidationKey' => getenv('APP_COOKIE'),
],
'user' => [
'class' => 'common\components\User',
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => [
'name' => '_backendUser',
'path' => '/myapp/backend/web'
]
],
'session' => [
'name' => 'myapp-backend',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning']
]
]
],
'errorHandler' => [
'errorAction' => 'site/error'
],
],
'params' => $params
];
my main.html.twig
located at backend/views/layouts/main.html.twig
:
{{ register_asset_bundle('backend/assets/AppAsset') }}
{{ void(this.beginPage()) }}
<!DOCTYPE html>
<html lang="{{ app.language }}">
<head>
<meta charset="{{ app.charset }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ html.encode(this.title) }}</title>
{{ html.csrfMetaTags | raw }}
{{ void(this.head) }}
</head>
<body>
{{ void(this.beginBody()) }}
{{ content | raw }}
{{ void(this.endBody()) }}
</body>
</html>
{{ void(this.endPage()) }}
my SiteController.php
located at backend/controllers/SiteController.php
:
<?php
namespace backend\controllers;
use Yii;
use yii\helpers\Url;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
class SiteController extends Controller
{
public function events()
{
return [
self::EVENT_BEFORE_ACTION => 'beforeAction'
];
}
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@']
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['delete'],
],
],
];
}
/**
* {@inheritdoc}
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}
public function beforeAction($action)
{
if (Yii::$app->user->isGuest && Yii::$app->getRequest()->url !== Url::to('/login')) {
$this->redirect('/login');
}
}
public function actionIndex()
{
return $this->render('index.html.twig');
}
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
/**
* commented out because there should be some other things done here.
* $model = new LoginForm();
* if ($model->load(Yii::$app->request->post()) && $model->login()) {
* return $this->goBack();
* }
*
* $model->password = '';
* return $this->render('login', ['model' => $model]);
*/
return $this->render('login.html.twig', ['model' => 'hi']);
}
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goLogin();
}
}
and my views (which are stupid simple atm with no functionality); For index.html.twig, login.html.twig and error.html.twig i have a corresponding h1 tag:
<h1>Login Page</h1>
for each page.
As of right now I delete the main.php which previously (for me) just had <?= $content; ?>
in it, and i get the 404. When I dig deeper into the YII2 code, most notably yii\base\Controller.php
renderContent
function, it looks like line 397
is returning /var/www/mycoolapp/backend/views/layouts/main.php
. It would appear that the view object has a default extension of php
making line 521 of the yii\base\Controller.php
to be essentially: $path = "$file.php";
so, adding 'defaultExtension' => 'html.twig',
into my main.php configuration then makes the layout file be seen as the right file name. Which removing all my debugging stuff from the yii\base\Controller and reload my screen - it begins to work.
So now the view
portion of my main configuration looks like:
'view' => [
'class' => 'yii\web\View',
'defaultExtension' => 'html.twig',
'renderers' => [
'twig' => [
'class' => 'yii\twig\ViewRenderer',
'cachePath' => '@runtime/Twig/cache',
'options' => [
'debug' => YII_DEBUG,
'auto_reload' => true,
],
'globals' => [
'html' => ['class' => '\yii\\helpers\Html'],
],
'functions' => [
new Twig_SimpleFunction('is_granted', function($permission) {
return Yii::$app->user->can($permission);
})
],
'filters' => [
new Twig_SimpleFilter('constant', function($argument) {
$arguments = explode('::', $argument);
$class = new $arguments[0];
return $class::$arguments[1];
})
],
'uses' => ['yii\bootstrap'],
],
],
],
helped me: add 'layout' => 'main.twig' in config