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

Быстрое прототипирование: от прототипа к коду, часть 2

25

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

  1. обсудили и построили прототип плагина,
  2. схематично один объектно-ориентированный подход может работать,
  3. и преобразовали наш прототип в реальный код.

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

Итак, вот посмотрите, как это проявляется в нашем текущем проекте.

От прототипа к коду: пространства имен

Я подробно рассмотрел пространства имен в предыдущих постах. Если не читали, то рекомендую. Затем вернитесь и проверьте остальную часть поста.

Если вы решите пропустить статью, вот краткое определение пространства имен :

Пространства имен предназначены для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы или функции…

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

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

С учетом сказанного давайте организуем файлы.

Организация файлов

Вместо того, чтобы начинать с основного файла плагина, давайте сначала организуем наши файлы.

  • Файлы Meta Box и Meta Box Display будут находиться в каталоге Display. Это совершенно произвольно, но поскольку эти файлы делают именно это, кажется, имеет смысл, что именно там они будут находиться.
  • Мы также можем поместить файлы message-description.php и no-post-list.php в этот каталог, но давайте поместим их в подкаталог Views. Вы можете назвать это Templates или Partials или что-то подобное.
  • Далее у нас есть классы, отвечающие за запросы к базе данных, и класс, отвечающий за координацию обмена сообщениями. Давайте поместим каждый из них в Utility. Конечно, есть и другие места, куда они могли бы пойти, но помните, что цель — продемонстрировать, как использовать пространства имен. Поэтому, если вы чувствуете себя так склонным, не стесняйтесь настраивать свои файлы по своему вкусу.

Если вы следовали тому, что мы сделали выше, то у вас должна быть структура каталогов, которая выглядит примерно так:

Один из способов организовать ваши файлы.

Теперь пришло время определить пространства имен для каждого из классов. Поскольку мы организовали их все в свои каталоги, будет легко указать пространство имен; однако важно понимать, что нам нужно будет использовать ключевое слово use, когда мы используем классы, расположенные в других пространствах имен.

Давайте пройдемся по каждому из наших файлов, начиная с файлов в Utility. Во-первых, мы начнем с Post Messenger :

<?php
/**
 * Display content for the meta box when requested.
 *
 * @author Tom McFarlin
 * @since  0.2.0
 */

namespace McFarlinTRPUtility;
use McFarlinTRPUtilityPost_Query;

/**
 * Retrieves information from the class responsible for querying the database and
 * renders it in the context of our meta box when called via the Meta Box Display.
 *
 * @author Tom McFarlin
 * @since  0.2.0
 */
class Post_Messenger {
  // Snip for brevity. 
}

Вы заметите, что пространство имен файла появляется в заголовке вместе с объявлением об использовании созданного нами класса Post Query . Я добавил имя класса в конец пространства имен, поэтому мне не нужно использовать его во всей кодовой базе.

Обратите внимание, что конструктор теперь выглядит так :

<?php

/**
 * Instantiates the class by setting a reference to the query.
 *
 * @param string $plugin_dir The path to the root of the plugin directory.
 */
public function __construct( $plugin_dir) {

    $this->query      = new Post_Query();
    $this->plugin_dir = trailingslashit( $plugin_dir );
}

Я добавил  аргумент $plugin_dir, потому что нам нужно использовать его для правильного отображения результатов запроса. И поскольку теперь они находятся в другой области приложения, функции выглядят так :

<?php

/**
 * Displays the description of the content of the meta box.
 *
 * @access private
 */
private function get_post_message() {
    include_once $this->plugin_dir. 'Display/Views/post-list.php';
}

/**
 * Displays the description of the content of the meta box.
 *
 * @access private
 */
private function get_description() {
    include_once $this->plugin_dir. 'Display/Views/message-description.php';
}

/**
 * Displays a message of there are no recent posts.
 *
 * @access private
 */
private function get_no_posts_message() {
    include_once $this->plugin_dir. 'Display/Views/no-post-list.php';
}

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

<?php

namespace McFarlinTRPUtility;

/**
 * Queries the database for three most recent posts. Returns the query to the
 * caller so that it can be interrogates for posts or not.
 *
 * @author Tom McFarlin
 * @since  0.2.0
 */
class Post_Query {

  // Snip for brevity.

    private function get_posts() {

        $args = array(
            'post_type'        => 'post',
            'post_status'      => 'publish',
            'posts_per_page' => 3,
            'orderby'          => 'date',
            'order'            => 'desc',
        );
        $this->query = new WP_Query( $args );

        return $this->query;
    }
}

