Url Rewriting Is Not Working When Action Is Not Given

Recently i have added language parameter in my URL Rules and now they looks like this


'urlManager'=>array(

			'showScriptName'=>false,

   			'caseSensitive'=>false, 

			'urlFormat'=>'path',

			'rules'=>array(

				'<lang:\w+>/<controller:\w+>/<id:\d+>'=>'<controller>/view',

				'<lang:\w+>/<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

				'<lang:\w+>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

			),

but the problem i am facing now is that i have to explicitly set action of views when i use id in my url…for example let me explain the situation


http://localhost/myweb/en/ProductApplications/view/0000000006 

This url should also work as


http://localhost/myweb/en/ProductApplications/0000000006 

since both are representing same url through the rules…both are working fine at this moment …

Now the problem comes when i create the url for suppose when i use CHtml::Link to generate url without the action presence as the second url then it does not work …here is my code


 

Yii::app()->createAbsoluteUrl( 'ProductApplications/' ,array( 'lang'=>Yii::app()->language,'id'=>3211));



the result of this above link generate a wrong link disintegrated like like below


http://localhost/myweb/ProductApplications/lang/en/id/3211

Suppose if i explicitly provide ‘view’ action along controller ‘productApplication’ then it works fine like below


 

Yii::app()->createAbsoluteUrl( 'ProductApplications/view' ,array( 'lang'=>Yii::app()->language,'id'=>3211));


// output http://localhost/myweb/en/ProductApplications/3211



The same issue is with using CHtml::Link , kindly suggest how can i make it correct so it will automatically detect when id is given then it could be either view or update…

Check if it works when you set ‘showScriptName’=>true. If it does, then the problem is in the .htaccess (if apache). In the tutorials that I have seen, you have to adjust the rewrite rules for the server. Check out this Wiki.

Edit 1: Opps: didn’t read fully. Yes you have to include ‘/view’ in your ::links. If you look at the Yii generated code in the controllers, it is always the view file that is referenced. It looks like your code will always go to actionIndex of the ProductApplication controller.

this is my ht access file


Options +FollowSymLinks

IndexIgnore */*

RewriteEngine on




# if a directory or a file exists, use it directly

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d


# otherwise forward it to index.php

RewriteRule . index.php




Thanks for reply so you mean i have to explicitly set view and update to run this , and yes you are right using this format automatically hide the view from the link…But i have one question the same disintegrated url is generated by CGridView




array(

			'header'=>'Remove Auditor',

			'class'=>'CButtonColumn',

			'template'=>'{delete}{update}'

		),

can i override their url creation settings so they will use lang with their template? right now it displays wrong link without lang

I am not sure, but I believe the Grid View uses the urlManager also to generate these links. I think you need to see how to get urlManager to generate the correct link (with lang) without the added array() that you use. I remember an extension that is for selecting the user’s lang for display. Maybe something in there would help.

And yes you need to set view, update, etc for this to work. The rule are looking for <controller>/<action> not just <controller>. If you are generating the link IN the controller, you don’t have to explicitly declare it, just the action, but for the createAbsolute() yes you do.

currently i am using these huge code everywhere




array(

			'header'=>'operation',

			'class'=>'CButtonColumn',

			'template'=>'{delete}{update}',

			'buttons'=>array(

			'update'=>array("url"=>'$this->grid->controller->createUrl("ProductApplications/update",array("id"=>$data["application_id"],"lang"=>"en"))'),

			)

I searched the solution but i cannot find any easy way to do that.

You could subclass the CGridView and modify/overwrite the function that generates the link to add the lang. You could add a public property to pass in the lang. You could also check the accepted_languages supplied by the user’s browser, and pick the first one.

I was just thinking, Why do you need ‘lang’? Why do you need it in your action call? If it is for multi language support, maybe the i18n stuff in Yii would be a better option. You could also set a selected language in the session data and check that in your actions. There are a number of i18n tutorials out there that talk about how use the Yii:t() function, some that also talk about serving whole pages that have been translated.

actually multilingual works fine because source language parameter does not require to be use in url but as far as SEO based url it is recommended to use the two character code of language in the url… That is why i have to use Lang character in my url Rules…but i have searched everywhere there is no way it will add source language in the url automatically or maybe i could not found if there is any other optimize solution not sure…

If you are only serving ‘en’ pages, maybe you could hardcode ‘en’ in your url rules. Have not tried this, didn’t know about the SEO thing. (I can go home now, I’ve learned my one new thing for the day ;D )

Also, in Yii sourceLanguage has a specific meaning, that is different from ‘language’. This maybe the same elsewhere I’m just saying B) sourceLanguage is the lang that the site was written in, and be set in config/main.php. Language is the i18n lang that is to be served.