Inicio » Blog » Laravel

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íbirse

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

Sistema de Tags Laravel

¿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 5263 veces

Descarga el código fuente Laravel

Recurso descargado 0 veces

USD

Descargar Código Fuente

Compartir link del tutorial con tus amigos


Laravel 9 Página Web para Negocio Laravel 9 Página Web para Negocio

Curso Laravel 9 Avanzado Desarrollo Web Administrable para negocio

Descarga del código fuente

USD 10.00

Aprende más sobre Laravel

Cursos de programación

Codea Codea App

México, Colombia, España, Venezuela, Argentina, Bolivia, Perú

© Todos los derechos reservados Codea App | ...de frente al código!!! | 2020 - 2023