• доступно о веб-разработке
04.01.2015 JavaScript, PHP, Wordpress, Плагины, Уроки

Разработка плагина для WordPress #3

wp-plug-dev

Завершаем разработку плагина для WordPress. В конце данного урока мы получим готовый к работе плагин.

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

 

Для создания файловой структуры плагина мы воспользовались программой-генератором Yeoman.

 

Напомню этот достаточно простой процесс, который экономит нам время.

Вместо того, чтобы вручную воссоздавать структуру плагина, мы используем консольное приложение Yeoman, написанное на Node.JS.

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

После чего мы через встроенную возможность поиска ищем генераторы по тегу WordPress, устанавливаем и зайдя в папку /wp-content/plugins/папка_плагина (где папка_плагина — это заранее выбранное вами название плагина, переведённое в соответствующий формат) вашей установки WordPress, запускаем генератор командой  yo, выбираем соответствующий генератор и нажимаем Enter.

Также можно просто запустить из консоли следующую команду yo wordpress-plugin.

Yeoman задаст нам пару вопросов, после чего сгенерирует необходимую файловую структуру плагина.

 

Структура плагина сгенерирована для абстрактного плагина с именем MyPlugin.

Если вы зайдете в папку /wp-content/plugins/mypluginname/, то увидите в ней следующую файловую структуру:

├── MyPluginName.php
├── README.txt
├── assets
│   └── index.php
├── css
│   └── index.php
├── js
│   ├── index.php
│   ├── my-plugin-name-admin.js
│   └── my-plugin-name.js
├── lang
│   ├── index.php
│   └── my-plugin-name.pot
├── my-plugin-name.php
├── package.json
├── sass
│   └── index.php
├── uninstall.php
└── views
├── admin.php
├── index.php
└── public.php

Конечно, нам не обязательно иметь точно такую же структуру. Допустим, вы не используете препроцессор Sass для компиляции CSS. В таком случае, можно смело удалять эту папку.

Вообще, вы можете удалить всё, кроме файлов my-plugin-name.php, MyPluginName.php и README.txt.

Но давайте от некого абстрактного плагинаMyPluginName вернёмся ко вполне конкретному Easy Prism Syntax Highlight, разработкой которого мы занимались в прошлый раз.

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

  • Название переводится целиком в нижний регистр
  • Пробелы заменяются на тире или нижнее подчёркивание

В итоге мы получили папку /wp-content/plugins/easy-prism-syntax-highlighter.

Подробно о том, что и как должно быть внутри плагина, написано в Кодексе разработчика WordPress.

Мы создали главный файл плагина easy-prism-syntax-highlighter.php, а всю логику вынесли в отдельный класс, файл которого разместили в той же папке, назвав его PrismSyntaxHighlither.php.

Код класса по части его свойств мы разбирали в прошлый раз.

Теперь давайте обратимся к его методам.

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

Первым идёт метод конструктора класса:

/**
* Initialize the plugin by setting localization, filters, and administration functions.
*
* @since 1.0.0
*/
private function __construct() {

// Load plugin text domain
// add_action("init", array($this, "load_plugin_textdomain"));

// Add the options page and menu item.
// add_action("admin_menu", array($this, "add_plugin_admin_menu"));

// Load admin style sheet and JavaScript.
// add_action("admin_enqueue_scripts", array($this, "enqueue_admin_styles"));
// add_action("admin_enqueue_scripts", array($this, "enqueue_admin_scripts"));
// Load public-facing style sheet and JavaScript.
add_action("wp_enqueue_scripts", array($this, "enqueue_styles"));
add_action("wp_enqueue_scripts", array($this, "enqueue_scripts"));
add_action ("wp_enqueue_scripts",array($this,"load"));
// Move auto p filter
remove_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'wpautop' , 12);
// add shortcodes
add_shortcode('code',array($this,'shortcode'));
add_shortcode('c',array($this,'shortcode'));
// Load TinyMce button plugin
add_filter('mce_external_plugins',array($this,'tinymce_plugin'));
add_filter('mce_buttons',array($this,'tinymce_button'));
}

У него приватная инкапсуляция, потому что это класс, созданный согласно паттерну Singleton. Он вызывается при помощи особого статического метода get_instance. Таким образом не может быть создано более одной сущности объекта класса вовне его.

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

Мы лишь оставили хуки на загрузку скриптов и стилей. Давайте посмотрим на эти методы подробнее:

 /**
* Register and enqueue public-facing style sheet.
*
* @since 1.0.0
*/
public function enqueue_styles() {
wp_register_style("prism", plugins_url("css/prism.css", __FILE__), array(),
$this->version);
}

/**
* Register and enqueues public-facing JavaScript files.
*
* @since 1.0.0
*/
public function enqueue_scripts() {
wp_register_script("prism", plugins_url("js/prism.js", __FILE__), array("jquery"),
$this->version);
}

Файлы prism.js и prism.css мы берём из дистрибутива jQuery-плагина для подсветки синтаксиса под одноименным названием:
http://prismjs.com

Тем самы мы зарегистрировали скрипты и стили заранее. Но когда мы будем их вызывать? В этом нам поможет следующий метод.

 /**
* Load scripts and styles
*
* @since 1.0.0
*/
public function load(){
global $post;
//if(!is_singular()) return;
$content = $post->post_content;
if ( FALSE !== strpos( $content, '[code' ) OR FALSE !== strpos( $content, '<code class="lang' ) ) {
wp_enqueue_style('prism');
wp_enqueue_script('prism');
}
}

