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 pueda ser leído y entendido por una persona. Desde hace algunos años los buscadores han tomado este factor como un determinante fundamental en el posicionamiento de resultados en búsquedas web, 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.

En Laravel es muy fácil hacer rutas amigables y existen muchas formas de hacerlo, hoy les explicaré un modo fácil y sencillo de lograr este resultado con un pequeño ejemplo.

Como siempre, antes de empezar debemos tener configurada la conexión a la base de datos desde el archivo .env. Luego crearemos un nuevo modelo llamado Post.

Creación del modelo y la migración de Post

$ php artisan make:model Post

Agregamos los siguientes campos en el archivo de la migración del post

public function up()
{
    Schema::create('posts', function(Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('body');
        $table->string('slug')->unique();
        $table->timestamps();
    });
}

Nota: para aprender un poco más sobre bases de datos y migraciones visita el post sobre Creando Migraciones en Laravel 5

El campo slug debe ser único ya que al ingresar una URL para el post la aplicación debe devolver un solo resultado.

Ahora vamos a agregar unos registros de prueba en la base de datos usando el componente Faker. Si no sabes como integrar o usar este componente visita Seeders y el componente Faker en Laravel 5.

Creación del seeder de Post

Creamos un archivo llamado PostTableSeeder que quedaría de esta forma:

<?php

use Illuminate\Database\Seeder;
use Faker\Factory as Faker;
use Illuminate\Support\Str as Str;

class PostTableSeeder extends Seeder {

    public function run()
    {
        $faker = Faker::create();
        for($i = 0; $i<20; $i++){
            $title = $faker->sentence;
            $body = $faker->text(3000);
            $slug = Str::slug($title);
            \DB::table('posts')->insert(array(
                'title' => $title,
                'body'  => $body,
                'slug'  => $slug
            ));
        }
    }
}

Como puedes ver, hacemos uso del método Str::slug(), esta clase permite trabajar con cadenas de texto y específicamente el método slug convierte un texto dado en una cadena en minúsculas, sin acentos y separado por guiones.

Si como yo, creaste el último archivo sin usar la consola no olvides ejecutar desde la consola:

$ composer dump-autoload

Para que se cargue la nueva clase en tu app.

Para finalizar con el tema de la base de datos sólo basta con ejecutar la migración y hacer seed de los datos de prueba.

Recuerda que debes agregar la nueva clase al método run() del archivo DatabaseSeeder.php 

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder {

    public function run()
    {
        Model::unguard();
        $this->call('PostTableSeeder');
    }

}

Y luego ejecutas desde la consola:

$ php artisan migrate --seed

Perfecto, ahora necesitamos dos métodos, uno para ver la lista de los posts y otro para ver el detalle de cada post, para ello podemos crear un nuevo controlador llamado PostController desde la consola con:

$ php artisan make:controller PostController

Y agregamos las siguientes funciones:

<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;
use App\Post as Post;

class PostController extends Controller {

    public function index()
    {
        $posts = Post::all();
        return \View::make('list', compact('posts'));
    }

    public function show($slug)
    {
        $post = Post::where('slug','=', $slug)->firstOrFail();
        return \View::make('post', compact('post'));
    }
}

Recuerda incluir el modelo Post en la cabecera del archivo. Para el método show() vamos a recibir en lugar del id un slug como parámetro, así procedemos a realizar la búsqueda del post usando Eloquent, para mas información sobre las búsquedas puedes leer el tutorial sobre Aprende a usar Eloquent el ORM de Laravel.

A continuación vamos a definir las rutas:

Para probar el slug, necesitamos dos rutas y luego definir dos vistas.

Primero definimos la ruta para el detalle del post, esta será la que apunte al controlador que hace la búsqueda por el slug dado y devuelve la información de cada publicación.

Route::get('post/{slug}', ['as' => 'post', 'uses' => 'PostController@show']);

Posteriormente definiremos una ruta para la lista de posts:

Route::get('posts', 'PostController@index');

Por último, vamos a crear las vistas:

Vamos a crear la vista que se encargará de mostrar la lista de los posts. Crearemos un archivo llamado list.blade.php:

@extends('app')

@section('content')
<div class="container">
    <div class="row">
         <div class="col-md-10 col-md-offset-1">
	     <table class="table table-striped">
                 <thead>
                     <tr>
                         <th>Title</th>
                         <th>Slug</th>
                     </tr>
                 </thead>
                 <tbody>
                     @foreach($posts as $post)
                        <tr>
                            <td><a href="{{ route('post', [$post->slug]) }}"> {{ $post->title }}</a></td>
                            <td>{{ $post->slug }}</td>
                        </tr>
                     @endforeach
                 </tbody>
             </table>
         </div>
     </div>
</div>
@endsection

Esta vista extiende de app.blade.php (viene definida por defecto en cada proyecto de Laravel) y  solo mostramos el título y el slug de cada post, el título enlaza al detalle de la publicación , esta URL llamada «post» recibe como parámetro un slug.

Si ingresas desde el navegador a url_de_tu_proyecto/public/posts verás algo como esto

posts

Hasta ahora todo perfecto, puedes ver que tienes un listado de publicaciones de prueba gracias al uso de Faker y cada una de ellas tiene un slug que formará parte de la url amigable de cada post.

Vamos a crear la vista del post en un archivo llamado post.blade.php

@extends('app')

@section('content')
<div class="container">
	<div class="row">
		<div class="col-md-10 col-md-offset-1">
		    <h1>{{ $post->title }}</h1>
                    <p>{{ $post->body }} </p>
		</div>
	</div>
</div>
@endsection

Como mencionaba anteriormente, se recibe el slug como parámetro, de esta forma en la función show($slug) podemos usarlo para la búsqueda del post, al final veremos en el navegador algo como esto

post-slug

Ahora tus publicaciones tendrán una url más agradable. Si te gustó el tutorial recuerda dejar tus comentarios y compartirlo en tus redes sociales.

Lecturas recomendadas 

 

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Uso de los View Composer en Laravel 5 Lección siguiente Videotutorial: actualiza tus proyectos de Laravel 5.0 a 5.1