I have a problem with laravel routes. I have a navbar with the urls /products
and /employee
.
I manage to switch between perfectly perfectly without giving error. However, when I access the link /products/new
and from there I try to go back to /products
or go to /employees
through the navbar, the link is /products/products
or /employee/employee
. How do I not replicate the links?
Routes
Route::get('/', function () { return view('index'); }); Route::get('/products', 'ControllerProduct@index'); Route::get('/products/new', 'ControllerProduct@create'); Route::post('/products', 'ControllerProduct@store'); Route::get('/products/show/{id}', 'ControllerProduct@show'); Route::get('/products/delete/{id}', 'ControllerProduct@destroy'); Route::get('/products/edit/{id}', 'ControllerProduct@edit'); Route::post('/products/{id}', 'ControllerProduct@update');
app.blade
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="{{asset('css/app.css')}}"> <meta name="csrf-token" content="{{csrf_token()}}"> <style> body { padding: 20px; } .card { padding: 20px; } h1, h2, h3, h4, h5 { margin: 20px 0 20px 0; } </style> </head> <title>Products</title> <body> <div class="container"> @component('componente_navbar', ["current"=>$current]) @endcomponent <main role="main"> @hasSection('body') @yield('body') @endif </main> </div> <script src="{{asset('js/app.js')}}" type="text/javascript"></script> </body> </html>
index.blade
@extends('layout.app', ["current"=>"home"]) @section('body') @endsection
producs.blade
@extends('layout.app', ["current"=>"products"]) @section('body') <h5 class="card-title">Product Registration</h5> <div class="card border"> <div class="card-body"> @if(count($products)>0) <table class="table table-ordered table-hover"> <thead> <tr> <th>ID</th> <th>Título</th> <th>Ações</th> </tr> </thead> <tbody> @foreach($products $pro) <tr> <td>{{$pro->id}}</td> <td>{{$pro->titulo}}</td> <td> <a href="/products/show/{{$pro->id}}" class="btn btn-sm btn-success">Show</a> <a href="/products/edit/{{$pro->id}}" class="btn btn-sm btn-primary">Edit</a> <a href="/products/delete/{{$pro->id}}" class="btn btn-sm btn-danger">Delete</a> </td> </tr> @endforeach </tbody> </table> @endif </div> <div class="card-footer"> <a href="/products/new" class="btn btn-sm btn-primary" role="button">New Products</a> </div> </div> @if (session('status')) <br> <div class="alert alert-danger"> {{ session('status') }} </div> @endif @endsection
new_products.blade
@extends('layout.app', ["current"=>"products"]) @section('body') <h4>Products Registration</h4> <div class="card border"> <form action="/products" method="POST"> @csrf <div class="form-group"> <label for="title_product">Titulo:</label> <input type="text" class="form-control" name="title_product" required> <br> <label for="cod_product">Código:</label> <input type="text" class="form-control" name="cod_product" pattern="d{3}-d{3}-d{1}" placeholder="Ex.: 000-000-0" required> <br> <label for="date_product">Data:</label> <input type="text" class="form-control" name="date_product" pattern="d{2}/d{/}/d{4}" placeholder="Ex.: dd/mm/aaa" required> <br> <label for="value_product">Valor:</label> <input type="number" class="form-control" name="value_product" step="0.01" required> <br> </div> <button type="submit" class="btn btn-primary btn-sm">Ok</button> <button type="submit" class="btn btn-danger btn-sm">Cancel</button> </form> </div> @endsection
componente_navbar.blade
<nav class="navbar navbar-expand-lg navbar-dark bg-dark rounded"> <div class="container-fluid"> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item"> <a @if($current=="home") class="nav-link active" @else class="nav-link" @endif aria-current="page" href="/">Home</a> </li> <li class="nav-item"> <a @if($current=="projects") class="nav-link active" @else class="nav-link" @endif href="projects">Projects</a> </li> <li class="nav-item"> <a @if($current=="employees") class="nav-link active" @else class="nav-link" @endif href="employees">Employees</a> </li> </ul> </div> </div> </nav>
Advertisement
Answer
The problem is with how you have specified your href
values on your a
links, they are all defined as relative to the current path:
<a ... href="employees" />
What the above says is; from where I am currently, take me to the employees
page. If you’re at the root (/
) of your application then the path is /employees
. However, if you are anywhere else, the path is /you-are-here/employees
.
What you really want to do is use one of the Laravel URL helpers such as url()
or route()
.
I personally favour the route
helper as it uses the name you have defined for a route meaning if the path for a given route changes, you only need to change it in your web.php
file and don’t have to go searching your code base for instances of /some/path/used/everywhere/
.
You define a name for your route on the route definition in your web.php
file, so for example:
Route::get('/products', 'ControllerProduct@index')->name('products.index');
With a name defined (they must be unique by the way), you can use the name in conjunction with the route()
helper:
<a ... href="{{ route('products.index') }}">Projects</a>
Now it doesn’t matter how deep you are in your site structure, your link will always take you to /products
.
On a side note, seeing as you appearing to be doing CRUDDY operations, you might want to consider using the resource
method available on Route
. This defines all your common routes and their names for you.
Route::resource('/products', 'ProductController'); Route::resource('/employees', 'EmployeeController');
Note that these assume you’re following naming conventions. So rather than /products/new
it’s /products/create
and your controllers as named {Something}Controller
. Follow framework conventions where possible, it will save you and other headaches down the line.