change controller's action calling from URL???

Hi everybody.

I have an URL


http://something-and-yii/

and menu links:




http://something-and-yii/index.php?r=site/index

http://something-and-yii/index.php?r=site/aboutUs



site/index calling actionIndex in SiteController, and

site/aboutUs calling actionAboutUs in SiteController, of course

but the "aboutUs" is not so good in URL, "about-us" is better

so, I want to call actionAboutUs in SiteController from URL index.php?r=site/about-us

how to automatize it?

about-us -> actionAboutUs

this-is-me -> actionThisIsMe

I can do it, like that




$url = strtolower(<get action name from an URL>);

$temp = explode("-", $url);

$actionName = 'action';

foreach ($temp as $part) {

     $actionName .= ucfirst($part);

}



but don’t know where …

thank you.

You may read this article about url management. You can do this:


http://example.com/

http://example.com/about-us

Yes, you can use CUrlManager component, but if you just want to call actions aboutUs, aboutMe, aboutThem for routes like http: //something-and-yii/index.php?r=site/about-us then you can rewrite Controller’s missingAction() method: http://www.yiiframework.com/doc/api/CController#missingAction-detail, where you should call run() method to run aboutUs action instead of about-us.

thank you

i’ve got it … to my site SiteController i wrote:




public function missingAction($missingActionId) {

		

		switch($missingActionId) {

			default:

			case '': {

				throw new CHttpException(404,Yii::t('yii','The system is unable to find the requested action "{action}".',

			array('{action}'=>$missingActionId==''?$this->defaultAction:$missingActionId)));

				break;

			}

			case 'about-us': {

				$this->render('about-us');

				break;

			}

		}

	}




this works nice, but, what if i want to do it widely, not only for one controller.

if i use this solution, i should add to every controller missingAction() function, and it’s not so pure …

even through, thank you :)

Yes, I can, but creating rules slow down my application :)

But not much, not much at all ;)

You can extend CController class, e.g.:




class MyController extends CController

{

    public function missingAction($missingActionId) 

    {

        // Some code, where you transform any $missingActionId string (with hyphen) 

        // into $action (without hyphen)


        if (method_exists($this, 'action'.$action))

        {

            $this->run($action);

        }

        else

        {

            parent::missingAction($missingActionId);

        }

    }

}



And then use MyController as a parent for all you controllers.

interesting :)

and this is a final code:




class MyCController extends CController

{

	public function missingAction($actionID) {

	

		$actionName = "";

		$temp = explode("-", $actionID);

		

		foreach ($temp as $item) {

			$actionName .= ucfirst(strtolower($item));

		}

		

		if (method_exists($this, "action" . $actionName)) {

			$this->run($actionName);

		}

		else {

			parent::missingAction($actionID);

		}

		

	}

}



and my problem has solution now. 8)

One tip: don’t use “C” prefix for your components :)