Yii url routing - yii

i have a url example.com/information/london. whenver some one calls this url i want to call a controller information and its index method. but i want to pass slug as jobs-in-london i.e. example.com/information/jobs-in-london how can i achive this by writing url rule in config/main.php.
i.e i want to redirect my page example.com/information/london to example.com/information/jobs-in-london but dont want to use .htaccess i want to achieve this only by url routing rules i have tried this by writing
'<_c:(information)>/<slug:london>'=>'information/index/jobs-in-london'
but this wont work for me.
class InformationController extends Controller
{
public function actionIndex($slug)
{
CVarDumper::dump($slug,10,true);
exit;
}
}

Your question is unclear. You may mean either of the following:
Url:
example.com/information/london
example.com/information/singapore
Rule:
'information/<slug>' => 'information/index',
Controller:
public function actionIndex($slug)
{
$slug = "jobs-in-".$slug;
var_dump($slug);
}
Slug Result:
jobs-in-london
jobs-in-singapore
Url:
example.com/information/jobs-in-london
example.com/information/jobs-in-singapore
Rule:
'information/<slug:jobs-in-.+>' => 'information/index',
Controller:
public function actionIndex($slug)
{
var_dump($slug);
}
Slug Result:
jobs-in-london
jobs-in-singapore

Here is what you will exactly have to do in the routes:
'<controller:(information)>/<slug:>' => '<controller>/index'
and here is how to add the slug while you're creating the URL:
Yii::app()->createUrl('information/index', array('slug' => 'jobs-in-london'));
and to check what the slug is, what you did to the function is correct.

Related

Route segment without matching controller or action in ASP.NET Core

Take a look at this route:
{controller}/{currency=USD}/{action=view}
It matches URLs of type rates/GBP/edit (and others as well..). Rates map to controller and edit maps to view. Thats fine. What I don't understand is to what the middle segment GBP is matched to.
If it would be the other way around => {controller}/{action=view}/{currency=USD}, GPB would be a parameter to action method. But with current syntax, it looks like a parameter for controller which doesn't make sense.
Example route config:
app.UseMvc(routes =>{
routes.MapRoute(
name:"def",
template:"{controller}/{currency=USD}/{action=view}"
);
});
Example controller:
public class RatesController : Controller{
public IActionResult Edit(){
return View();
}
}
So, to what code is currency matched, if any? Perhaps the same question.. how can I access the currency segment value?

Appending hash/fragment to RedirectResult results in cumbersome code

The code works but is silly.
When the View is returned to the user the page scrolls to the companyId anchor.
Silly is that I have to expose another public action with another route (without 'terms')
I want to redirect to /terms/companyId but then I get an ambigiousAction exception that this action with same routes already exists...
How to solve that dilemma if possible not change the first route?
[HttpGet("~/terms/{companyId}")]
public IActionResult Home(string companyId})
{
string url = Url.Action(nameof(HomeForRedirect), new { companyId}) + "#conditions";
return new RedirectResult(url);
}
[HttpGet("{companyId}")]
public IActionResult HomeForRedirect(string companyId)
{
Viewbag.CompanyId = companyId;
return View(nameof(Home));
}
If I'm understanding your code, you essentially want the URL /terms/{companyId} to redirect to /{controller}/{companyId}#conditions? The easiest path would be to attach both routes to the same action and do the redirect in a conditional. Something like:
[HttpGet("{companyId}", Order = 1)]
[HttpGet("~/terms/{companyId}", Order = 2)]
public IActionResult Home(string companyId)
{
if (Context.Request.Path.StartsWith("/terms"))
{
var url = Url.Action(nameof(Home), new { companyId }) + "#conditions";
return Redirect(url);
}
ViewBag.CompanyId = companyId;
return View();
}
An even better method would be to simply do the redirect directly in IIS. There's a not insignificant amount of processing that needs to occur to handle a request in ASP.NET Core machinery, and it's totally wasted effort simply to redirect. Use the URL Rewrite module in IIS to set up your redirect for this URL, and then your application doesn't have to worry about it at all. You just have your normal run-of-the-mill Home action that returns a view, and everything will just work.
A few other notes since it seems like you're new to this:
It's better to use the Route attribute rather than the more specific HttpGet etc. The default is GET.
Return the controller methods like Redirect rather than instances of IActionResult (i.e. new RedirectResult(...)).
The default is to return a view the same name as the action. So, assuming your action is Home, you can just do return View(), rather than return View(nameof(Home)).