Если мы встречаем в посте специальный «шорткод» или же тег кода, тогда загружается скрипт подсветки синтаксиса.

Вернёмся снова в конструктор:

// Move auto p filter
remove_filter( ‘the_content’, ‘wpautop’ );
add_filter( ‘the_content’, ‘wpautop’ , 12);

Мы переносим фильтр автоматического добавления тега <p> вперёд, чтобы он не добавлял лишние теги абзаца вовнутрь нашего «шорткода».

После чего, собственно, в конструкторе добавляет хук для «шорткода»:

 // add shortcodes
add_shortcode(‘code’,array($this,’shortcode’));
add_shortcode(‘c’,array($this,’shortcode’));

Делаем два одинаковых «шорткода» – один обычный [code][/code], а второй короткий для более оперативных действий — [c][/c].

Следующий метод обрабатывает «шорткод»:

/**
* Shorcode implementaion
*
* @since 1.0.0
*
* @param array $attrs Shortcode attributes
* @param string $content Content
*/
public function shortcode($attrs, $content = «»){
$class = »;
if(isset($attrs[0])){
$class = «language-«.$attrs[0];
}
else {
$class = «language-markup»;
}
if(FALSE !== strpos($content,»\n»)){
$content = trim(strip_tags($content),»\n\r»);
return «<pre class=\»{$class}\»><code class=\»{$class}\»>{$content}</code></pre>»;
}
else {
return «<code class=\»{$class}\»>{$content}</code>»;
}
}

Банально, один аргумент, ключ которого является подсвечиваемым языком. Например, [code php][/code].

Если ключ не указан, показывается базовый markup.

Остаётся только лишь добавить кнопку в Визуальный редактор и «горячие клавиши».

 // Load TinyMce button plugin
add_filter(‘mce_external_plugins’,array($this,’tinymce_plugin’));
add_filter(‘mce_buttons’,array($this,’tinymce_button’));

Кнопка добавляется элементарно:

 /**
* Tinymce button
*
* @since 1.0.0
*/
public function tinymce_button($buttons) {
array_push($buttons, ‘separator’, ‘wp-prism-hl-code’);
return $buttons;
}

А вот с плагином для редактора всё интереснее:

 /**
* Tinymce plugin
*
* @since 1.0.0
*/
public function tinymce_plugin($plugins_array){
$plugin_array[‘code’] = plugins_url($this->plugin_slug) . ‘/js/tinymce.js’;
return $plugin_array;
}

Для генерации JavaScript я пользуюсь препроцессорным языком CoffeeScript и программой CodeKit, которая автоматически компилирует многие препроцессорные языки.

Листинг файла js/tinymce.coffee:

(($)->
$ ->
tinymce.create ‘tinymce.plugins.Code’,
init: (ed,url)->
ed.addButton ‘wp-prism-hl-code’,
title: «Code»
cmd: «code»
icon: ‘code’
ed.addShortcut ‘alt+c’, ‘Insert [code] shortcode.', 'code'
ed.addCommand 'code', ->
if sel_text = ed.selection.getContent()
text = '[code]' + sel_text + '[/code]'
else
text = '[code][/code]'
ed.execCommand('mceInsertContent',0,text)
getInfo: ->
[
longname: "WordPress Prism Highlighter"
author: "Dmitriy Belyaev"
authorurl: "http://codemotion.ru"
infourl: "http://codemotion.ru"
version: "1.0"
]
tinymce.PluginManager.add('code',tinymce.plugins.Code)

) jQuery

Из него генерируется файл js/tinymce.js следующего содержания:

// Generated by CoffeeScript 1.8.0
(function() {
(function($) {
return $(function() {
tinymce.create('tinymce.plugins.Code', {
init: function(ed, url) {
ed.addButton('wp-prism-hl-code', {
title: "Code",
cmd: "code",
icon: 'code'
});
ed.addShortcut('alt+c', 'Insert [code] shortcode.', 'code');
return ed.addCommand('code', function() {
var sel_text, text;
if (sel_text = ed.selection.getContent()) {
text = '[code]' + sel_text + '[/code]';
} else {
text = '[code][/code]';
}
return ed.execCommand('mceInsertContent', 0, text);
});
},
getInfo: function() {
return [
{
longname: "WordPress Prism Highlighter",
author: "Dmitriy Belyaev",
authorurl: "http://codemotion.ru",
infourl: "http://codemotion.ru",
version: "1.0"
}
];
}
});
return tinymce.PluginManager.add('code', tinymce.plugins.Code);
});
})(jQuery);

}).call(this);

Всё, плагин должен работать так, как мы его и задумывали:
img_54a8eeedf3577

В следующем уроке мы поговорим о процессе публикации плагина в официальный каталог WordPress, чтобы в итоге он выглядел примерно следующим образом:
2015-01-04 10-48-50 Редактировать запись ‹ ДвижКод — WordPress

Поделиться

Комментарии Правила дискуссии

Читайте ранее:
Запускаем Sublime из консоли

Сегодня Sublime является излюбленным средством работы с кодом миллионов веб-разработчиков. В ходе курса лекций «Веб от А до Я» я уже рассказывал об...

Закрыть