How to use a Widget as an Action Provider

38 followers

What is an Action Provider Widget?

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()'.

Step 1: Create the Action Class

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';
    }
}

Step 2: Configure the Widget

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',
        );
    }
}

Step 3: Configure the Controller

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

Passing Parameters to Actions

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

#11716 report it
Jmper at 2013/01/29 05:54am
Action maps are case sensitive

It is worth noting that, opposite to normal actions, actions defined through provider are case sensitive. For example you can have

public function actionGetData() {
...
}

in your controller, and have a link

index.php?r=controller/getdata

However, if you define the action through action provider, like in this article, you cannot use

index.php?r=controller/test.getdata

This will give you 404 error. You have to use

index.php?r=controller/test.GetData
#11097 report it
Cherif at 2012/12/16 04:00pm
HMVC

Is this how we can implement the HMVC in Yii? It sounds like what it is discused here HMVC

#6576 report it
Antonio Ramirez at 2012/01/19 09:15am
@charliehyii

Thanks charlie... is now fixed

#6555 report it
Charlie Hand at 2012/01/18 11:38am
Incorrect URL

In the default configuration of Yii, the url has to be index.php?r=site/...

instead of index.php?site/...

#4110 report it
Mike at 2011/06/07 05:56am
Passing additional parameters to specific actions

@Tony: Maybe you can inlcude what Attilio found out here?

#3787 report it
Antonio Ramirez at 2011/05/08 05:38am
@yiqing95

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.

#3714 report it
yiqing95 at 2011/05/01 07:37am
widget as Action

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.

#3713 report it
yiqing95 at 2011/05/01 07:17am
widget as Action

why do you directly config the actions function of controller like: return array(

  'getData'=>'xx.xxx.getData',
);

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 to leave your comment.

Write new article