Problem to create a good SEO friendly route with Laravel - php

I have a SEO project with Laravel, I want to use the routes to config a friendlys dynamic urls.
This is my route:
# Designs
Route::get('/d/{article}-{tag}-{design_name}-{design_id}',['as' => 'web.product_design', 'uses' => 'ProductController#getProductDesign']);
I want to build this SEO friendly url: /d/mug-harry-potter-wingardium-leviosa-xfdsfsdf
And that's what I call the route into any laravel blade view:
route('web.product_design',['article' => 'mug'), 'tag' => str_slug('Harry Potter'), 'design_name' => str_slug('Wingardium Leviosa'), 'design_id' => 'xfdsfsdf'])
The problem is that inside the ProductController I don't receive these parameters as I would like. I think Laravel confuses when it starts and when it finishes the slugs.
For example, in the controller method...
# Product Design Page
public function getProductDesign($article,$tag,$design_name,$design_id) {
dd($article); // It gives me back 'mug', that's right.
dd($tag); // It return me 'harry', is WRONG, I want to get 'harry-potter'.
dd($design_name); // It return me 'potter', is WRONG, I want to get 'wingardium-leviosa'.
dd($design_id); // It return me 'wingardium-leviosa-xfdsfsdf', is WRONG, I want to get 'xfdsfsdf'.
}
How can I build a url SEO friendly and at the same time be able to take the parameters correctly within the controller method?

