<?phpnamespaceApp\Http\Controllers\Admin;useApp\Http\Controllers\Controller;useApp\Models\Tag;useIlluminate\Http\Request;classTagControllerextendsController{/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/publicfunctionindex(){returnview('admin.tags.index');}/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/publicfunctioncreate(){returnview('admin.tags.create');}/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/publicfunctionstore(Request$request){//
}/**
* Display the specified resource.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctionshow(Tag$tag){//
}/**
* Show the form for editing the specified resource.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctionedit(Tag$tag){returnview('admin.tags.edit',compact('tag'));}/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctionupdate(Request$request,Tag$tag){//
}/**
* Remove the specified resource from storage.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctiondestroy(Tag$tag){//
}}
Dentro del archivo admin.php añado una ruta de tipo resources que me genere las rutas para el crud de las etiquetas, se la asigno al controlador TagController.php y le digo que todas las rutas comiencen con admin.tags.
Ahora debo crear las vistas dentro de la carpeta views, donde creo una carpeta llamada tags para tenerlas todas dentro bien organizadas (resources/views/admin/tags/index.blade.php, resources/views/admin/tags/show.blade.php, resources/views/admin/tags/create.blade.php y resources/views/admin/tags/edit.blade.php). A modo de ejemplo muestro la vista index en la que he cargado la plantilla de adminLTE3.
index.blade.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@extends('adminlte::page')
@section('title', 'Blog con Laravel')
@section('content_header')
<h1>Listado de etiquetas</h1>@stop
@section('content')
<p>Aqui va un listado de etiquetas dentro de una tabla.</p>@stop
@section('css')
<linkrel="stylesheet"href="/css/admin_custom.css">@stop
@section('js')
<script>console.log('Hi!');</script>@stop
Lo siguiente que quiero es modificar es el menú de navegación de la barra lateral de la izquierda. Para ello dentro de adminlte.php modifico la sección Menu Items para que aparezca un enlace a la vista index de las etiquetas.
/*
|--------------------------------------------------------------------------
| Menu Items
|--------------------------------------------------------------------------
|
| Here we can modify the sidebar/top navigation of the admin panel.
|
| For more detailed instructions you can look here:
| https://github.com/jeroennoten/Laravel-AdminLTE/#8-menu-configuration
|
*/'menu'=>[['text'=>'search','search'=>true,'topnav'=>true,],['text'=>'blog','url'=>'admin/blog','can'=>'manage-blog',],['text'=>'Dashboard','route'=>'admin.home','icon'=>'fas fa-tachometer-alt fa-fw',],['header'=>'ADMINISTRADOR'],['text'=>'Categorías','route'=>'admin.categories.index','icon'=>'fab fa-fw fa-buffer','active'=>['admin/categories*'],],['text'=>'Etiquetas','route'=>'admin.tags.index','icon'=>'fas fa-fw fa-lock','active'=>['admin/tags*'],],
Mostrando un listado de etiquetas
En la vista index.blade.phpquiero mostrar el listado de etiquetas que podré crear, editar y borrar. Para ello llamo a la base de datos desde el método index del controlador TagController.php almaceno todas etiquetas dentro de una variable y se la paso a la vista index.blade.php.
Método index de TagController.php
1
2
3
4
5
6
7
8
9
10
11
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/publicfunctionindex(){$tags=Tag::all();returnview('admin.tags.index',compact('tags'));}
En la vista index creo una tabla dentro de un card de bootstrap en el que muestro el id, nombre, color y los botones de editar (ruta admin.tags.edit) y eliminar (admin.tags.destroy) para cada etiqueta. sobre esta lista añado un botón para crear etiquetas que me dirige a la ruta admin.tags.create
@extends('adminlte::page')
@section('title', 'Blog con Laravel')
@section('content_header')
<h1>Lista de etiquetas.</h1>@stop
@section('content')
<p>Aqui aparece un listado de etiquetas</p> // mensajes de exito al editar, crear o eliminar una etiqueta
@if (session('info'))
<divclass=" alert alert-success"><strong>{{session('info')}}</strong></div> @elseif(session('info-del'))
<divclass=" alert alert-danger"><strong>{{session('info-del')}}</strong></div> @endif
<divclass="card"><divclass="card-header"><aclass=" btn btn-secondary float-right"href="{{route('admin.tags.create')}}">Crear Etiqueta</a></div><divclass="card-body"><tableclass=" table table-striped"><thead><tr><th>Id</th><th>Nombre</th><th>Color</th><thcolspan="2"></th></tr></thead><tbody> @foreach ($tags as $tag)
<tr><th>{{$tag->id}}</th><th>{{$tag->name}}</th><th>{{$tag->color}}</th><thwidth="10px"><aclass=" btn btn-primary btn-sm"href="{{route('admin.tags.edit', $tag)}}">Editar</a></th><thwidth="10px"><formaction="{{route('admin.tags.destroy', $tag)}}"method="POST"> @csrf
@method('delete')
<buttonclass="btn btn-danger btn-sm"type="submit">Eliminar</button></form></th></tr> @endforeach
</tbody></table></div></div>@stop
@section('css')
<linkrel="stylesheet"href="/css/admin_custom.css">@stop
@section('js')
@stop
Creando una etiqueta
Una vez que tengo creado el listado de las etiquetas me centro en poder crear una etiqueta nueva. Al hacer clic en el botón crear me envia a la ruta admin.tags.create que es administrada por el método create del controlador TagController.php. Debo pues crear un formulario en la vista resources/views/admin/tags/create.blade.php a la que seré enviado desde el método create.
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/publicfunctioncreate(){$colors=['red'=>'Color rojo','yellow'=>'color amarillo','green'=>'Color verde','purple'=>'Color púrpura','pink'=>'Color rosa'];returnview('admin.tags.create',compact('colors'));}
Como el formulario lo voy a volver a utilizar para editar las etiquetas, lo voy a factorizar de forma que solo tenga que crearlo y realizar las modificaciones futuras sobre un solo archivo. Para ello creo la carpeta resourses/views/admin/tags/partialsy dentro el archivo form.blade.php con los imputs del formulario recién creado.
<divclass="form-group">{!!Form::label('name','Nombre:')!!}{!!Form::text('name',null,['class'=>'form-control','placeholder'=>'ingresa el nombre de la categoria'])!!}@error('name')<spanclass=" text-danger">{{$message}}</span>@enderror</div><divclass="form-group">{!!Form::label('slug','Slug:')!!}{!!Form::text('slug',null,['class'=>'form-control','placeholder'=>'ingresa el slug de la categoria','readonly'])!!}@error('slug')<spanclass=" text-danger">{{$message}}</span>@enderror</div><divclass="form-group">{!!Form::label('color','Color:')!!}{!!Form::select('color',$colors,null,['class'=>'form-control'])!!}@error('color')<spanclass=" text-danger">{{$message}}</span>@enderror</div>
y lo incluyo dentro de la vista resources/views/admin/tags/create.blade.php.
@extends('adminlte::page')
@section('title', 'Blog con Laravel')
@section('content_header')
<h1>Crear Etiqueta</h1>@stop
@section('content')
<p>Aqui va un formulario para crear una etiqueta.</p><divclass="card"><divclass="card-body"> {!! Form::open(['route' => 'admin.tags.store']) !!}
@include('admin.tags.partials.form')
{!! Form::submit('Crear etiqueta', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
</div></div>@stop
@section('js')
<scriptsrc="{{asset('vendor/jQuery-Plugin-stringToSlug-1.3/jquery.stringToSlug.min.js')}}"></script><script>$(document).ready(function(){$("#name").stringToSlug({setEvents:'keyup keydown blur',getPut:'#slug',space:'-'});});</script>@endsection
Al hacer clic en el botón Crear etiqueta toda la información del formulario se envía a la ruta admin.tags.store que es gestionada por el método store del controlador TagController.php. En este método valido los datos recibido en $request y los almaceno como un registro en la tabla tags de la base de datos del blog. Acto seguido le pido que me redirija a la ruta admin.tags.index a la que le paso un mensaje de éxito.
.........../**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/publicfunctionstore(Request$request){$request->validate(['name'=>'required','slug'=>'required|unique:tags','color'=>'required']);Tag::create($request->all());returnredirect()->route('admin.tags.index')->with('info','La etiqueta se creo con éxito.');}...................
Para que esto funcione debo de habilitar la asignación masiva en el modelo Tag.php.
<?phpnamespaceApp\Models;useIlluminate\Database\Eloquent\Factories\HasFactory;useIlluminate\Database\Eloquent\Model;classTagextendsModel{useHasFactory;protected$fillable=['name','slug','color'];//habilito la asignación masiva
publicfunctiongetRouteKeyName()//convierto las rutas en amigables
{return"slug";}// relacion muchos a muuchos con post
publicfunctionposts(){return$this->belongsToMany(Post::class);}}
Edición de una etiqueta
En la edición de etiquetas voy a necesitar el método edit del controlador TagController.php que me mostrará el formulario de edición de la vista resourdces/admin/tags/edit.blade.php en el voy a incluir el formulario resources/admin/tags/partials/form.blade.php.
/**
* Show the form for editing the specified resource.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctionedit(Tag$tag){// Array con los valores del select que le paso a la vista edit
$colors=['red'=>'Color rojo','yellow'=>'Color amarillo','blue'=>'Color azul','green'=>'Color verde','indigo'=>'Color índigo','pink'=>'Color rosa','purple'=>'Color morado'];returnview('admin.tags.edit',compact('tag','colors'));}
El formulario de la vista edit nos dirige a la ruta admin.tags.update a la que pasamos $tag a editar utilizando el método put.
@extends('adminlte::page')
@section('title', 'Blog con Laravel')
@section('content_header')
<h1>Editar una etiqueta</h1>@stop
@section('content')
<p>formulario edicion etiqueta.</p> @if (session('info'))
<divclass=" alert alert-success"><strong>{{session('info')}}</strong></div> @endif
<divclass="card"><divclass="card-body"> {!! Form::model($tag, ['route' => ['admin.tags.update', $tag], 'method' => 'put']) !!}
@include('admin.tags.partials.form')
{!! Form::submit('Editar etiqueta', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
</div></div>@stop
@section('css')
<linkrel="stylesheet"href="/css/admin_custom.css">@stop
// Codigo para autocompletar correctamente el campo slug con los datos del campo name.
@section('js')
<scriptsrc="{{asset('vendor/jQuery-Plugin-stringToSlug-1.3/jquery.stringToSlug.min.js')}}"></script><script>$(document).ready(function(){$("#name").stringToSlug({setEvents:'keyup keydown blur',getPut:'#slug',space:'-'});});</script>@endsection
Al hacer clic en el botón editar etiqueta los datos del formulario de la vista edit son enviados a la ruta admin.tags.update que es controlado por el método update del controlador TagController.php. En este método valido los datos recibidos en la variable $request y los actualizo en el registro almacenado en la variable $tag en la tabla tags de la base de datos. Conseguido esto, le pido que me redirija a la ruta admin.tags.edit a la que le paso un mensaje de éxito.
..................../**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param App\Models\Tag$tag
* @return \Illuminate\Http\Response
*/publicfunctionupdate(Request$request,Tag$tag){$request->validate(['name'=>'required','slug'=>"required|unique:tags,slug,$tag->id",//ignora el slug de la etiqueta $tag que quiero actualizar
'color'=>'required']);$tag->update($request->all());returnredirect()->route('admin.tags.edit',$tag)->with('info','La etiqueta se actualizó con éxito.');}...................
Eliminando una etiqueta
Si hago clic en el botón eliminar la información de la etiqueta se envía a la ruta admin.tags.destroyque es administrada por el método destroy del controlador TagController.php. En este método elimino el registro en la base de datos y que me redirecciona a la ruta admin.tags.index donde me muestra una alerta de borrado del registro.
Método destroy de TagController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
................/**
* Remove the specified resource from storage.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctiondestroy(Tag$tag){$tag->delete();returnredirect()->route('admin.tags.index')->with('info-del','La etiqueta se eliminó con éxito.');}}................
<?phpnamespaceApp\Http\Controllers\Admin;useApp\Http\Controllers\Controller;useApp\Models\Tag;useIlluminate\Http\Request;classTagControllerextendsController{/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/publicfunctionindex(){$tags=Tag::all();returnview('admin.tags.index',compact('tags'));}/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/publicfunctioncreate(){$colors=['red'=>'Color rojo','yellow'=>'Color amarillo','blue'=>'Color azul','green'=>'Color verde','indigo'=>'Color índigo','pink'=>'Color rosa','purple'=>'Color morado'];returnview('admin.tags.create',compact('colors'));}/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/publicfunctionstore(Request$request){$request->validate(['name'=>'required','slug'=>'required|unique:tags','color'=>'required']);Tag::create($request->all());returnredirect()->route('admin.tags.index')->with('info','La etiqueta se creo con éxito.');}/**
* Display the specified resource.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctionshow(Tag$tag){//
}/**
* Show the form for editing the specified resource.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctionedit(Tag$tag){$colors=['red'=>'Color rojo','yellow'=>'Color amarillo','blue'=>'Color azul','green'=>'Color verde','indigo'=>'Color índigo','pink'=>'Color rosa','purple'=>'Color morado'];returnview('admin.tags.edit',compact('tag','colors'));}/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param App\Models\Tag$tag
* @return \Illuminate\Http\Response
*/publicfunctionupdate(Request$request,Tag$tag){$request->validate(['name'=>'required','slug'=>"required|unique:tags,slug,$tag->id",//ignora el slug de la etiqueta $tag que quiero actualizar
'color'=>'required']);$tag->update($request->all());returnredirect()->route('admin.tags.edit',$tag)->with('info','La etiqueta se actualizó con éxito.');}/**
* Remove the specified resource from storage.
*
* @param App\Models\Tag $tag
* @return \Illuminate\Http\Response
*/publicfunctiondestroy(Tag$tag){$tag->delete();returnredirect()->route('admin.tags.index')->with('info-del','La etiqueta se eliminó con éxito.');}}