Как написать short-code класс для WordPress - vorst.ru

Short-code


как написать short-code для WordPress

При написании short-code для WordPress можно создать класс и инкапсулировать в него всю необходимую функциональность. В статье показано с чего нужно начать создание short-code для WordPress, какие методы должны быть определены и как подключить short-code к вашему проекту.

Short-code

как написать short-code для WordPress

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

Должна быть возможность легко размещать такой вопросник в статье или на странице блога WordPress. Об этом была речь в предыдущем посте.

Для подобных задач в WordPress есть механизм short-code. При создании сайта или в процессе развития сайта в страницу или пост вставляется специальный код. Если есть зарегистрированные коды, страница проходит проверку. Если код обнаружен, то вызывается обработчик. Результатом работы обработчика является html код, который вставляется на место short-code.

Именно такой обработчик нам нужно написать. Чтобы скрыть детали реализации от остальной программы, напишем класс, который выполняет все необходимые действия и, прежде всего, регистрирует обработчик (handler).


В классе нам, прежде всего, понадобится вопросник. Имя файла с вопросником будем передавать в конструкторе. Еще нам необходимо зарегистрировать обработчик, и тоже в конструкторе.

class LisetteCCApplication
{
  private $name = 'questionnaire'; // file name of a questionnaire
  private static $questionnaire; // questions and answers
  public function __construct($param) {
    $this->name = $param['name'];
    if ( !is_admin() ) {
      add_action( 'plugins_loaded', [ $this, 'plugins_loaded'] );
      // register shortcode
      add_shortcode('cost_calculator', [$this, 'cost_calculator_handler']);
    }
  }
  public function plugins_loaded() {
    // load questionnaire
    self::$questionnaire = require(dirname(__FILE__) . '/config/' . $this->name . '.php');
  }
}

Обработчик должен возвращать html код. В нашем случае это форма содержащая список полей ввода <input type="radio"> на основе self::$questionnaire.

class LisetteCCApplication
{
  ...
  public function cost_calculator_handler($atts = '') {
    // show questionnaire
    $out = '<div id="cost-calculator">';
    $out .= '<form id="questionnaire-form" action="#" method="post">';
    $out .= $this->show(self::$questionnaire['items']);
    $out .= '<div class="error"></div>';
    $out .= '<input type="submit" value="'. __('Calculate', 'lcc') .'" class="btn-calculate">';
    $out .= '</form>';
    $out .= '</div>';
    return $out;
  }
}

Поля ввода формирует метод show, последовательно проходя по дереву вопросника начиная с корня. Сначала выводятся все вопросы с текущего уровня. Если есть еще уровень, то он рекурсивно выводится следом, в блоке с классом dependent. Таким образом выводится все дерево.

После вывода, все уровни, кроме самого верхнего, скрываются с помощью JavaScript. Тут и пригождается класс dependent.

class LisetteCCApplication
{
  ...
  public function show($items) {
    $out = '';
    foreach($items as $var => $item) {
      $out .= '<div id="'. $var .'" class="question-answers">';
      $out .= '<h3>'. $item['question'] .'</h3>';
      // first - show all answers (inputs)
      $i = 0; $value = [];
      foreach($item['answers'] as $answer) {
        $value[$i] = isset($answer['value']) 
          ? $answer['value'] 
          : 0;
        $out .= $this->option($var, $i, $value[$i], 
          $answer['image'], $answer['caption']);
        $i++;
      }
      //second - recursively show dependent block if exist
      $i = 0;
      foreach($item['answers'] as $answer) {
        if(isset($answer['items']))
          $out .= '<div id="'. $var . '-' . $i .'" class="dependent">' . $this->show($answer['items']) .'</div>';
        $i++;
      } 
      $out .= '</div>';
    }
    return $out;
  }
}

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

class LisetteCCApplication
{
  ...
  public function cost_calculator_handler($atts = '') {
    // show result if exists
    $out = $this->get_results();
    // show questionnaire
    ...
  }
}

Вывод результатов тоже рекурсивный, а потому лаконичный и интуитивно понятный. Полный текст класса LisetteCCApplication можно посмотреть на GitHub.

Чтобы short-code можно было использовать, нужно подключить класс LisetteCCApplication к WordPress. Для этого используется специальный файл, который определяет plugin - его описание, автора и прочее и создает экземпляр только что написанного класса.

<?php
/*
Plugin Name: Lisette Cost Calculator
Plugin URI: http://lisette.vorst.ru
Description: Product cost calculator
Author: Sergey Morozov
Author URI: http://vorst.ru
License: MIT
Version: 1.0
Text Domain: lcc
Domain Path: /languages
*/
define('СOST_CALCULATOR_VERSION', '1.0');
define('СOSTCALCULATOR__DOCUMENT_ROOT', dirname(__FILE__));
require_once 'LisetteCCApplication.php';
function cost_calculator_activate() {
  // Do somethig once, when the plugin is activated.
}
register_activation_hook(__FILE__, 'cost_calculator_activate');
try {
    $application = new LisetteCCApplication(['name' => 'questionnaire-test']);
} catch (Exception $e) {
    echo $e->getMessage();
}

Теперь можно активировать plugin в административной панели. Как это работает вы уже видели, но все же Demo.

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

Заключение

Чтобы short-code мог быть обработан, нужен класс. В классе нужно определить метод-регистратор и метод-обработчик. Метод-регистратор сообщает WordPress, что появился обработчик. Метод-обработчик заменяет short-code на html код.

Класс нужно связать с WordPress с помощью файла со строго определенной заголовочной частью, где определяется название plugin, автор и прочее. В файле обязательно создается экземпляр написанного класса.

Оставьте комментарий