Widget WordPress: refactoring, parte 10
Per quanto riguarda il refactoring di WordPress Widget Boilerplate, siamo a buon punto. È stato fatto molto lavoro in modo tale che l’introduzione di nuove classi, funzionalità e funzionalità dovrebbe essere molto più semplice.
E non solo: dovrebbe essere più facile da seguire.
Grazie al lavoro nell’ultimo post, abbiamo molto lavoro su cui costruire, vale a dire un’interfaccia amministrativa di base.
Infine, l’ultimo post diceva:
Nei prossimi articoli, questo continuerà ad evolversi ma, come puoi vedere, ci stiamo assicurando di avere un’unica classe base di funzionalità per parlare con WordPress e una classe specifica per il rendering del modulo amministrativo.
Ed è qui che riprenderemo in questo articolo. In particolare, esamineremo la sanificazione e la serializzazione dei dati, nonché il recupero dei dati salvati nel widget.
The WordPress Widget Boilerplate: Refactoring Parte 10
Refactoring dell’interfaccia utente
Prima di entrare nella serializzazione, c’è del lavoro minore che dovremo fare per la nostra vista amministrativa. Ricordiamo dai post precedenti della serie che abbiamo creato un modulo che accetta:
- un titolo,
- alcuni contenuti,
- e una casella di controllo.
Questo viene visualizzato bene, ma esclude alcune funzionalità chiave dell’API dei widget. Vale a dire, dobbiamo assicurarci di denominare correttamente i nostri elementi utilizzando le seguenti funzioni:
E poi scriveremo la nostra funzione chiamata semplicemente get che spiegherò momentaneamente.
Le funzioni di cui sopra sono necessarie perché aiutano WordPress a tenere traccia di quante istanze del widget vengono utilizzate e quale l’utente sta modificando. In altre parole, otteniamo molte funzionalità gratuitamente.
Prima di mostrarti il codice, voglio discutere brevemente lo scopo della funzione get che stiamo per introdurre. In breve, è un modo per passare una chiave (come nella chiave in una coppia chiave/valore) in una funzione e quindi far sì che recuperi facilmente un valore per noi in modo che mantenga la nostra interfaccia il più pulita possibile.
Quindi, per prima cosa, il metodo get :
<?php
/**
* If the value for the key exists in the current instance of the widget, then it will
* retrieve it. Otherwise, it will return an empty value.
*
* @param string $key the used to identify the value of the widget.
* @param array $instance the options for the instance of this widget
*/
protected function get($key, $instance)
{
return empty($instance[$key])? '': $instance[$key];
}
La cosa importante da notare è che questo metodo accetta non solo la chiave per il valore che stiamo leggendo, ma un array che fa riferimento all’istanza dell’array.
E ora, l’interfaccia utente modificata :
<?php
/*
* This file is part of WordPress Widget Boilerplate
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
?>
<div class="widget-content">
<p>
<input
type="text"
id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>"
value="<?php echo $this->get('title', $instance) ?>"
placeholder="Widget Title"
class="widefat"
/>
</p>
<p>
<textarea
id="<?php echo esc_attr($this->get_field_id('content')); ?>"
name="<?php echo esc_attr($this->get_field_name('content')); ?>"
placeholder="Widget Content"
style="width:100%;"><?php echo $this->get('content', $instance) ?></textarea>
</p>
<p>
<input
type="checkbox"
value="on"
name="<?php echo esc_attr($this->get_field_name('display-title')); ?>"
id="<?php echo esc_attr($this->get_field_id('display-title')); ?>"
<?php checked('on', $this->get('display-title', $instance), true); ?>
class="checkbox"
/>
<label for="<?php echo esc_attr($this->get_field_id('display-title')); ?>">Display Title?</label>
</p>
</div><!-- .widget-content -->
Ma questo lascia ancora la funzionalità carente e lascia il lavoro da fare per noi. Vale a dire, dobbiamo disinfettare i dati e ritrasmetterli a WordPress, in modo che salvi i dati.
Sanificazione e serializzazione
Ai fini del nostro esempio, saremo molto severi in ciò che permettiamo. Vale a dire, supporteremo solo il testo di base e elimineremo tutto in modo aggressivo.
Ciò significa che non consentiremo markup o cose del genere. Invece, rimuoveremo tutto ciò che non è testo di base. Possiamo decorarlo un po’ quando arriva il momento di mostrarlo sul front-end, ma lo lasceremo fino al post appropriato.
Per fare ciò, utilizzeremo le seguenti funzioni:
Ricordiamo che abbiamo due campi nel nostro widget: il campo del titolo e il campo del contenuto. A seconda del tipo di widget che stai creando, potresti aver bisogno di una sola classe o funzione per disinfettare i dati. In altre situazioni, potresti aver bisogno di qualcosa di più complesso.
Tienilo a mente mentre esaminiamo questo codice poiché questa non sarà una soluzione valida per tutti. Invece, sarà specifico per questo.
Ad ogni modo, per sanificare i dati, scriveremo una classe specifica per questo scopo, e poi la metteremo a disposizione della nostra classe WidgetAdmin.
Ecco la classe nella sua interezza con una descrizione da seguire:
<?php
/*
* This file is part of WordPress Widget Boilerplate
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
namespace WordPressWidgetBoilerplateWordPress;
/**
* Santiizes and saves the data for the widget.
*/
class WidgetSerializer
{
/**
* Updates the values of the widget. Sanitizes the information before saving it.
*
* @param array $newInstance the array of new options to save
*/
public function update($newInstance)
{
$instance = [];
foreach ($newInstance as $key => $value) {
$instance[$key] = strip_tags(
stripslashes($value)
);
}
return $instance;
}
}
La classe dovrebbe essere diretta. Accetta i valori in entrata del widget, li disinfetta e quindi restituisce un nuovo array da restituire a WordPress.
C’è un problema però. Questa classe deve essere una proprietà della classe Widget principale mostrata nell’ultimo post.
In secondo luogo, il metodo di aggiornamento che fa parte dell’API Widgets è ciò che chiamerà in questa classe. Non è necessario passare la variabile $oldInstance nel serializzatore ma è necessaria per il metodo di aggiornamento.
Ecco la classe Widget come è attualmente costruita :
<?php
/*
* This file is part of WordPress Widget Boilerplate
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
namespace WordPressWidgetBoilerplateWordPress;
use WP_Widget;
class Widget extends WP_Widget
{
/**
* @var string unique identifier for your widget
*/
protected $widgetSlug;
/**
* Initializes the plugin by setting its properties and calling the parent class with the description.
*
* @param string $widgetSlug unique identifier for your widget
* @param WidgetSerializer $widgetSerializer the class responsible for saving widget options
*/
public function __construct($widgetSlug)
{
$this->widgetSlug = $widgetSlug;
parent::__construct(
$this->getWidgetSlug(),
__('Widget Name', $this->getWidgetSlug()),
[
'classname' => $this->getWidgetSlug().'-class',
'description' => __('Short description of the widget goes here.', $this->getWidgetSlug()),
]
);
}
/**
* Return the widget slug.
*
* @return string slug variable
*/
public function getWidgetSlug()
{
return $this->widgetSlug;
}
/**
* Displays the administrative view of the form and includes the options
* for the instance of the widget as arguments passed into the function.
*
* @param array $instance the options for the instance of this widget
*/
public function form($instance)
{
include plugin_dir_path(__FILE__).'Views/Admin.php';
}
/**
* Updates the values of the widget. Uses the serialization class to sanitize the
* information before saving it.
*
* @param array $newInstance the values to be sanitized and saved
* @param array $oldInstance the values that were originally saved
*/
public function update($newInstance, $oldInstance)
{
return $this->widgetSerializer->update($newInstance, $oldInstance);
}
/**
* If the value for the key exists in the current instance of the widget, then it will
* retrieve it. Otherwise, it will return an empty value.
*
* @param string $key the used to identify the value of the widget
* @param array $instance the options for the instance of this widget
*/
protected function get($key, $instance)
{
return empty($instance[$key])? '': $instance[$key];
}
}
Ma se aggiorni la pagina, potresti notare che la sanificazione e la serializzazione non sembrano funzionare durante il recupero dei dati. Ed è quello che esamineremo nel prossimo post.
Recupero dati
Si noti che sebbene la funzionalità sembri incompleta per questo (poiché i dati non sterilizzati sono ancora visualizzati), ci concentriamo sull’assicurarci di scrivere classi con coesione, responsabilità e che non siano strettamente accoppiate.
Ci accingiamo ad iterare un po’ di più su questo nel prossimo post. Quindi studia il codice sopra, implementalo se è quello che hai fatto, e partiremo da lì nel prossimo post.