Обратите внимание, что в коде я также поставил перед WP_Query косую черту, потому что это часть глобального пространства имен.

Давайте перейдем в  каталог Display и посмотрим на класс Meta Box. Ему также было присвоено пространство имен, а также используется полное имя класса Meta Box Display, которое мы сейчас рассмотрим.

<?php

 namespace McFarlinTRPDisplay;
 use McFarlinTRPDisplayMeta_Box_Display;

/**
 * Registers the Meta Box with WordPress. Defines the ID, title, display function,
 * and the post type on which it will live.
 *
 * @author Tom McFarlin
 * @since  0.2.0
 */
class Meta_Box {

    /**
     * A reference to the class that will display the contents in the meta box.
     *
     * @access private
     * @var    Meta_Box_Display
     */
    private $meta_box_display;

    /**
     * Instantiates the class by setting its property equal to a reference to its display.
     *
     * @param string $plugin_dir A reference to the root of the plugin's directory.
     */
    public function __construct( $plugin_dir) {
        $this->meta_box_display = new Meta_Box_Display( $plugin_dir );
    }

    // Snip for brevity.
}

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

Наконец, давайте рассмотрим класс отображения Meta Box . Это простой класс, который включает в себя пространство имен и ссылается на Post Messenger, который мы рассмотрели выше.

<?php
/**
 * Defines the display for the meta box.
 *
 * @author Tom McFarlin
 * @since  0.2.0
 */

namespace McFarlinTRPDisplay;
use McFarlinTRPUtilityPost_Messenger;

/**
 * Defines the display for the meta box that will render the content in the
 * context of its meta box.
 *
 * @author Tom McFarlin
 * @since  0.2.0
 */
class Meta_Box_Display {

    /**
     * A reference to the class that will display the contents in the meta box.
     *
     * @access private
     * @var    Post_Messenger
     */
    private $messenger;

    /**
     * Instantiates the object by setting a property equal to that of the class
     * responsible for rendering the messages from the post query.
     *
     * @param string $plugin_dir A reference to the root of the plugin's directory.
     */
    public function __construct( $plugin_dir) {
        $this->messenger = new Post_Messenger( $plugin_dir );
    }

    /**
     * If there are posts to display, renders them in the metabox. Otherwise, displays
     * a note that there are no posts to display.
     */
    public function display() {
        $this->messenger->get_message();
    }
}

На данный момент мы прошли полный круг через плагин. За одним исключением: файл начальной загрузки. Мы добавили к нему пространство имен и должны обновить способ его создания :

<?php

namespace McFarlinTRP;
use McFarlinTRPDisplayMeta_Box;

include 'Display/class-meta-box.php';
include 'Display/class-meta-box-display.php';
include 'Utility/class-post-messenger.php';
include 'Utility/class-post-query.php';

add_action( 'add_meta_boxes', __NAMESPACE__. 'trp_start' );
/**
 * Starts the plugin.
 */
function trp_start() {

    $meta_box = new Meta_Box( dirname( __FILE__) );
    $meta_box->init();
}

А именно, у нас есть:

  • определил пространство имен,
  • ссылаться на расположение класса Meta Box ,
  • обновлены пути, чтобы указать, где найти файлы (что в конечном итоге можно сделать с помощью автозагрузчика),
  • и обновил вызов add_action .

Вот что касается вызова действия добавления: поскольку WordPress необходимо найти эту функцию, а функция находится в пространстве имен, необходимо определить полное имя функции, чтобы WordPress мог ее вызвать. Отсюда и необходимость NAMESPACE в имени функции.

Теперь мы организованы (за одним исключением)

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

Даже если класс немного монолитный, его все же можно организовать таким образом, чтобы упростить обслуживание.

С учетом сказанного, есть еще кое-что, что я бы изменил в этом плагине: передача каталога плагина таким образом не помогает с низкой связностью, и это более тесно связывает классы вместе, потому что файл начальной загрузки должен передавать значение в один класс передает его другому классу, который использует его для загрузки файлов и так далее.

Так есть ли способы исправить это? Абсолютно. И, возможно, мы рассмотрим это в последнем посте.

До тех пор помните, что самая последняя версия плагина доступна в основной ветке с тегом 0.3.0 на GitHub.

Сообщения серии

  1. Быстрое прототипирование с помощью WordPress: от концепции до плагина
  2. Быстрое прототипирование с помощью WordPress: анализ концепции
  3. Быстрое прототипирование: от прототипа к коду, часть 1
  4. Быстрое прототипирование: от прототипа к коду, часть 2
  5. Быстрое прототипирование: знакомство с автозагрузкой

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

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