miércoles, 5 de octubre de 2016

Sluggable: rutas amigables

Los slugs son formas “amigables” de representar el texto de un enlace de tal manera que no se muestren caracteres extraños o variables confusas y que sean entendidos por una persona.
El slug puede contener las palabras clave de un artículo y de esta forma indicarle al lector si la publicación está relacionada con el término de la búsqueda.
Laravel tiene una forma de hacer esto desde el propio framework. Pero yo lo voy a hacer desde un paquete, este me hace practico a todo nivel el uso de rutas amigables, sin tocar mas que el modelo.

El paquete en cuestion es spatie/laravel-sluggable

Para instalarlo, como casi todo paquete, debemos hacer:

     composer require spatie/laravel-sluggable

Bueno básicamente lo que debemos hacer es crear un nuevo atributo en el modelo de dato. llamado slug preferentemente. El cual albergara la ruta amigable. Una vez creado a través de migraciones o como sea. Vamos al modelo.


namespace App; use Spatie\Sluggable\HasSlug; use Spatie\Sluggable\SlugOptions; use Illuminate\Database\Eloquent\Model; class Articulo extends Model { use HasSlug; protected $table = "articulos"; protected $fillable = ['titulo','contenido','slug','visitas']; /** * Get the options for generating the slug. */ public function getSlugOptions() : SlugOptions { return SlugOptions::create() ->generateSlugsFrom('titulo') ->saveSlugsTo('slug'); } public static function findBySlugOrFail($slug, $columns = array('*') ) { if ( ! is_null($slug = static::whereSlug($slug)->first($columns))) { return $slug; } throw new ModelNotFoundException; } }

La primer funcion getSlugOptions() es la que genera el slug a partir del titulo y lo guarda en slug dentro de nuestra base de datos (atributo previamente creado en nuestra base)

La segunda funcion servira para buscar un articulo o el objeto que sea, a traves del slug. Funcion clave para el controlador cuando pasemos a la nueva vista seleccionada y pasemos el slug creado como parametro (que es lo que se mostrara en la url)

Entonces. Definiendo una ruta del estilo:

Route::get('/articulos/{slug}', 'FrontController@viewArticulo')
                    ->name('front.view.articulo');

Nos vamos al controlador y podemos manejarlo de la siguiente forma:

public function viewArticulo($slug){ $articulo= Articulo::findBySlugOrFail($slug); $articulo->categoria; $articulo->imagen; $articulo->autor; $articulo->visitas++; $articulo->save(); return view('front/articulo')->with('articulo',$articulo); }

En definitiva se vera asi:

    www.nombredelsitio.com/articulos/nombre-del-articulo

Espero que les sirva.
Un saludo

3 comentarios:

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  3. Hola, como se puede hacer para que al querer cambiar el titulo a un articulo no cambie el slug, es decir mantenga la ruta y no cambie a cada rato

    ResponderEliminar