As written on the API docs: An Action Provider Widget is a widget that has declared several actions by using its 'public static function actions()'. After, a Controller can easily import all its declared actions on its 'public function actions()'.
For the sake of the article we need to create an action named getData that is supposed to be shared among the whole project and saved with the name getData.php on our protected/components/actions folder.
class getData extends CAction{ public function run(){ echo 'HELLO WORLD'; } }
To transform a Widget into an action provider is quite easy (once you know of course). The only thing we need to do is to set the static function actions(). As you will see on the following code, we name the action as GetData and that is the action that will be called in our route. We are going to save the following widget in our protected/components/ folder with the name testProvider.php.
class testProvider extends CWidget{ public static function actions(){ return array( // naming the action and pointing to the location // where the external action class is 'GetData'=>'application.components.actions.getData', ); } }
Finally we set our controller’s actions() function to point to our actions provider.
// This function is in this example // on SiteController public function actions() { return array( // test. is the prefix we are going to use on our URL // for all actions within the actionProvider class // we point to the location where the provider // is. 'test.'=>'application.components.testProvider', ); }
All done, now we can call all the actionProvider actions as controllerID/actionPrefix.actionID. Here is the example:
index.php?r=site/test.GetData
As you all know, and already explained in the wiki Actions Code Reuse with CAction, Actions are classes that extend from CAction, that is, a CComponent. If we wish to pass parameters to the actions that are within the provider, we have to do it this way when configuring your controller (step 3) (Thanks to Attilio for pointing this out):
// This function is in this example // on SiteController public function actions() { return array( // test. is the prefix we are going to use on our URL // for all actions within the actionProvider class // we point to the location where the provider // is. 'test.'=>array( 'class'=>'application.components.testProvider', 'getData'=>array( // property1 must be a public variable // on getData CAction class 'property1'=>'value1', ), ), ); }
Total 8 comments
It is worth noting that, opposite to normal actions, actions defined through provider are case sensitive. For example you can have
in your controller, and have a link
However, if you define the action through action provider, like in this article, you cannot use
This will give you 404 error. You have to use
Is this how we can implement the HMVC in Yii? It sounds like what it is discused here HMVC
Thanks charlie... is now fixed
In the default configuration of Yii, the url has to be index.php?r=site/...
instead of index.php?site/...
@Tony: Maybe you can inlcude what Attilio found out here?
That is not bad approach. Nevertheless, the point of the article was how Yii uses a widget as an action provider which is not documented elsewhere.
The widget encapsulates all the 'shared' actions throughout our application, that means, that we do not need to 'include' one by one all the shared actions . As you can see on the article, I just need to include the Actions Provider and thats it, all its actions will be included at once. This is the actual role of the widget.
let's say : class MyActionWidget extends CWidget { // public $actionPrefix = 'act_'; /no use/
public static function actions(){ return array( 'route1'=>'someName', 'route2'=>'someName2', ); } public function someName(){ $this->render('someView1');} public function someName2(){ $this->render('someView2');}} in controller public function actions() {
return array( 'test.'=>'application.components.MyActionWidget', ); }know i can access it from route: index.php/site/test.rout1 or index.php/site/test.rout2
the key point is that key in actions function of controller('test.') end with dot '.' will be treated as a widget but a CAction subcalss . above code just my imagination , please don't mislead by me.
why do you directly config the actions function of controller like: return array(
now we can access it from route: index.php?site/getData; above is the normally usage;
if follow your way, what's the role of widget? the question is CWidget doesn't extends the CAction , if so we can do a lot , refers to this wiki :http://www.yiiframework.com/forum/index.php?/topic/16357-how-to-use-widget-as-action-provider/page__p__81206__hl__actionPrefix#entry81206
Leave a comment
Please login to leave your comment.