Twig view renderer

This extension allows you to use Twig templates in Yii.

http://www.yiiframework.com/extension/twig-view-renderer/

Hi!

I installed Twig and twig extension, but i get this error:

Fatal error: Class ‘CErrorEvent’ not found in /var/www/yii/base/CApplication.php on line 607

Can you help me?

Thanks!

Can you show error trace?

i only get this error

Fatal error: Class ‘CErrorEvent’ not found in /var/www/yii/base/CApplication.php on line 607

Using yii 1.0.9

Can’t tell anything about your case because can’t reproduce it. It would be really helpful if you will reproduce the same error with clean application code, zip application and pass it to me.

Updated installation instructions on extension page.

Stack Trace

#0 E:\AppServ\www\school\core\base\CModule.php(431): CComponent->__set(‘viewRenderer’, Array)

#1 E:\AppServ\www\school\core\base\CApplication.php(117): CModule->configure(Array)

#2 E:\AppServ\www\school\core\YiiBase.php(81): CApplication->__construct(‘E:\AppServ\www\…’)

#3 E:\AppServ\www\school\app\index.php(11): YiiBase::createWebApplication(‘E:\AppServ\www\…’)

#4 {main}

i got This error when i try to use it ? any idea?

after i used it , it show me this error !!

SiteController cannot find the requested view "index".

Do you have this view? As stated in documentation you can set view files extension. By default it’s .html, so your view have to be protected/views/site/index.html. You can change extension in your config file.

Как можно вызвать виджет в твиге. Например в prado можно так сделать:


<com:WidgetClass property1=value1 property2=value2 ...>

и можно ли делать сделать нападобии этого:


Выражение <%= expression %> преобразуется в <?php echo expression ?>. <% statement %> — в <?php statement ?>. К примеру:


<%= CHtml::textField($name,'value'); %>

<% foreach($models as $model): %>


преобразуется в


<?php echo CHtml::textField($name,'value'); ?>

<?php foreach($models as $model): ?>

Надо написать плагин для Twig. В расширении этого не предусмотрено.

it looks like te download file is corrupt.

Try one from here: http://code.google.com/p/yiiext/downloads/list

Thanks this download works! There’s only no support for theme’s…

Hello Samndark,

In the near future we will have to use a template language (like liquid for RoR) in our yii based multitenant platform. The main functionality (apart from our own use in coding) is to let the final users customize their own web themes and templates. I started with phphamlp but finally is not convenient for our propouses.

In my research I saw that you have ported 3 language templates to yii widgets (Quicky, Smarty 3 , Twig and Dwoo). Maybe you didn’t try all of them, but from your experience, could you please suggest to us one of them in terms of functionality, performance, yii integration, security, etc? Whatever opinion would be useful for me.

Many thanks,

Alex

aleksdj

Yii integration is not so good for all these template engine extensions I’ve implemented. The main purpose was to show that it’s possible and give people a good starting point.

Quicky, Smarty (btw., extension is for v2, not v3), and Dwoo syntax is alike. Twig is different and is more like Django templates.

Since I don’t know your requirements I can say anything about what will fit your application best.

Thanks SamDark,

well, in the end, the main requirement is to let the platform final users implement their own themes/templates without the need of dealing with php language and -of course- preserving the platform security. I don’t want a shortcut of php code like hamlphp, I need like an own language on top of php, where the users can call to {{categories.title}} {{footer.links}} for example, etc. One interesting point I saw in favor of your smarty extension is the possibility to “define” some functions (like link or t function), I don’t know if it would be possible with twigg extensiong also.

P.S: On your smarty changelog you put:

0.9.5 [+] Smarty 3 comatibility.

So is it smarty 3 supported?

Thanks,

Alex

Вопрос был задан давно, но может кому и пригодиться мой ответ)

Создадим классы и сделаем их видимыми в CTwigViewRenderer (я добавил их в этот же файл) :




class YiiStatic {

    function __get($method) {

        return call_user_func(array('Yii', $method));

    }

    function __call($method, $args = array()) {

        return call_user_func_array(array('Yii', $method), $args);

    }

}

class twigC {

    private $_objects = array();

    function __isset($name) {

        return true;

    }

    function __get($method) {

        if( ! isset($this->_objects[$method])) {

            $this->_objects[$method] = new twigCObj($method);

        }

        return $this->_objects[$method];

    }

}


class twigCObj {

    private $_name;

    function __construct($name) {

        $name = 'C'.$name;

        $this->_name = new $name();

    }

    function __get($method) {

        return call_user_func(array($this->_name, $method));

    }

    function __call($method, $args = array()) {

        return call_user_func_array(array($this->_name, $method), $args);

    }

}

в renderFile CTwigViewRenderer’а после


$data['this'] = $context;

добавим переменных:




