Make Widgets selfcontained

On the wiki is a good Example how to use a widget to set the language of an application (http://www.yiiframework.com/wiki/26/setting-and-maintaining-the-language-in-application-i18n)

My question is: How can I change this example, so that I don’t need to change the Controller and get the same functionality.

Background: I have many from implemented as Widgets and they clutter the controller with code needed to process the $_POST data. Is there any solution to get rid of any code in the controller or can’t Yii provide such a feature?

Thanks

you should be more specific, question unclear…

What is the problem?

To process the form, you have to add code to the Controller. If you have many Forms as Widgets, because you reuse them on multiple places, your controller gets cluttered with the processing for every form.

The following code, from the example, resides in the controller.




 if (isset($_POST['_lang']))

        {

            $app->language = $_POST['_lang'];

            $app->session['_lang'] = $app->language;

        }

        else if (isset($app->session['_lang']))

        {

            $app->language = $app->session['_lang'];

        }



That may be find for one form. But if you add another, the controller get’s filled up with code for the form processing.

So if you want to reuse such a widget in another application, you need to copy also the code for the controller.

I’d like to have just the widget (plus the view) and nothing else make the code more modular.

Hope i’ts clearer now.

This problem is not new: http://www.yiiframework.com/forum/index.php?/topic/7343-self-contained-ajaxian-widgets

I have the only one question: what will be the difference between a controller and a "self-contained" widget? Both will have actions, access rules, etc.

It’s not about the actions/rules, it’s about the ability to reuse the widget without cluttering the controller action with code to process the $_REQUEST.

I think of an widget which process it’s request and then hands the request handling to the actual controller which was called.

It’s more a question if it’s possible or not.

The typical problem is, if the request is processed in the run() method of the widget, the controller has no chance to react on the input from the request.

http://www.yiiframework.com/forum/index.php?/topic/7343-self-contained-ajaxian-widgets seems the right direction to me.

Maybe this will also help you: http://www.yiiframework.com/wiki/146/how-to-use-a-widget-as-an-action-provider/

The controller mentioned in the wiki should be a parent/base controller, so you only need to implement this once per app. IMO, if you allow widgets to handle GET/POST data, you blur the line between a controller and widget. Let’s say you have a widget that displays a login/signup form for a guest and a logout link for a logged in user. If the widget is to handle all the scenarios for logins (active, inactive, suspended users etc.) it’s going to become bloated and not a whole lot different from a controller - not to mention handling access rules etc. This leads to embedding a conget (controller + widget) in a view i.e. MVCC

Don’t be afraid to get your controllers dirty, that’s what they’re there for. If you do want to separate your widget handling, look at andy_s’s link.

Just my 2 cents.

Matt

Well, whats about separation of concerns? With this approach I don’t really see any separation.

And the paradigm fat model/skinny controller is also violated, if I put everything into the controller.

With this approach the reuse of widgets through many projects is very limited, if I it’s always needed to also change the controller.

But it seems, that Yii just can’t handle this use case.