✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

Виджеты WordPress: рефакторинг, часть 10

18

Что касается рефакторинга 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, показанного в последнем посте.

Во-вторых,  метод обновления, являющийся частью 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];
    }
}

Но если вы обновите страницу, вы можете заметить, что очистка и сериализация не работают при извлечении данных. И это то, что мы собираемся изучить в следующем посте.

Получение данных

Обратите внимание, что хотя функциональность для этого кажется неполной (поскольку непроверенные данные все еще отображаются), мы сосредоточены на том, чтобы убедиться, что мы пишем классы слаженно, ответственно и не тесно связаны.

Мы собираемся повторить это немного больше в следующем посте. Итак, изучите приведенный выше код, внедрите его, если это то, что вы делали, и мы начнем с него в следующем посте.

Источник записи: tommcfarlin.com

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принимаю Подробнее