Mapping route to another route in Laravel - php

I am developing an application in the Laravel 5.2 which must have a friendly URL-s. This is not problem with the regular way, where the {slug} wildcard is handled by a controller but I want to make it in a different way.
For now I have only two controllers:
ProductsController#show to show details product
CategoriesController#show to show selected category with listing products which are assigned to it
And routes:
Route::get('product/{product}', 'ProductsCategory#show')->name('product.show');
Route::get('category/{category}', 'CategoriesController#show')->name('category.show');
So when I want to echo a just use route('product.show', compact('product'))
Nothing special until I want to handle different URL-s which are fetched from a database. I thought it will be possible to make an another routes which are assigned to existing and when I use a route(...) helper it will be handled automatically. But it is not. So for example I have a new URL:
domain.com/new-url-for-product.html
so by route it should be assigned to the regular 'product.show' route with some ID, which is handled by route model binder for {product} wildcard. The same for route(..) helper it should print friendly URL-s.
I don't know if my strategy is good. How do you handle with the similar problems?

of course route will handle this automatically. have a look into this. I am just giving you example, you have to set this code as per your need.
route('product.show', 'product'=>'new-url-for-product.html');
will generate this
domain.com/new-url-for-product.html
route('product.show', 'product'=>'new-url2-for-product.html');
will generate this URL
domain.com/new-url2-for-product.html
and so on, and then you have to handle all this in your controller method.
eg: your controller method for this route is ProductsCategory#show which is
public function show($product){
if($product == 'new-url-for-product.html'){
//perform this
}
if($product == 'new-url2-for-product.html'){
//perform this
}
}
this just an example, you have to map this according to your need
Edited Here is the example I tested it
Route::get('/product/{product}.html', ['as'=>'product.show', 'uses'=>'ProductsCategory#show']);

Related

Naming routes different from Controller / Database

In a Laravel 5.8 app i want my url's to be in Dutch, however, for consistency and just general easier use, i want to name everything else by their English names. Eloquent will ( as far as i know ) only pass me the proper vars if my Model, Controller, table etc. are all named the same.
Right now, i have a route named /backend/facturen which in English would be /backend/invoices. I have tried using names routes, however, i found that this wasn't what i was looking for.
My route:
Route::resource('/backend/facturen', 'InvoicesController');
My show method inside the InvoicesController:
public function show(Invoice $invoice) {
return view('backend.invoice.show', compact('invoice'));
}
The database table is named 'invoices'.
The only way so far i have got this to work is by renaming my route to:
Route::resource('/backend/invoices', 'InvoicesController');
But, of course, this is not a solution to my problem.
I would like to see all data from the invoices show up on my ( Dutch ) /facturen route.
Resource controllers by default look for a variable with the same name as the (last part of the) URL, so renaming the URL changes that variable as well.
But you can tell Laravel to use a different name:
Route::resource('/backend/facturen', 'InvoicesController')->parameters([
'facturen' => 'invoice'
]);
You could also get the variable itself from the id, without using the laravel magic to correctly detecting the variable from the url:
public function show($id) {
$invoice = Invoice::findOrFail($id);
return view('backend.invoice.show', compact('invoice'));
}
No, you have registered a route pointing to the URL /backend/facturen, to name it, use the name function:
Route::resource('/backend/facturen', 'InvoicesController')->name('backend.invoice.show');
Even then, it won't show that route, when using the view function you need to pass the path to your template, not the route.

Laravel call controller based upon query string or post variables

I am creating APIs for an app. Now app developer wants me to create a fixed base url and pass the ROUTE NAME (Which will point to controller function) as POST variable. Example:
http://example.com/Api
and POST variables like:
action=>'ROUTE_NAME'
But in laravel we can define the routes based upon the url parts as:
http://example.com/Api/ROUTE_NAME
I have tried using a single controller and loading the other controllers based upon SWITCH statements. But that doesn't seem to be a standard practice as i need to add switch condition every time I'll create a new API. Also middleware will not work on the loaded controllers dynamically.
Is there a way in laravel to achieve this? I am using laravel 5.4
You could implement a middleware that listens on the /Api route, which gets the ROUTE_NAME from the $request, then you could use the Route() helper function to find the url of that named route, then redirect the request to that route.
Something like:
// Generating ROUTE_NAME url...
$url = route($request->route_name);
// Redirect to that route...
return redirect()->route($url);
Obviously you'll need to add code to handle if it doesn't find a route etc, maybe return a json response back with a proper error code etc.

Routing in CodeIgniter for (:any)

