Crea i tuoi Slug con Eloquent Sluggable

0
362

Questa è una traduzione della pagina relativa al package Eloquent-sluggable.

Prima di presentare questo package, chiariamo alcuni concetti. Cos’è uno slug? È una versione URL-friendly di una stringa. Lo _slugging _è quella operazione che “sanifica” un URL da caratteri particolari come spazi, lettere accentate, apostrofi, ecc. Il risultato finale è una stringa più leggibile.

Vediamo un piccolo esempio:

In un’ottica SEO non è proprio un URL friendly, non è vero? Sarebbe più corretto avere come parte dell’URL il titolo del post. Tuttavia se il post avesse come titolo “My Dinner With André & François”, l’URL risulterebbe:

http://example.com/post/My+Dinner+With+Andr%C3%A9+%26+Fran%C3%A7ois

Probabilmente ancora meno SEO-friendly 🙁

La soluzione è creare uno slug per questo titolo e utilizzarlo quindi come link per accedere al post. A dirla tutta, Laravel ha già un suo metodo: si tratta di Str::slug() e dà come risultato proprio quello di cui abbiamo bisogno:

http://example.com/post/my-dinner-with-andre-francois

Beh, allora? Che senso ha un altro package che fa la stessa cosa? Per rispondere a questa domanda, poniamo il caso che si debba scrivere un post con lo stesso titolo, ma con contenuto diverso. Con il metodo built-in di Laravel avremmo esattamente lo stesso URL. La soluzione, quindi, non sarebbe univoca. Eloquent-Sluggable fa proprio questo: automatizza tutte le procedure per rendere lo slug univoco anche se il titolo del post è identico al precedente.

Vediamo un altro esempio che rende l’idea:

http://example.com/post/my-dinner-with-andre-francois
http://example.com/post/my-dinner-with-andre-francois-1
http://example.com/post/my-dinner-with-andre-francois-2

Installazione e requisiti

Se il package ti ha convinto, vediamo come installarlo. Prima di tutto aggiungilo al file composer.json:

{
“require”: {
“cviebrock/eloquent-sluggable”: “2.*”
},
}

Nota: Eloquent-Sluggable usa i _traits, _dunque la versione PHP adatta per questo package è la 5.4 +. Tuttavia se sei “costretto” ad usare la versione PHP 5.3., utilizza la versione 1.* di questo package e segui le istruzioni nel file README.md.

Dopo aver lanciato _composer update, _aggiorna il file _app/config/app.php _e aggiungi questo nuovo service provider:

‘providers’ => array(

// …

‘CviebrockEloquentSluggableSluggableServiceProvider’,

);

Ok, ci siamo quasi: dalla riga di comando lancia _php artisan config:publish cviebrock/eloquent-sluggable _per creare il file default di configurazione.

Aggiornare tutti gli Eloquent Model

Per usare Eloquent-Sluggable devi implementare l’interfaccia Sluggable nei tuoi model e usare quindi i suoi traits. Prima definisci un array protetto $sluggable in questo modo:

Chiaramente, la tabella corrispondente al model avrà bisogno di una colonna dove salvare lo slug. Puoi farlo manualmente o creare una migrazione da riga di comando attraverso artisan in questo modo:

use CviebrockEloquentSluggableSluggableInterface;
use CviebrockEloquentSluggableSluggableTrait;

class Post extends Eloquent implements SluggableInterface
{

use SluggableTrait;

protected $sluggable = array(
‘build_from’ => ‘title’,
‘save_to’ => ‘slug’,
);

}

Questo comando aggiunge una colonna chiamata slug alla tabella posts. Se vuoi dare un nome diverso, aggiungi un altro parametro al comando. Così:

php artisan sluggable:table posts

Il tuo model, ora, è sluggable!

Utilizzare la Classe

Una volta salvato un post:

$post = new Post(array(
‘title’ => ‘My Awesome Blog Post’
));

$post->save();

recuperare lo slug è piuttosto semplice:

echo $post->slug;

// oppure
echo $post->getSlug();

Una nota interessante è il supporto di Ardent: se ti interessa dai un’occhiata la file README-Ardent.md

Ti faccio notare che se desideri replicare i tuoi model con il metodo Eloquent replicate(), assicurati di “informare” il package che c’è bisogno di un re-slugging. Ecco come:

$new_post = $post->replicate()->resluggify();

Configurazione

Il sistema di configurazione è stato sviluppato per essere molto flessibile.

Si parte da assegnazioni di default per i tuoi model, ma si può gestire il setting per ogni singolo model.