Yii rules urlManager

My URL Rule is as below :
'product-<typeproduct:.{1,255}>-prd-<positionIds:[\d\-]+>.html' => 'site/products/bycate',
I want to get positionIds in Array variable.
So is it possible to send positionIds in Array as below ? :
'product-<typeproduct:.{1,255}>-prd-<positionIds:array[\d\-]+>.html' => 'site/products/bycate',
As I understood you want to get it as array so url would be something like this:
'/product-2-prd-222,223,224.html'
Where 222,223,224 are positionId's that you want to obtain in array.
As of I know, this cannot be done without creating urlRule class which would look something like this:
class ProductsUrlRule extends UrlRule
{
public function parseRequest($manager, $request)
{
if (preg_match("/product-([0-9]+)-prd-([0-9,]+).html/",$request,$vars)===3) {
$typeProduct = $var[1];
$productIds = explode(',',$var[2]);
return [
'controller/action',
'typeproduct'=> $typeProduct,
'positionIds'=>$productIds
];
}
}
}
this will parse example url that I showed you above to something like this:
'?r=controller/action&typeproduct=2&positionIds[]=222&positionIds[]=223&positionIds[]=224'
Ofcourse you need to replace controller/action with your controller/action pair and later to validate fields.

Yii router rule to redirect a keyword to an action's $_GET Parametric

In Yii, is it possible to use the router rule to "translate" a keyword in a URL to a certain action's $_GET Parametric?
What I want, is to let this URL:
http://example.com/MyModule/MyController/index/foo
to point to:
http://example.com?r=MyModule/MyController/index&id=12
where foo points to 12.
And, since I am using "path" urlFormat, and are using other url rules to hide index and id=, the URL above should eventually point to:
http://example.com/MyModule/MyController/12
Is this possibe by setting rules in the config file for urlManager component?
Your action should accept a parameter $id:
public function actionView($id) {
$model = $this->loadModel($id);
What you need to do, is to modify the loadModel function in the same controller:
/**
* #param integer or string the ID or slug of the model to be loaded
*/
public function loadModel($id) {
if(is_numeric($id)) {
$model = Page::model()->findByPk($id);
} else {
$model = Page::model()->find('slug=:slug', array(':slug' => $id));
}
if($model === null)
throw new CHttpException(404, 'The requested page does not exist.');
if($model->hasAttribute('isDeleted') && $model->isDeleted)
throw new CHttpException(404, 'The requested page has been deleted for reasons of moderation.');
// Not published, do not display
if($model->hasAttribute('isPublished') && !$model->isPublished)
throw new CHttpException(404, 'The requested page is not published.');
return $model;
}
Then, you will need to modify the urlManager rules to accept a string, instead of just an ID:
Remove :\d+ in the default rule below:
'<controller:\w+>/<id:\d+>' => '<controller>/view',
It should be like this:
'<controller:\w+>/<id>' => '<controller>/view',
One more thing to note, if you are going this path, make sure slug is unique in your database, and you should also enforce the validation rule in the model:
array('slug', 'unique'),

How do I make a construct to have beforeAuth only apply to certain views/functions in Laravel 4

I have a resource in Laravel I have called artists with an ArtistsController. I would like to add filters to some of the pages, but not all. I know I can add a filter to all of the functions/views in the resource controller like so:
public function __construct()
{
$this->beforeFilter('auth', array('except' => array()));
}
How do I add the beforeAuth filter to only a certain view/function? I would like a user to be logged in in order to go the "index" view, but I would like a user to be able to go to the "show" pages without necessarily being logged in:
public function index()
{
$artists = Artist::all();
return View::make('artists.index', compact('artists'))
->with('artists', Artist::all())
->with('artists_new', Artist::artists_new());
}
public function show($id)
{
$artist = Artist::find($id);
return View::make('artists.show', compact('artist'))
->with('fans', Fan::all());
}
Is there a way to do this? Thank you.
Not sure if this helps but you could use the only key instead of the except (if I understand your question correctly).
$this->beforeFilter('auth', array('only' => array('login', 'foo', 'bar')));
Although that would still go in the constructor.