I'm trying to make my CodeIgniter application work similarly to WordPress.
I want to be able to make these kind of URLs:
http://www.example.com/my-post-example
http://www.example.com/new-headline-here
http://www.example.com/i-love-stackoverflow
My routing:
$route['(:any)'] = "core/index/$1";
Which will call my Core controller and pass the page name into the index function.
I then lookup in my database for the page name and display the page to the user. So far so good.
However, there will be times when I want to call another controller. For example:
http://www.example.com/admin/edit_page/3
http://www.example.com/admin/settings
Now I assume my route will just grab all these rules and send them into my Core controller. Is there a way to make an exception for certain pages? Or is it a good idea to do this check inside my Core controller.
For example,
if ($page not in DB) {
// Call controller/method
}
This seems a little redundant since I just want CodeIgniter to handle this.
The routing rule you using it is OK for your purpose.
If you use http://www.example.com/admin/edit_page/3 this link it will send you admin controller and edit_page method.It will not use routes any rule.
However you will get one problem if your link looks like this
http://www.example.com/my-post-example/test
It will try to go my-post-example controller and test method.
Again http://www.example.com/admin will use routes any rule, means it will redirect your to core controller instead of admin/index. In that case your url should be http://www.example.com/admin/index
Finally If you call your other link with controller/method name it will be OK using your any rule

Route::controller with optional parameters in Laravel 4

I'm just new to Laravel but I immediately fell in love with it. As a not so super experienced php developer I do find the official documentation, although very expansive, somewhat complicated to use and find everything I need.
My question is about the Routing component. As the documentation states you can assign a route to a controller with the Route::controller method. So if I want a Blog controller for all /blog/ routes I assign it like this:
Route::controller('blog', 'BlogController');
So then if I'd like to acces all my blog posts I acces the the getIndex method by www.foo.com/blog or www.foo.com/blog/index
But let's say I'd like to be able to display categories via a getCategory method. My url would look like www.foo.com/blog/category and if, for example, I want to get the news category from the DB by slug, I'd like to use: www.foo.com/blog/category/news as the URI.
My question now is, how do I pass the slug to the url and access it in the getCategory method? Do I need specify it via Route::get('blog/category/{slug}', 'BlogController#getCategory') or is there a way to use Route::controller('blog', 'BlogController') and to send and acces parameters from the URL in the getCategory method?
I already tried to find it via google and in the official documentation, but I couldn't find a crystal clear answer to this problem...
You can simply add parameters to your getCategory method:
public function getCategory($category) {
die($category);
}
If you initialize it to null in the parameter list, it becomes optional. Alternatively, you can always pull parameters from the Input object but they would need to be passed in querystring format:
$category = Input::get('category');
With that said, I'd caution against using the Controller route. It's handy and mimics traditional MVC frameworks, but I believe it's planned to be deprecated -- and honestly, you miss out on some pretty flexible features.
using Route::controller('blog', 'BlogController'); allows you to define a single route to handle every action in a controller using REST naming conventions.then you have to add methods to your controller, prefixed with the HTTP verb they respond to. That means if you have a method called getIndex() it will be executed when there is a GET request to the url "yoursite.com/blog".
To handle POST requests to the same url add a method prefixed with post(ex: postComment()) and so on for other http verbs PUT, PATCH and DELETE.
I think you want something more customized, so you can use a resource controller:
Route::resource('blog', 'BlogController');
This will generate some RESTful routes around the blog resource, run php artisan routes in your project folder to see the generated routes, it should be something like this:
Verb Path Action Route Name
GET /blog index blog.index
GET /blog/create create blog.create
POST /blog store blog.store
GET /blog/{blog} show blog.show
GET /blog/{blog}/edit edit blog.edit
PUT/PATCH /blog/{blog} update blog.update
DELETE /blog/{blog} destroy blog.destroy
in the action column are the functions that you should have in the controller.
If you want to define more routes you can simply do it with Route::get or Route::post in the routes.php file
I hope this will make it more clear for you, enjoy routing with Laravel!!!

PHP Laravel extending resource routing

Laravel routing functionality allows you to name a resource and name a controller to go with it. I am new to Laravel and would like to know if anyone knows how to extend the resources method in the route class provided.
Basically say I have: (which works fine)
/invoices
But say I want:
/invoices/status/unpaid
How is this achievable?
To see the basics of what I am doing check:
http://laravel.com/docs/controllers#resource-controllers
Resource controllers tie you into a specific URLs, such as:
GET|POST /invoices
GET|PUT /invoices/{$id}
GET /invoices/create
and so on as documented.
Since, by convention, GET /invoices is used to list all invoices, you may want to add some filtering on that:
/invoices?status=unpaid - which you can then use in code
<?php
class InvoiceController extends BaseController {
public function index()
{
$status = Input::get('status');
// Continue with logic, pagination, etc
}
}
If you don't want to use filtering via a query string, in your case, you may be able to do something like:
// routes.php
Route::group(array('prefix' => 'invoice'), function()
{
Route::get('status/unpaid', 'InvoiceController#filter');
});
Route::resource('invoice', 'InvoiceController');
That might work as the order routes are created matter. The first route that matches will be the one used to fulfill the request.

Categories