Віджети WordPress: рефакторинг, частина 10
Що стосується рефакторингу WordPress Widget Boilerplate, то ми в хорошому місці. Було зроблено багато роботи, щоб запроваджувати нові класи, функції та функції було набагато легше.
І не тільки це: це має бути легше слідувати.
Завдяки роботі в останньому дописі, у нас є багато роботи, над якою можна попрацювати, а саме базовий адміністративний інтерфейс.
Нарешті, останній пост сказав:
У наступних кількох статтях це продовжуватиме розвиватися, але, як ви бачите, ми гарантуємо, що у нас є єдиний базовий клас функціональності для спілкування з WordPress і клас спеціально для відтворення адміністративної форми.
І ось чому ми збираємося зупинитися в цій статті. Зокрема, ми розглянемо дезінфекцію та серіалізацію даних, а також отримання даних, збережених у віджеті.
Шаблон віджета WordPress: рефакторинг, частина 10
Рефакторинг інтерфейсу користувача
Перш ніж ми приступимо до серіалізації, нам потрібно буде виконати невелику роботу з нашим адміністративним представленням. Згадайте з попередніх дописів серії, що ми створили форму, яка приймає:
- назва,
- деякий вміст,
- і прапорець.
Це добре відображається, але виключає деякі ключові функції Widgets API. Зокрема, нам потрібно переконатися, що ми правильно називаємо наші елементи за допомогою таких функцій:
А потім ми напишемо нашу функцію під простою назвою get, яку я зараз поясню.
Наведені вище функції необхідні, оскільки вони допомагають WordPress відстежувати, скільки екземплярів віджета використовується та який з них редагує користувач. Іншими словами, ми отримуємо багато функцій безкоштовно.
Перш ніж показати вам код, я хочу коротко обговорити призначення функції get, яку ми збираємося представити. Коротше кажучи, це спосіб для нас передати ключ (як у ключі в парі ключ/значення) у функцію, а потім дозволити їй легко отримати значення для нас, щоб наш інтерфейс був максимально чистим.
Отже, спочатку метод 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];
}
Важливо зауважити, що цей метод приймає не лише ключ для значення, яке ми читаємо, але й масив, який посилається на екземпляр масиву.
А тепер оновлений інтерфейс користувача :
<?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 -->
Але це все одно залишає функціональність нестачею, і це залишає роботу для нас. А саме, нам потрібно очистити дані та передати їх назад у WordPress, щоб він зберіг дані.
Дезінфекція та серіалізація
Для цілей нашого прикладу ми будемо дуже суворими щодо дозволеного. Зокрема, ми збираємося підтримувати лише базовий текст, і ми збираємося різко вилучити все.
Це означає, що ми не дозволимо розмітку чи щось подібне. Натомість ми видалимо все, що не є основним текстом. Ми можемо трохи прикрасити його, коли прийде час відображати його на інтерфейсі, але ми залишимо це до відповідної публікації.
Для цього ми будемо використовувати такі функції:
Пам’ятайте, що у нашому віджеті є два поля – поле заголовка та поле вмісту. Залежно від типу віджета, який ви створюєте, вам може знадобитися лише один клас або функція для очищення даних. В інших ситуаціях вам може знадобитися щось складніше.
Майте це на увазі, коли ми проходимо цей код, оскільки це не буде універсальним рішенням. Натомість це буде спеціально для цього.
У будь-якому разі, щоб очистити дані, ми напишемо клас спеціально для цієї мети, а потім зробимо його доступним для нашого класу WidgetAdmin.
Ось весь клас із наступним описом:
<?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;
}
}
Клас має бути прямолінійним. Він приймає вхідні значення віджета, дезінфікує їх, а потім повертає новий масив для повернення до WordPress.
Але тут є заковика. Цей клас має бути властивістю основного класу Widget, який було показано в останньому дописі.
По-друге, метод оновлення, який є частиною Widgets API, є тим, що викликає цей клас. Немає необхідності передавати змінну $oldInstance у серіалізатор, але це потрібно для методу оновлення.
Ось клас Widget , як він побудований на даний момент :
<?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];
}
}
Але якщо ви оновите сторінку, ви можете помітити, що очищення та серіалізація не працюють під час отримання даних. І саме це ми розглянемо в наступній публікації.
Отримання даних
Зауважте, що, незважаючи на те, що функціональні можливості для цього здаються неповними (оскільки неочищені дані все ще відображаються), ми зосереджені на тому, щоб упевнитися, що ми пишемо класи з згуртованістю, відповідальністю та без тісного зв’язку.
Ми збираємося повторити це трохи більше в наступній публікації. Тож вивчіть наведений вище код, запровадьте його, якщо це те, що ви робили, і ми підемо звідти в наступній публікації.