От автора: WooCommerce, возможно самый популярный способ продать товары, используя WordPress. Примерно 25% интернета и WooCommerce обеспечивают около 39% всех интернет-магазинов, используя WordPress. Если вы хотите продавать товары клиентам, то использовать их в сочетании друг с другом, это самый надёжный способ. Но иногда, как с любым программным обеспечением, нам или нашим клиентам хочется расширить набор функций исходя из тех, что предлагаются в стандартном наборе.
Например: есть простой продукт, который нужно продать, но сначала необходимо включить немного больше информации о продукте для отображения в интерфейсе. Мы рассмотрим, как расширить в WooCommerce описание товара, используя пару хуков, предоставляемых этим же сервисом, и пользовательские функции, которые мы напишем.
Необходимые инструменты
Предполагается, что на компьютере уже есть следующие настройки (или что-то подобное):
Выбранная операционная система — я выбрал macOS
PHP не меньше 5.6.25, я буду использовать PHP 7
MySQL 5.6.33
Apache или Nginx
WordPress 4.7
WooCommerce 3.9
И ваша IDE
Далее по руководству предполагается, что все это установлено, активировано и запущено.
Если вы загружаете WooCommerce специально ради этого руководства, вам не нужно беспокоиться о таких вещах, как страницы корзины, условия и положения, или всё прочее в этом роде. На самом деле, мы собираемся сосредоточиться на метабоксе Simple Product на протяжении всего этого руководства.
Добавление пользовательских полей
Когда дело доходит до работы с WordPress, понятие пользовательских полей обычно несет в себе другое определение: WordPress имеет возможность разрешать авторам публикаций назначать настраиваемые поля для публикации. Эта произвольная дополнительная информация известна как метаданные.
Для тех, кто не является разработчиком, этот тип информации может быть довольно сложным и ненужным. Но если вы привыкли работать с WordPress, важно отметить, что когда я ссылаюсь на пользовательские поля в этом уроке, я говорю о чем-то совершенно другом.
Я говорю о текстовом поле, которое мы представим на вкладке Linked Product (Связанный продукт) типа Simple Product.
Но об этом мы поговорим позже, а пока давайте начнем.
Хуки
Подобно WordPress, WooCommerce предоставляет API, который позволяет нам подключаться к части жизненного цикла страницы. Поэтому, хотя вы, возможно, раньше работали с API метаданных WordPress, это делается отдельно с WooCommerce. Существуют два приёма, которые важно знать:
woocommerce_product_options_grouping. Эту функцию мы будем использовать для создания описания и ввода текста, которые будут принимать наши значения.
woocommerce_process_product_meta. А эту — для обработки, дезинфекции и сохранения значения нашего ввода текста.
Эти хуки требуется определить, как любые другие в WordPress, а затем определить для них настраиваемые функции. И хотя это можно сделать с помощью процедурного программирования, это руководство будет реализовывать функциональность с помощью объектно-ориентированного программирования.
Функциональность
Сначала мы определим класс, который будет иметь переменную, как данные экземпляра. Эта переменная будет представлять идентификатор поля ввода, который появится в пользовательском интерфейсе:
1 2 3 4 5 6 |
<?php class TutsPlus_Custom_WooCommerce_Field { private $textfield_id; } |
Затем мы инициализируем эту переменную экземпляра в конструкторе класса:
1 2 3 4 5 6 7 8 9 10 |
<?php class TutsPlus_Custom_WooCommerce_Field { private $textfield_id; public function __construct() { $this->textfield_id = 'tutsplus_text_field'; } } |
На этом этапе мы готовы начать использовать перечисленные выше хуки. Для этого мы добавим функцию инициализации, которая зарегистрирует две пользовательские функции с помощью одного из хуков. В следующих двух разделах мы рассмотрим, как реализовать пользовательскую функциональность.
Добавление поля ввода текста
Во-первых, нам нужно добавить функцию, к которой подключен woocommerce_product_options_grouping. В функции init, которую мы определили в предыдущем разделе, мы сделаем следующее.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php class TutsPlus_Custom_WooCommerce_Field { private $textfield_id; public function __construct() { $this->textfield_id = 'tutsplus_text_field'; } public function init() { add_action( 'woocommerce_product_options_grouping', array( $this, 'product_options_grouping' ) ); } public function product_options_grouping() { } } |
Обратите внимание, что я назвал эту функцию product_options_grouping. Я считаю, что это делает код более легким для чтения. Хотя функция сама по себе не может быть очень описательной, она относится к соответствующему ей хуку. Затем нам нужно реализовать следующую функцию. Для того нам понадобится следующая информация:
Идентификатор, который мы будем использовать, чтобы точно определить текстовое поле. Мы будем использовать набор данных экземпляра в конструкторе.
Метка, которая будет использоваться для того, чтобы дать некоторое описание в поле ввода.
Также для целей нашего примера можно дополнительно указать плэйсхолдер.
Есть возможность отображать всплывающую подсказку, когда пользователь наводит курсор мыши на значок.
И есть опция для описания, которую мы будем использовать для заполнения текста всплывающей подсказки.
Вся вышеуказанная информация будет установлена в ассоциативном массиве и затем будет передана woocommerce_wp_text_input. Это функция API WooCommerce, предназначенная для вывода текстового элемента с указанными выше аргументами.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php class TutsPlus_Custom_WooCommerce_Field { private $textfield_id; public function __construct() { $this->textfield_id = 'tutsplus_text_field'; } public function init() { add_action( 'woocommerce_product_options_grouping', array( $this, 'product_options_grouping' ) ); } public function product_options_grouping() { $description = sanitize_text_field( 'Enter a description that will be displayed for those who are viewing the product.' ); $placeholder = sanitize_text_field( 'Tease your product with a short description.' ); $args = array( 'id' => $this->textfield_id, 'label' => sanitize_text_field( 'Product Teaser' ), 'placeholder' => 'Tease your product with a short description', 'desc_tip' => true, 'description' => $description, ); woocommerce_wp_text_input( $args ); } } |
На этом этапе у нас есть первая часть плагина, но нам еще предстоит написать код, который устанавливает все в движении, и код, который сохраняет информацию в базе данных, поэтому давайте сейчас займёмся именно этим.
Сохранение информации
Добавьте следующие строки кода в init метод:
1 2 3 4 5 |
<?php add_action( 'woocommerce_process_product_meta', array( $this, 'add_custom_linked_field_save' ) ); |
После этого обязательно добавьте функцию add_custom_linked_field_save.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php public function add_custom_linked_field_save( $post_id ) { if ( ! ( isset( $_POST['woocommerce_meta_nonce'], $_POST[ $this->textfield_id ] ) || wp_verify_nonce( sanitize_key( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) ) ) { return false; } $product_teaser = sanitize_text_field( wp_unslash( $_POST[ $this->textfield_id ] ) ); update_post_meta( $post_id, $this->textfield_id, esc_attr( $product_teaser ) ); } |
В следующем разделе я расскажу немного о реализации функции.
Очистка данных
Обратите внимание, что в функции выше есть три вещи:
Мы проверяем, есть ли несколько значений nonce. Если нет, то мы вернем false. Это стандартная мера предосторожности. Значения nonce обнаруживаются, глядя конкретно на то, что предлагает WooCommerce в исходном коде.
Санируйте данные в $_POST коллекции, соответствующие введенному значению пользователя.
Сохраните информацию в таблице метаданных поста.
Обратите внимание, что мы фактически ничего не делаем, чтобы отобразить информацию в интерфейсе, даже не нужно вызывать get_post_meta. Однако именно так мы будем предоставлять информацию в интерфейсе.
Отображение тизера на front end
Для предоставления информации в интерфейсе нам понадобится класс, который будет выполнять большую часть той же работы, которую мы уже сделали. В частности, нам понадобятся:
идентификатор текстового поля
инициализация указанного идентификатора в конструкторе
функция инициализации для подключения нашего пользовательского кода к интерфейсу
рендеринг фактического значения
Настройка этого процесса на самом деле не так сложна, к тому же мы уже её сделали, поэтому ниже я собираюсь передать класс целиком; тем не менее, у меня будет несколько комментариев, чтобы объяснить, как настроить этот класс после прыжка:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php class TutsPlus_Custom_WooCommerce_Display { private $textfield_id; public function __construct() { $this->textfield_id = 'tutsplus_text_field'; } public function init() { add_action( 'woocommerce_product_thumbnails', array( $this, 'product_thumbnails' ) ); } public function product_thumbnails() { $teaser = get_post_meta( get_the_ID(), $this->textfield_id, true ); if ( empty( $teaser ) ) { return; } echo esc_html( $teaser ); } } |
Конечный результат должен быть примерно таким:
На данный момент у нас есть лишний код. В частности, общедоступный и административный классы используют textfield_ID и настраивают его в своем конструкторе. Это код “с душком”, поскольку он нарушает весь принцип DRY объектно-ориентированного программирования.
Существует несколько способов облегчить это, например, передать значение в конструкторы при создании экземпляров классов, используя простой шаблон проектирования для организации информации между этими двумя классами и т. д.
В файле, который сопровождает этот урок (его можно загрузить с помощью ссылки на боковой панели), вы увидите, как я передал значение в конструктор, чтобы сделать его немного проще в управлении.
Обратите внимание, что я использую хук woocommerce_product_thumbnails, чтобы помочь сделать рендеринг информации. Существует несколько доступных для WooCommerce хуков, и я просто выбрал этот из доступных для рендеринга. Вы можете свободно разбираться в документации, чтобы определить, какой хук лучше всего подходит для ваших нужд.
Соединим воедино
Последнее, что нам нужно сделать, это настроить загрузочный файл, который запустит плагин. Мы делали это в ряде моих предыдущих уроков, поэтому сейчас я не буду тратить слишком много времени на то, чтобы ввести в суть дела. Здесь пример того, как я разбиваю код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?php /** * The plugin bootstrap file * * This file is read by WordPress to generate the plugin information in the * plugin admin area. This file also includes all of the dependencies used by * the plugin, and defines a function that starts the plugin. * * @link //code.tutsplus.com/tutorials/adding-custom-fields-to-simple-products-with-woocommerce--cms-27904 * @package CWF * * @wordpress-plugin * Plugin Name: Tuts+ Custom WooCommerce Field * Plugin URI: //code.tutsplus.com/tutorials/adding-custom-fields-to-simple-products-with-woocommerce--cms-27904 * Description: Demonstrates how to add a custom field to a Simple Product. * Version: 1.0.0 * Author: Tom McFarlin * Author URI: //tommcfarlin.com * License: GPL-2.0+ * License URI: //www.gnu.org/licenses/gpl-2.0.txt */ defined( 'WPINC' ) || die; include_once 'admin/class-tutsplus-custom-woocommerce-field.php'; include_once 'public/class-tutsplus-custom-woocommerce-display.php'; add_action( 'plugins_loaded', 'tutsplus_wc_input_start' ); /** * Start the plugin. */ function tutsplus_wc_input_start() { if ( is_admin() ) { $admin = new TutsPlus_Custom_WooCommerce_Field( 'tutsplus_text_field' ); $admin->init(); } else { $plugin = new TutsPlus_Custom_WooCommerce_Display( 'tutsplus_text_field' ); $plugin->init(); } } |
Обратите внимание, что сначала я включаю зависимости, а затем, как только функция срабатывает, проверяю, отображается ли панель мониторинга. Если отображается, то загружается соответствующая часть плагина; в противном случае загружается стандартный дисплей, который вы можете увидеть на странице товара.
Вывод
На этом этапе мы рассмотрели всё, что мы и планировали во введении данного урока:
Добавили настраиваемое поле.
Санировали и сохранили его.
Создали публичный аспект плагина.
И получили и отобразили контент.
Автор: Tom McFarlin
Источник: //code.tutsplus.com/
Редакция: Команда webformyself.