Di default, la configurazione globale può essere impostata nel file _app/config/packages/cviebrock/eloquent-sluggable/config.php. _Se una configurazione singola non è impostata, il package prenderà come riferimento le impostazioni di default presenti nel file _vendor/cviebrock/(eloquent-sluggable/src/config/config.php. _Ecco tutti i parametri di default:

return array(
‘build_from’ => null,
‘save_to’ => ‘slug’,
‘max_length’ => null,
‘method’ => null,
‘separator’ => ‘-‘,
‘unique’ => true,
‘include_trashed’ => false,
‘on_update’ => false,
‘reserved’ => null,
‘use_cache’ => false,
);

build_from

Questo è un campo o un array di campi dal quale costruire lo slug. Ogni _$model->field è concatenato (con uno spazio separatore) per costruire la stringa sluggable. La stringa può nascere da campi di un db o da qualsiasi altra cosa:

class Person extends Eloquent implements SluggableInterface {

use SluggableTrait;

public static $sluggable = array(
‘build_from’ => ‘fullname’
);

public function getFullnameAttribute() {
return $this->firstname . ‘ ‘ . $this->lastname;
}

}

se _build_from _è vuoto, false o nullo, sarà usato il valore di _$model->__toString()_.

save_to

È il campo del tuo db dove sarà salvato lo slug. Di default, è “slug”. Ma puoi dargli il nome che preferisci:

Schema::create(‘posts’, function($table)
{
$table->increments(‘id’);
$table->string(‘title’);
$table->string(‘body’);
$table->string(‘slug’);
$table->timestamps();
});

max_length

Se assegni un valore positivo intero a questo indice di array, il tuo slug avrà una lunghezza prefissata. Di default, questo valore è nullo e non ha limiti.

N.b. I numeri alla fine della stringa “-1”, “-2”, “-3” non sono inclusi nel conteggio di max_length.

method

Definisce il metodo usato per trasformare la stringa sluggable in un vero e proprio slug.

Tre sono le possibili opzioni:

  1. Quando il metodo è nullo, il package userà il metodo di Laravel _Str::slug() _
  2. Si può richiamare un metodo di una classe. Due i parametri: la stringa da processare e una stringa di separazione. Per esempio: per duplicare il comportamento di default puoi fare così:

‘method’ => array(‘Illuminate\Support\Str’, ‘slug’),

  1. Puoi anche definire il metodo come closure. In questo modo:

‘method’ => function( $string, $separator ) {
return strtolower( preg_replace(‘/[^a-z]+/i’, $separator, $string) );
},

separator

Definisce il separatore usato per costruire lo slug. Il valore di default è il trattino (-).

unique

E’ un valore booleano, utile per indicare se lo slug debba essere univoco tra i model. Per esempio, se hai due blog ognuno dei quali ha un post come titolo “My Blog Post”, avranno entrambi lo slug “my-blog-post” . E questo potrebbe essere un problema. Ma se valorizzi l’indice con on, il secondo model Post restituirà come slug “my-blog-post-1”. Se ci fosse un terzo post con lo stesso titolo, avrà “my-blog-post-2”, e così via.

include_trashed

Questo indice funziona solo se utilizzi il SoftDelete di Laravel. Se imposti questo indice a true il package si preoccuperà di controllare anche tra i record soft deleted. Di default è impostato su false.

on_update

Anche questo è un valore booleano. Se impostato a false (valore di default), gli slug non saranno aggiornati in caso di update del model (ad esempio, se dovessi cambiare il titolo del post, lo slug non cambierebbe).

reserved

Un sorta di black list per la creazione di slug. I motivi possono essere tantissimi: evitare collisioni nella route, nei metodi del controller, ecc. Può essere un array, o una closure che restituisce un array. Di default il valore è null.

use_cache

Quando controlla i valori univoci, il package interroga il db: questo significa che c’è un importante utilizzo del db. Attivando use_cache l’ultimo incremento generato sarà gestito dalla cache e saranno evitate query future. Il valore di default è false: il package non usa la cache. Se stai già usando un sistema di caching che supporta Cache::tags(), è preferibile attivare anche use_cache. E’ sufficiente, quindi, cambiare il valore false in un numero intero positivo che rappresenta i minuti del ciclo di vita della cache per il package (non per l’app di Laravel, naturalmente).

Estendere Sluggable

A volte le opzioni di configurazione non sono sufficienti quando l’applicazione è complessa. La buona notizia è che questo package si può estendere sovrascrivendo i metodi. Dai un’occhiata a _SluggableTrait->sluggify() _per vedere quale sia l’ordine delle operazioni. Puoi anche considerare l’opzione di effettuare un overloading dei seguenti metodi protetti:

needsSlugging()

Verifica se il modello ha bisogno di essere slugged. Restituisce true o false.

getSlugSource()

Restituisce una stringa utile per creare il sorgente dello slug.

generateSlug($source)

Il codice che genera lo slug. _Di solito implementa tutto ciò che è definito nel _method, ma potrebbe far riferimento ad altre librerie esterne. Prende la stringa originaria e la restituisce.

validateSlug($slug)

Valida lo slug e controlla anche se ci sia qualche riferimento nella variabile reserved: la black list di cui abbiamo parlato prima. Restituisce uno slug valido.

makeSlugUnique($slug)

Controlla l’univocità dello slug. Restituisce uno slug univoco.

getExistingSlugs($slug)

Restituisce tutti gli slug simili a quello dato. Dovrebbe restituire un’accoppiata chiave-valore di slug esistenti, dove il valore è rappresentato dallo slug e la chiave dall’id.

setSlug($slug)

Scrive lo slug (generato, valido, e univoco) per gli attributi del model.