30 enero, 2020
Un sistema de Tags en Laravel más fácil
Para programar un sistema de tags primero definimos el modelo pivote luego de migrarlo debemos crear las consultas y las vistas necesarias. A programarlo

Suscríbete a nuestro canal en Youtube
SuscríbirseEn este tutorial vamos a ver la implementación de un sistema de etiquetas o tags para agregar o suprimirlas en un post usando el framework de desarrollo de aplicaciones web Laravel, sin agregar módulos o componentes adicionales, ni archivos que extiendan o ralentizen el proceso y carga de las vistas. Empecemos entonces.
Contenido
- Sistema de tags o etiquetas en Laravel 10
- Instalación y configuración de Laravel
- Base de datos, modelos, relaciones y migraciones
- Definir las rutas y controladores
- CRUD para Tags
- CRUD para Posts
- Mostrar los Posts
- Mostrar detalle del Post
- Mostrar Tag con Posts
¿Qué es un Tag?
Un tag o etiqueta se podría decir que es un sistema de clasificación de contenidos que ayuda a tener un orden dentro de un conjunto de publicaciones, ayuda a tener un acceso a la información mucho más eficiente, en un proyecto web de SEO realmente es una buena opción para hacer enlazado interno, pero debemos saber usarlo para evitar las urls duplicadas con canónicals.
¿Para qué sirve un sistema de tags?
Sirve para organizar el acceso a las diferentes secciones mediante un orden, es una forma de relaciones post de distintas temáticas pero que tienen algo en común, un nexo que los úne según el significado que tengan. Implementar este sistema es relativamente sencillo con Laravel sus sistema blade nos ayuda bastante, no obstante es imprescindible el uso de Javascript, en esta ocasión usaremos el viejo Jquery que aún sigue vigente de más a menos tambien usaremos una libreria llama Choosen la cual permite el diseño de la interactividad para agregar o suprimir tags en la vista de creación o edición del post de noticias. Ahora si entremos al desarrollo.
¿Cómo programar un sistema de tags eficientemente?
Para programar un sistema de tags en Laravel, debemos tener en claro lo que vamos a contruir y con ello veremos el diseño o arquitectura de urls, la clasificación de los contenidos, asi como las relaciones entre ellos.
No obstante, asumimos que tienes instalado Laravel la versión 5.8 esta bien, la configuración de la base de datos en .env y por su puesto ejecutado el comando auth para generar el sistema de autenticación ésta última no es necesario pero sería recomendable por el sistema de rutas que generaremos. Continuamos.
Instalación de Laravel
Base de datos, modelos y migraciones
Creación del modelo y migración para Posts
Crearemos dos modelos uno para Posts y otro que contendrá los Tags, entonces de una vez comencemos:
Ejecutamos el siguiente comando para obtener el modelo y la migración para Noticias en nuestra terminal
php artisan make:model Post-m
Implementamos el siguiente código en App/models/Post.php, donde adeás de los atributos para el modelo declaramos la relación con el modelo Tags.
App/models/Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = ['slug','nombre','descripcion'];
public function tags(){
return $this->belongsToMany(Tag::class);
}
}
Ahora veamos como debe quedar la migración para el modelo Post y Tag
Migracion post
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('slug',50)->unique();
$table->string('nombre',50)->unique();
$table->text('descripcion');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('posts');
}
};
Creación del modelo y migración para Tags
Ejecutamos en la terminal el siguiente comando para generar los archivos del modelo y la migración correspondiente
php artisan make:model Tag -m
Con ello obtenemos los templates, al cual le agregamos código y debería quedar de la siguiente manera
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['nombre','slug'];
public function posts(){
return $this->belongsToMany(Post::class);
}
}
En nuestra migración ocurre algo especial debemos declarar la tabla pivote llamada noticias_tags, veamos como debe quedar
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('slug',15)->unique();
$table->string('nombre',15)->unique();
});
Schema::create('posts_tags', function (Blueprint $table) {
$table->id();
$table->foreignId("post_id")->constrained();
$table->foreignId("tag_id")->constrained();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tags');
Schema::dropIfExists('posts_tags');
}
};
Ok, entonces ahora solo queda migrar los modelos para generar la tablas correspondientes además de crear la relaciones de integridad referencial. Ejecutemos el siguiente comando en la terminal:
php artisan migrate
En nuestra base de datos local, en Xampp o Wampp veremos las tablas creadas que nos interesan además de los otras que por defecto las generar Laravel.
Creando el sistema de rutas y controladores
Para ello en el archivo routes/web.app agregamos las siguientes lìneas de código PHP
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FrontController;
use App\Http\Controllers\Admin\TagController;
use App\Http\Controllers\Admin\PostController;
// rutas para admininistrar
Route::view('/', 'welcome');
Route::resource('admin/tag', TagController::class);
Route::resource('admin/post', PostController::class);
// rutas publicas para user
Route::get('/blog', [FrontController::class, 'index']);
Route::get('/blog/{post:slug}', [FrontController::class, 'post']);
Route::get('/tag/{tag:slug}', [FrontController::class, 'tag']);
// no login
Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
CRUD para Tags
Ejecutamos el comando artisan
php artisan make:controller Admin/TagController --resource
Este comando creará una carpeta con el nombre de Admin y dentro se generará un controlador con los métodos CRUD vacios, depende de nosotros programar la lógica usando consultas eloquent.
Veamos ¿Cómo debería quedar esto controlador?
namespace App\Http\Controllers\Admin;
use App\Models\Tag;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class TagController extends Controller
{
public function index(){
$tags = Tag::all();
return view('admin.tag.index', compact("tags"));
}
public function create(){
return view('admin.tag.create');
}
public function store(Request $request){
$tag = new Tag($request->all());
$tag->slug = Str::slug($request->nombre);
$tag->save();
return redirect('admin/tag');
}
public function edit($id){
$tag = Tag::find($id);
return view('admin.tag.edit',compact("tag"));
}
public function update(Request $request,$id){
$tag = Tag::findOrFail($id);
$tag->fill($request->all());
$tag->slug = Str::slug($request->nombre);
$tag->save();
return redirect('admin/tag');
}
public function destroy($id){
$tag = Tag::findOrFail($id);
$tag->delete();
return redirect('admin/tag');
}
}
Vista resources/views/admin/tag/index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-sm-2">
<ul>
<li><a href="/admin/post">Post</a></li>
<li><a href="/admin/tag">Tag</a></li>
</ul>
</div>
<div class="col-sm-10">
<div class="card">
<div class="card-body">
<a href="{{route('tag.create')}}" class="btn btn-primary">New Tag</a>
@if ($tags->count())
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Accion</th>
</tr>
</thead>
<tbody>
@foreach ($tags as $tag)
<tr>
<td>{{ $tag->id }}</td>
<td>{{ $tag->nombre }}</td>
<td>
<a class="btn btn-primary" href="{{ route('tag.edit',$tag->id) }}">Edit</a>
{!! Form::open(['method' => 'DELETE','route' => ['tag.destroy', $tag->id],'style'=>'display:inline']) !!}
{!! Form::submit('Del', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
</td>
</tr>
@endforeach
</tbody>
</table>
@else
<p class="text-center">Tags vacios!!</p>
@endif
</div>
</div>
</div>
</div>
</div>
@endsection
Vista resources/views/admin/tag/create.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-sm-2">
<ul>
<li><a href="/admin/post">Post</a></li>
<li><a href="/admin/tag">Tag</a></li>
</ul>
</div>
<div class="col-sm-10">
<div class="card">
<div class="card-body">
{!! Form::open(['route'=>'tag.store','method'=>'POST']) !!}
<div class="form-group row">
<div class="col-sm-6">
{!! Form::label('nombre','Nombre') !!}
{!! Form::text('nombre',null,['class'=>'form-control','required']) !!}
</div>
</div>
{{ Form::submit('Save',['class'=>'btn btn-primary']) }}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
Vista resources/views/admin/tag/edit.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-sm-2">
<ul>
<li><a href="/admin/post">Post</a></li>
<li><a href="/admin/tag">Tag</a></li>
</ul>
</div>
<div class="col-sm-10">
<div class="card">
<div class="card-body">
{!! Form::open(['route'=>['tag.update',$tag],'method'=>'PUT']) !!}
<div class="form-group row">
<div class="col-sm-6">
{!! Form::label('nombre','Nombre') !!}
{!! Form::text('nombre',$tag->nombre,['class'=>'form-control','required']) !!}
</div>
</div>
{{ Form::submit('Save',['class'=>'btn btn-primary']) }}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
CRUD para Posts
Ejecutamos el comando artisan
php artisan make:controller Admin/PostController --resource
Este comando creará una carpeta con el nombre de Admin y dentro se generará un controlador con los métodos CRUD vacios, depende de nosotros programar la lógica usando consultas eloquent.
namespace App\Http\Controllers\Admin;
use App\Models\Tag;
use App\Models\Post;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
public function index(){
$posts = Post::all();
return view('admin.post.index', compact("posts"));
}
public function create(){
$tags = Tag::pluck("nombre","id");
return view('admin.post.create', compact("tags"));
}
public function store(Request $request){
$post = new Post($request->all());
$post->slug = Str::slug($request->nombre);
$post->save();
$post->tags()->sync($request->tags);
return redirect('admin/post');
}
public function edit($id){
$post = Post::find($id);
$tags = Tag::pluck("nombre","id");
$taggeds = $post->tags->pluck("id")->toArray();
return view('admin.post.edit',compact("post","tags","taggeds"));
}
public function update(Request $request,$id){
$post = Post::findOrFail($id);
$post->fill($request->all());
$post->slug = Str::slug($request->nombre);
$post->save();
$post->tags()->sync($request->tags);
return redirect('admin/post');
}
public function destroy($id){
$post = Post::findOrFail($id);
$post->delete();
return redirect('admin/post');
}
}
....
Pronto publicaremos un video completo del sistema de tags Laravel
Leido 6098 veces | 0 usuarios
Descarga del código fuente Laravel de Un sistema de Tags en Laravel más fácil
Accede al código fuente esencial de nuestra aplicación en formato ZIP ó TXT. Ideal para desarrolladores que desean personalizar o integrar nuestra solución.
Opciones de descarga
- Usuarios Registrados: Inicia sesión para descarga inmediata.
- Nuevos Usuarios: Regístrate y descarga.