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>
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.