Rendering view outside controller?

Hi,

I asked this question as a part of different thread and get no answer, so I decided to repeat it, as it might get missed.

How can I render a view from a class not being extension to any controller? As in mentioned thread, I’ve created separate class, that does not extends from neither CController nor any other class, to hold all events handlers. One of these events is onException, were I introduce my own exception handler. At the end of my own exception handling, I would like to throw results using render and system error view.

Can I do this, and if yes - then, how? Since class isn’t a descent of CController, I can’t use $this->render.

If you have controller you probably can use Yii::app()->controller to get it.

Nope! As I stated in cited thread, using Yii::app()->controller->render ends with error message "Call to a member function render() on a non-object".

Seems that the only way to solve this problem is to declare event-handling functions inside classes that are descending from any controller and using $this.

What’s the context? Web application? Console application?

Web application…

Looks like controller does not exists when onException is called. In all other cases you can get a controller.

You can implement a simple renderer yourself:




function render($view, $data){

  extract($data);

  ob_start();

  include Yii::getPathOfAlias('application.views').'/'.$view.'.php';

  echo ob_get_clean();

}




Not sure if there is a better solution.

Could it be that there’s no controller, because your exception is thrown before the application found the right controller? Then your approach will fail.

So you should keep custom exception handling as simple and failsafe as possible: Yii might not be in the state you expect it to be yet.

@samdark: Thanks! I changed and extened your solution a little bit, but the idea was great!

@mike: Yes, seems you’re right.

Thanks and cheers!

Hello again!

I would like to reopen this subject in a bit changed context. Is it possible (and how to achieve it) to render user view inside a widget (this is base part of this question - I don’t want to render widget’s specific views!)? I know, that this may lead to a possible threat of for example endless loop (recurrence), when inside widget I’ll be trying to render the very same view where the widget is placed. But even so, I would like to try it and take the chance.

The question is, if inside widget I’m able to access controller that rendered view holding widget and use it to render any view I want - only using partialRender for rendering only a parts of my widget? Or can I access application default controller to render with it, what I want? Or again the only option is to introduce own, simple renderer, as samdark showed?

Let’s say (example for this post) that I have one controller in the app, called DefaultController, which renders view in protected/views/default/index.php and this file contains my widget, from which I would like to be able to partially render any view placed in protected/views/default/for_widget/index.php or hold in the same folder as main view, but marked for example with @: protected/views/default/@*.php.

Thanks in advance for any tips or ideas.

Heh! :] It was easier then I thought! :]


echo($this->controller->renderPartial('@test', NULL, true));

Cheers! :]