Laravel 8 how to split url into seo friendly? - laravel

I am using laravel 8 and currently my url is looking as
http://127.0.0.1:8000/?country_id_to=1
and I want to set URL as
http://127.0.0.1:8000/uk/en/pakistan
In each route. Ihave no idea to do it.

To add on #Douwe de Haan comment - and be more precise have a look at this page: https://laravel.com/docs/8.x/routing#route-parameters
For your example you could do
Route::get('/{localization}/{language}/{country}', function ($localization, $language, $country) {
// your code
});
Where
http://127.0.0.1:8000/uk/en/pakistan
Would now result in
$localization = "uk";
$language = "en";
$country = "pakistan";
This will obviously also work with a controller.
If you want to reference an entity not by its ID but by a custom field you can do that as well
https://laravel.com/docs/8.x/routing#customizing-the-default-key-name

Related

rewriting the URLs dynamically laravel

I am trying to rewrite some of the pages URL in my web app, for example, I have a company details page and I want the URL of this page to contain the name of the company without space or special characters and to have the id too, and I have no idea on how to do that or where to start.
I tried adding the name of the company in the route as a parameter like this:
Route::get('/{RS}-{id}', 'App\Http\Controllers\SiteController#getDetails')->name('details');
It didn't work for some reason and even if it worked there's no way to replace the special characters with their normal form and replace the space with dashes.
This the URL I'm getting: http://mywebsite.come/entreprise_details-13109
this the URL I want: http://mywebsite.come/yoorika-managements-13109 ( with Yoorika Managements being the name of the company )
I searched a lot but I can't seem to find what I am looking for, I just need someone to help me find the right term. thank you!
In route :
Route::get('/{input}', 'App\Http\Controllers\SiteController#getDetails')->name('details');
In controller :
public function getDetails($input)
{
$input_array = explode("-", $input);
$name = $input_array[0];
$id = $input_array[1];
$data = MyModel::where('id', $id)->get();
// return data to view
}
In list view, you may display data like this (table cell ) :
<td> <a href="/{{name .'-'.{{id}}"> {{name .'-'.{{id}}<td/>

show name instead of id in a url using laravel routing

I have defined a route in laravel 4 that looks like so :
Route::get('/books/{id}', 'HomeController#showBook');
in the url It shows /books/1 for example , now i'm asking is there a way to show the name of the book instead but to keep also the id as a parameter in the route for SEO purposes
thanks in advance
You could also do something like this:
Route::get('books/{name}', function($name){
$url = explode("-", $name);
$id = $url[0];
return "Book #$id";
});
So you can get book by id if you pass an url like: http://website.url/books/1-book-name
if your using laravel 8, this may be helpfull.
In your Controller add this
public function show(Blog $blog)
{
return view('dashboard.Blog.show',compact('blog'));
}
In your web.php add this
Route::get('blog/{blog}', [\App\Http\Controllers\BlogController::class,'show'])->name('show');
Then add this to your model (am using Blog as my Model)
public function getRouteKeyName()
{
return 'title'; // db column name you would like to appear in the url.
}
Note: Please let your column name be unique(good practice).
Result: http://127.0.0.1:8000/blog/HelloWorld .....url for a single blog
So no more http://127.0.0.1:8000/blog/1
You are welcome.
You can add as many parameters to the url as you like, like this:
Route::get('/books/{id}/{name}', 'HomeController#showBook');
Now when you want to create an url to this page you can do the following:
URL::action('HomeController#showBook', ['id' => 1, 'name' => 'My awesome book']);
Update:
If you are certain that there will never be two books with the same title, you can just use the name of the book in the url. You just need to do this:
Route::get('/books/{name}', 'HomeControllers#showBook');
In your showBook function you need to get the book from the database using the name instead of the id. I do strongly encourage to use both the id and the name though because otherwise you can get in trouble because I don't think the book name will always be unique.
You can also use model binding check more on laravel docs
For example
Route::get('book/{book:name}',[BookController::class,'getBook'])->name('book');
The name attribute in "book/{book:name}" should be unique.

Laravel routing - shorten the urls upto only one URI segment.

It is said that shorter the URL, better the seo (atleast my client believes on it).
Now am creating website similar to watchtown.co.uk in laravel. I need to generate in such a way that the uri should not be more than one segment.
Requirement
I have following urls:
1.Need to change From:
localhost/laravelproj/public/brands/brandname/watches
to
localhost/laravelproj/public/brandname-watches.html
2.Need to change From:
localhost/laravelproj/public/brands/brandname/jewellery
to
localhost/laravelproj/public/brandname-jewellery.html
3.Need to change From:
localhost/laravelproj/public/categories/categoryname/watches
to
localhost/laravelproj/public/categoryname-watches.html
4.Need to change From:
localhost/laravelproj/public/categories/categoryname/jewellery
to
localhost/laravelproj/public/categoryname-jewellery.html
5.Need to change From:
localhost/laravelproj/public/products/productname
to
localhost/laravelproj/public/productname-watches.html
I hope you understood the pattern .
I can see watchtown.co.uk has done exactly the same (or is it any other way ?)
I created this function in controller for brands:
public function showProductListingByBrands($brandSlug) {
$brand = Brand::findBySlug($brandSlug)->first();
$products = "";
if($brand){
$products = $brand->products()->paginate(Misc::getSetting('paginate'));
}
$products = Product::findBySlug($brandSlug);
return View::make('store');
}
Now how do i manipulate it as my requirement? Im really new in laravel.
Thanks in advance.
Just to give you a brief idea.
On your route page
Route::get('/{product_name}/', array(
'as' => 'product_page',
'uses' => 'ProductPage#getProduct'
));
As you see when the user goes to the page like
Example: www.website.com/watch
it will go to the controller ProductPage with the method of getProduct, so the variable {product_name} will be passed on the controller.
Controller
public function getProduct($product_name = false) {
$product = Products::where('product_name', '=', $product_name);
// Do check product existing record
if ($product->count() == 0) {
return Redirect::route('some-page-error')
->with('failure', 'The hell are you doing?');
} else {
$product = $product->first();
return View::make('product_page')
->with('product_name', $product);
}
}
So on method getProduct, the parameter $product_name is watch
So, the method will check if the product exists or not, if not the user will be redirected to 404 page.
If not, it will be redirected to the template that you've made then pass all the product data and display it all there.
But it would be nice if you put the Route into /product/{product_name}, also it would be also good if it's product id instead of product name since product name can get redundant.
So yea.
edits
I don't know what you're trying to do and why it must be .html, but mmm.. Just wanna give you an idea. Well I don't know if my answer is a good way, someone might give better answer than me.

Country name in codeigniter url

My question is how to append country name in codeigniter url?
Lets say my website is http://mywebsite.com and I am opening the website from Canada so my url should be http://mywebsite.com/canada.
Meaning I just want to append the country name in the url, nothing change except this. I have read about routes of codeigniter, I have googled it but all in vain.
If anyone have a clue how to do this please let me know.
I guess you'd do that with a IP lookup to guess the country based on the request IP address ($_SERVER['REMOTE_ADDR']). Mapping the IP address to a location is pretty well documented. Once you have the country, redirect to the correct controller method.
That what you're looking for?
This is like for language code in url.
With my solution you can put any segment in your uri and hide it to CI.
http://site.com/page.html will be equal to http://site.com/canada/page.html and vice versa.
set_country_uri.php
//App location
$ci_directory = '/ci/';
//countries
$countries = array('canada','france');
//default country
$country = 'canada';
foreach( $countries as $c )
{
if(strpos($_SERVER['REQUEST_URI'], $ci_directory.$c)===0)
{
//Store country founded
$country = $c;
//Delete country from URI, codeigniter will don't know is exists !
$_SERVER['REQUEST_URI'] = substr_replace($_SERVER['REQUEST_URI'], '', strpos($_SERVER['REQUEST_URI'], '/'.$c)+1, strlen($c)+1);
break;
}
}
//Add the country in URI, for site_url() function
$assign_to_config['index_page'] = $country."/";
//store country founded, to be able access it in your app
define('COUNTRY', $country);
index.php
<?php
require('set_country_uri.php');
//ci code ...
So in your CI code use COUNTRY constant to know wich is used. And make your code like routing without take in consideration the country in the uri.

Codeigniter - best routes configuration for CMS?

I would like to create a custom CMS within Codeigniter, and I need a mechanism to route general pages to a default controller - for instance:
mydomain.com/about
mydomain.com/services/maintenance
These would be routed through my pagehandler controller. The default routing behaviour in Codeigniter is of course to route to a matching controller and method, so with the above examples it would require an About controller and a Services controller. This is obviously not a practical or even sensible approach.
I've seen the following solution to place in routes.php:
$route['^(?!admin|products).*'] = "pagehandler/$0";
But this poses it's own problems I believe. For example, it simply looks for "products" in the request uri and if found routes to the Products controller - but what if we have services/products as a CMS page? Does this not then get routed to the products controller?
Is there a perfect approach to this? I don't wish to have a routing where all CMS content is prefixed with the controller name, but I also need to be able to generically override the routing for other controllers.
If you use CodeIgniter 2.0 (which has been stable enough to use for months) then you can use:
$route['404_override'] = 'pages';
This will send anything that isn't a controller, method or valid route to your pages controller. Then you can use whatever PHP you like to either show the page or show a much nicer 404 page.
Read me guide explaining how you upgrade to CodeIgniter 2.0. Also, you might be interested in using an existing CMS such as PyroCMS which is now nearing the final v1.0 and has a massive following.
You are in luck. I am developing a CMS myself and it took me ages to find a viable solution to this. Let me explain myself to make sure that we are on the same page here, but I am fairly certain that we area.
Your URLS can be formatted the following ways:
http://www.mydomain.com/about - a top level page with no category
http://www.mydomain.com/services/maintenance - a page with a parent category
http://www.mydomain.com/services/maintenace/server-maintenance - a page with a category and sub category.
In my pages controller I am using the _remap function that basically captures all requests to your controllers and lets you do what you want with them.
Here is my code, commented for your convenience:
<?php
class Pages extends Controller {
// Captures all calls to this controller
public function _remap()
{
// Get out URL segments
$segments = $this->uri->uri_string();
$segments = explode("/", $segments);
// Remove blank segments from array
foreach($segments as $key => $value) {
if($value == "" || $value == "NULL") {
unset($segments[$key]);
}
}
// Store our newly filtered array segments
$segments = array_values($segments);
// Works out what segments we have
switch (count($segments))
{
// We have a category/subcategory/page-name
case 3:
list($cat, $subcat, $page_name) = $segments;
break;
// We have a category/page-name
case 2:
list($cat, $page_name) = $segments;
$subcat = NULL;
break;
// We just have a page name, no categories. So /page-name
default:
list($page_name) = $segments;
$cat = $subcat = NULL;
break;
}
if ($cat == '' && $subcat == '') {
$page = $this->mpages->fetch_page('', '', $page_name);
} else if ($cat != '' && $subcat == '') {
$page = $this->mpages->fetch_page($cat, '', $page_name);
} else if ($category != "" && $sub_category != "") {
$page = $this->mpages->fetch_page($cat, $subcat, $page_name);
}
// $page contains your page data, do with it what you wish.
}
?>
You of course would need to modify your page fetching model function accept 3 parameters and then pass in info depending on what page type you are viewing.
In your application/config/routes.php file simply put what specific URL's you would like to route and at the very bottom put this:
/* Admin routes, login routes etc here first */
$route['(:any)'] = "pages"; // Redirect all requests except for ones defined above to the pages controller.
Let me know if you need any more clarification or downloadable example code.

Resources