$data['Yii'] = new YiiStatic();

$data['app'] =& Yii::app(); // для более быстрого доступа

$data['C'] = new twigC();

теперь в шаблоне можно делать так:


<div id="logo">{{ C.Html.encode(app.name) }}</div>

На примере стандартного меню:


<div id="mainmenu">

    {{ this.widget('zii.widgets.CMenu',{

        'items': [

            { 'label':'Home', 'url':['/site/index'] },

            { 'label':'About', 'url':{'0':'/site/page','view':'about'} },

            { 'label':'Contact', 'url':['/site/contact'] },

            { 'label':'Login', 'url':['/site/login'], 'visible':app.user.isGuest },

            { 'label':'Logout (' ~ app.user.name ~ ')', 'url':['/site/logout'], 'visible':app.user.isGuest ? false : true },

        ]

    }, true)|raw }}

</div><!-- mainmenu -->

вот так:




{{ C.Html.textField(name,'value')|raw }}


<ul>

{% for object in objects %}

    <li>{{ object.name }}</li>

{% endfor %}

</ul>

[size="3"]Под спойлером стандартный макет yii переписанный под Twig (без добавления блоков)[/size]

[spoiler]


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

	<meta name="language" content="en" />


	<!-- blueprint CSS framework -->

	<link rel="stylesheet" type="text/css" href="{{ app.request.baseUrl }}/css/screen.css" media="screen, projection" />

	<link rel="stylesheet" type="text/css" href="{{ app.request.baseUrl }}/css/print.css" media="print" />

	<!--[if lt IE 8]>

	<link rel="stylesheet" type="text/css" href="{{ app.request.baseUrl }}/css/ie.css" media="screen, projection" />

	<![endif]-->


	<link rel="stylesheet" type="text/css" href="{{ app.request.baseUrl }}/css/main.css" />

	<link rel="stylesheet" type="text/css" href="{{ app.request.baseUrl }}/css/form.css" />


	<title>{{ C.Html.encode(this.pageTitle) }}</title>

</head>


<body>


<div class="container" id="page">


	<div id="header">

		<div id="logo">{{ C.Html.encode(app.name) }}</div>

	</div><!-- header -->


<div id="mainmenu">

    {{ this.widget('zii.widgets.CMenu',{

        'items': [

            { 'label':'Home', 'url':['/site/index'] },

            { 'label':'About', 'url':{'0':'/site/page','view':'about'} },

            { 'label':'Contact', 'url':['/site/contact'] },

            { 'label':'Login', 'url':['/site/login'], 'visible':app.user.isGuest },

            { 'label':'Logout (' ~ app.user.name ~ ')', 'url':['/site/logout'], 'visible':app.user.isGuest ? false : true },

        ]

    }, true)|raw }}

</div><!-- mainmenu -->


	{{ this.widget('zii.widgets.CBreadcrumbs', {

		'links' : this.breadcrumbs,

	}, true)|raw }}<!-- breadcrumbs -->


	{{ content|raw }}


	<div id="footer">

		Copyright &copy; {{ "now"|date('Y') }} by My Company.<br/>

		All Rights Reserved.<br/>

		{{ Yii.powered|raw }}

	</div><!-- footer -->


</div><!-- page -->


</body>

</html>

[/spoiler]

P.S.: еще чтобы не писать везде |raw , код можно заключить в {% raw %}{% endraw %}, либо {% autoescape off %}{% endautoescape %} (подробнее об autoescape)

P.P.S.: С классами мне кажется я набыдлокодил малясь, "поможити кто можите"

Hello there,

this Extension is very cool! We’ll use in our os-software.

I added auto-remove-support for cached files if source file is newer. If you’re interessed in replace renderFile in ETwigViewRenderer with following code:




public function renderFile($context,$sourceFile,$data,$return) {

	// current controller properties will be accessible as {{this.property}}

	$data['this'] = $context;


	// check if view file exists

	if(!is_file($sourceFile) || ($file=realpath($sourceFile))===false)

		throw new CException(Yii::t('yiiext','View file "{file}" does not exist.', array('{file}'=>$sourceFile)));

	 

	$viewFile = substr($sourceFile, strlen($this->getBasePath()));

	

	$cachedFile = $this->twig->getCacheFilename($viewFile);

	

	//remove file if Source is newer than viewFile and Cache is enabled

	if(@filemtime($sourceFile)>@filemtime($cachedFile) && $this->twig->getCache() !== false)

	{

		@unlink($cachedFile);

	}


	$template = $this->twig->loadTemplate($viewFile);


	if($return)

		return $template->render($data);

	else

		echo $template->render($data);

}



Best regards from germany

Нигде явно не сказано, но для того чтоб заработало наследование в шаблонах, нужно в контроллере вместо render вызывать renderPartial