Creiamo il blog – parte 3

In questa 3° parte andremo ad associare dei Behaviors standard di Yii al nostro blog. In particolare sfrutteremo i campi created_by, updated_by, created_at, updated_at e slug che abbiamo definito nella tabella post.

Il campo slug, ovvero SluggableBehavior

Yii ci permette di generare in automatico lo slug del nostro post tramite un comportamente predefinito. Siccome abbiamo già inserito la colonna slug nella nostra tabella possiamo implementare direttamente il codice. Apriamo il file backend/models/Post.php ed inseriamo nel nostro codice la seguente funzione

/**
 * Definisco i behavior che vengono utilizzati nel modello
 * @return type
 */
public function behaviors(){
  return [
    [
      'class' => SluggableBehavior::className(),
      'attribute' => 'title',
      'immutable' => true,
      'ensureUnique'=> true,
    ],
  ];
}

senza dimenticarci di richiamare il behavior tramite

use yii\behaviors\SluggableBehavior;

all’inzio del file.

Basta! Se procediamo a salvare un nuovo post Yii valorizzerà in automatico il campo slug partendo dal nostro titolo.
Il campo immutable impedisce la modifica dello slug nei successivi update, anche in caso di modifica del titolo (utile per motivi di indicizzazione).
Il campo ensureUnique ci assicura invece che altri articoli con lo stesso titolo avranno slug differenti (-2, -3, …) per avere unicità in fase di apertura.

Già, l’apertura… Lo slug è salvato e gestito correttamente, ma se dalla tabella di riepilogo andiamo in visualizzazione di un post rimane l’id numerico! Andiamo quindi nel file backend/views/post/index.php e modifichiamo la riga

['class' => 'yii\grid\ActionColumn'],

in

[
  'class' => 'yii\grid\ActionColumn',
  'template'=> '{view} {update} {delete}',
  'buttons'=> [
    'view' => function ($url, $model) {
      return Html::a('<span class="glyphicon glyphicon-eye-open</span>', 'post/'.$model->slug, ['title' => Yii::t('yii', 'View'),]);
    }
  ],
],

ridefinendo cosi il solo pulsante per la visualizzazione dell’articolo.

Bene, ma ancora non ci siamo… Se cliccate sulla visualizzazione apparirà infatti un bel 404 not found!

Dobbiamo infatti dire a Yii di usare lo slug per decidere quale contenuto mostrare, e questo lo facciamo in due fasi…

Come prima cosa, nel file backend/config/main.php andiamo a modificare la definizione dell’urlManager nel seguente modo

'urlManager' => [
  'enablePrettyUrl' => true,
  'showScriptName' => false,
  'rules' => [
    'post' => 'post/index',
    'post/index' => 'post/index',
    'post/create' => 'post/create',
    'post/view/<id:\d+>' => 'post/view',
    'post/update/<id:\d+>' => 'post/update',
    'post/delete/<id:\d+>' => 'post/delete',
    'post/<slug>' => 'post/slug',
    'defaultRoute' => '/site/index',
  ],
] 

in questo modo specifichiamo tutte le possibili regole degli url da gestire per i post. Ho dovuto specificare anche post/index e post/create per evitare che la parola index e la parola create fossere confuse come <slug>.

Infine, nel nostro file backend/controllers/PostController.php andiamo a definire la nuova azione Slug come segue

/**
 * Displays a single Status model.
 * @param string $slug
 * @return mixed
 */
public function actionSlug($slug){
  $model = Post::find()->where(['slug'=>$slug])->one();
  if (!is_null($model)) {
    return $this->render('view', ['model' => $model,]);
  } else {
    return $this->redirect('/post/index');
  }
}

l’azione è molto simile a quella di View, ma va a fare una ricerca sul campo slug.

Bene, adesso cliccando sulla visualizzazione del post dalla tabella di riepilogo tutto si apre correttamente!

 

I campi created_by e updated_by, ovvero BlameableBehavior

Il BlameableBehavior ci permette di gestire in automatico campi come created_by e updated_by, cioè di assegnare in automatico l’autore di un contenuto.

Apriamo il file del modello backend/models/Post.php ed aggiungiamo anche questo secondo behavior

public function behaviors(){
  return [
    [
      'class' => SluggableBehavior::className(),
      'attribute' => 'title',
      'immutable' => true,
      'ensureUnique'=> true,
    ],
    [
      'class' => BlameableBehavior::className(),
      'createdByAttribute' => 'created_by',
      'updatedByAttribute' => 'updater_id',
    ],
  ];
}[/php</pre>
&nbsp;

Ricordiamoci di chiamare il behavior con

use yii\behaviors\BlameableBehavior;

ed assicuriamoci che nella funzione che definisce le rules del modello vengano tolti i riferimenti a created_by e updated_by in quanto saranno gestiti in automatico e non vogliamo la validazione nel form.

Basta! Non tocchiamo altro, perchè Yii in automatico prenderà l’id dell’utente corrente ed andrà a valorizzare i campi come deve.

 

I campi created_at e updated_at, ovvero TimestampBehavior

L’ultimo behavior della puntata è quello che permette di aggiornare in automatico data di inserimento e di modifica di un contenuto. Aggiungiamo al nostro modello l’inclusione del behavior con

use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;

e trasformiamo la nostra funzione di inclusione dei behaviors cosi

public function behaviors(){
  return [
    [
      'class'     => SluggableBehavior::className(),
      'attribute' => 'title',
      'immutable' => true,
      'ensureUnique'=>true,
    ],
    [
      'class' => BlameableBehavior::className(),
      'createdByAttribute' => 'created_by',
      'updatedByAttribute' => 'updater_id',
    ],
    'Timestamp' => [
      'class' => TimestampBehavior::className(),
      'attributes' => [
        ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
        ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
      ],
      'value' => new Expression('NOW()'),
    ],
  ];
}

Anche qui, assicuriamoci di rimuovere la regola di require nei nostri campi.

Fine, possiamo controllare che tutto vada!

 

Alla prossima puntata, dove andremo a customizzare la schermata di insert ed update!