If you got this in your code
mug-harry-potter-wingardium-leviosa-xfdsfsdf
and exploded it on - then you would be in the same boat. How would you know that harry-potter was a single entity and not two. If you want to have spaces in your parameters, and then slugify them, then you need to choose a different separator in the rest of the URL.
You could switch to _ instead?
Route::get('/d/{article}_{tag}_{design_name}_{design_id}'
so your url is now
mug_harry-potter_wingardium_leviosa_xfdsfsdf

Related

Making sub category in laravel website

so i want to expand my site to have like region site, so when user open my site it will be ask to select which region he/she interested into and lets just say he interesting in London, then the site will generate a webpage that already all content related to that region...
i tried to just do the same way i create administrator page by group them in this route
Route::group(array('prefix'=>'admins','before' => 'auth'),function(){
Route::resource('partner','AdminPartnerController',array('except' => array('show')));
Route::get('partner/index_kategori/{id}',array(
'as' => 'admins.partner.index_kategori',
'uses' => 'AdminPartnerController#index_kategori'
});
but it's mean that i need to create a different controller function for each region i gonna create, so it's not very efficient.
what comes to my mind is just like making
www.websiteadress.com/region
so how i can catch that "/region" and add that value into each my function in controller? how to build that kind of routes?
update:
to make it more easily to understand, what become my problem is like i have this normal route:
Route::get('product/{id}',array( 'as' => 'product','uses' => 'PublicController#product'));
what this route do is pretty straight foward, when i type
www.websiteadress.com/product/12
it will open the product page for number 12, so my problem is if i add like this
www.websiteadress.com/Asia/product/12
how i make my PublicController to catch Asia and later in my product function i will just process that..?
Of course you don't need to create controller for each region. You want to use simple route with a variable:
Route::get('region/{region}', 'RegionController#show');
And just one controller for all regions:
public function show ($region)
{
// Logic here
return view('region.show', compact(['region']));
}
So, when user will load http://example.com/region/London, show action will have London in $region variable.
so after searching for days and asking around, i finally getting the best solution to answer my own question and i willing to share it to here, so someday maybe there is other people who want to do what want to...
so first in the route just create like this
Route::group(['prefix' => '{region}'], function(){
Route::get('member',array('as' => 'member','uses' => 'PublicController#member'));
});
and what this route do is just group it into prefix with value is in region variable and then i set the get route to where the controller will use to show the page and also taking region value into use
and then in my PublicController
public function sitemap($region){
if($region =='london'){
//do something
}else{
//do something
}
}
and so there it is.. i can get those region value from prefix and use it. in my case i use it to show certain page with different content.

Laravel 5: build URL with custom parameters

I have an application in which you can choose between multiple customers.
Choosing a customer will generate following URL:
http://localhost:8000/customer/CUSTOMER_NAME
From there on, I would like to choose a specific sub-page (e.g.: the support page)
How do I generate the following link:
http://localhost:8000/customer/CUSTOMER_NAME/support
So far, I always lose my CUSTOMER_NAME parameter, and I do not know how to keep it.
The framework I use is Laravel 5.
Any ideas?
You shall do this by passing the url param to the view by
I believe you have something like this in your route
Route::get('customer/{id}', 'yourController#yourFunctionName');
Then, in your controller, you may have
public function yourFunctionName($id)
{
return view('yourViewName')->with('id', $id);
}
Then from your view can simply do this to generate a url like this
Click here
To have the url like below
http://yourprojectname/customer/18/support
Advice : Use the Primary key or any unique field rather than using name to avoid some future issues.
Also you shall use helpers to generate url's
Are you using named routes?
Route::get('customer/{name}', ['as' => 'customer.index', 'uses' => 'CustomerController#index']);
You could set up a new route like this:
Route::get('customer/{name}/support', ['as' => 'customer.support', 'uses' => 'CustomerController#support']);
with a method for the support section
public function support($name) {
return view('customer.support', [
'name' => $name,
]);
}
And in your layout you can link to the route.
Support
{{ route('pages.home', $array_of_custom_params) }}
This will generate the link:

CakePHP - Change Controller name in URL

I have a legacy application built in CakePHP 2.2.3
One part of the application has controller file which has been named SymposiumsController.php. This resulted in URL's such as:
domain.com/symposiums
domain.com/symposiums/view/23
The problem is that 'symposiums' isn't a real (English language) word; it should be 'symposia'.
I want to rename my URL's so they are like this:
domain.com/symposia
domain.com/symposia/view/23
I tried to do this by editing app/Config/Routes.php to use this:
Router::connect('symposia/:action', array('controller' => 'symposiums'));
However all this does is redirects domain.com/symposia to domain.com/symposiums which therefore makes no difference to what the user sees in the URL.
To put it simply I don't want 'symposiums' exposed anywhere in my URLs. I want them all to use 'symposia' in it's place.
I read http://book.cakephp.org/2.0/en/development/routing.html but can't see how to do this. Does anyone have a solution? Surely I don't have to rename controllers/models and DB tables to do this?
I don't know if this makes a difference but I also have admin routing switched on so my SymposiumsController.php also has functions such as:
admin_add()
admin_delete()
admin_edit($id)
Any help is appreciated.
Here is the code for this specific redirection:
Router::connect('/:controller/:action/:id',
array('controller' => 'symposiums', 'action' => 'view', 1)
);
:controller => Give the name new name of controller e.g. symposia
:action => Give the name new name of action e.g. view
:id => Give the name new name of controller e.g. 23
But if you need to redirect more than one action then I suggest you to rename the controller.
Note: If you rename the controller or create new Routers then you would need to make sure in the all application modify the link to new controller name.
Source: Cakephp Router

Add JSON routes for all routes to handle backend requests

I'm using Laravel 5.1 and am building a service that can be seen as JSON or HTML. This approach is already done by sites like reddit.
Example
Normal view: http://www.reddit.com/r/soccer
JSON view: http://www.reddit.com/r/soccer.json
As you can see, they simply add .json to an URL and the user is able to see the exact same content either as HTML or as JSON.
I now wanted to reproduce the same in Laravel, however I'm having multiple issues.
Approach 1 - Optional parameter
The first thing I tried was adding optional parameter to all my routes
Route::get('/{type?}', 'HomeController#index');
Route::get('pages/{type?}', 'PageController#index');
However, the problem I was facing here, is that all routes were caught by the HomeController, meaning /pages/?type=json as well as /pages?type=json were redirected to the HomeController.
Approach 2 - Route Grouping with Namespaces
Next I tried to add route groupings with namespaces, to seperate backend and frontend
Route::get('pages', 'PageController#index');
Route::group(['prefix' => 'json', 'namespace' => 'Backend'], function(){
Route::get('pages', 'PageController#index');
});
However, this doesn't work either. It does work, when using api as prefix, but what I want, is that I can add .json to every URL and get the results as json. How can I achieve that in Laravel?
You can apply regular expressions on your parameters to avoud such catch-all situation as you have for HomeController#index:
Route::get('/pages{type?}', 'PageController#index'->where('type', '\.json'));
This way it type will only match, if it is equal to .json.
Then, to access it in your controller:
class PageController {
public function index($type = null) {
dd($type);
}
}
and go to /pages.json

Create a Dynamic URL and Redirect to it in Laravel

So basically this is what I need. I have a router definition like this.
Route::get('view/{postId}', 'PostController#view');
Above router definition will get triggered if the url we request is www.domain.com/view/4. But what I want is I want to appear this url like www.domain.com/[category-of-post]/[titile-of-post] (Ex : www.domain.com/music/easy-chords-in-guitar).
In PostController, I will get the post using the id passed and thus can generate the url what I need. Here is the problem begins. As you can see, I need to redirect to a dynamic url which will look differently for each post. I want to redirect to this dynamic urls but these urls are not defined inside routes.php.
Is this possible in Laravel ?
In short, what I need is, I want to update Illuminate\Routing\RouteCollection::$route array with my dynamically generated url value with corresponding controller action in run time before I am invoking Redirect::to('someurl')
If you need further clarification, I will do it for sure. Please give me your suggestions.
it is simpler than you are thinking.
Route::get('{category}/{title}',['uses' => 'FooController#bar']);
This should be the last route defined in your route list. Any other route should go upper than this one.
this will match www.domain.com/music/easy-chords-in-guitar
rest routes define as you want.
e.g.
Route::get('/',['uses' => 'FooController#home']);
Route::get('about',['uses' => 'FooController#about']);
Route::get('contact',['uses' => 'FooController#contact']);
Route::get('{category}/{title}',['uses' => 'FooController#bar']);
route :
Route::get('action/{slug}', 'HomeController#actionredeemvoucher')->name('home.actionredeemvoucher');
Function in controller:
public function actionredeemvoucher($slug)
{
print_r($slug);
}

Categories