Шорткод — это тег вида ‘[shortcode]’, помещённый в текст поста и преобразуемый в определённый контент при его отображении. Шорткоды помогают легко конструировать весьма сложные фрагменты страниц. Простейший пример — галерея WordPress: встреченный в тексте поста тег будет заменён кодом галереи изображений.
Любой плагин может определять собственные шорткоды. Это в некотором роде интерфейс, позволяющий пользователям формировать свой контент функциями плагина. Форма шорткода может быть сложнее, если работа этих функций зависит от пожеланий пользователя или заключается в обработке какого-либо текста. Так, шорткоду можно передавать параметры:
Создание шорткодов в WordPress
[shortcode параметр1=»значение1″ параметр2=»значение2″ …]
А также параметры без значений, носящие флаговый характер:
[shortcode параметр1 параметр2]
Наконец, в теги шорткода можно заключить текст:
[shortcode параметры]ТЕКСТ[/shortcode]
В этом случае появляется закрывающий тег [/shortcode].
Создание шорткода
Регистрация нового шорткода выполняется функцией add_shortcode:
add_shortcode(‘mySC’, ‘myShortCode_fn’);
Первый аргумент — имя тега, второй — функция, которая этот тег обработает. Имя зависит от регистра. Поэтому теги ‘[mySC]’ и ‘[mysc]’ различны.
Обрабатывающая шорткод функция получает все его атрибуты и текст, заключённый между головным и закрывающим тегами. Её результат замещает обрабатываемые теги. Параметры в функцию передаются в первом аргументе, текст — во втором:
function myShortCode_fn ($attr, $text = null) {
return $text ? ‘<h1>’.$text.'</h1>’ : »;
}
С такой функцией фрагмент ‘[mySC]Header[/mySC]’ будет преобразован в строку ‘<h1>Header</h1>’.
Если задан только головной тег, аргумент $text будет нулевым.
Параметры шорткода помещаются в массив $attr, передаваемый в первом аргументе. Ключами массива являются имена параметров, имеющих значения, и числа, по которым расположены имена параметров без значений.
То есть при обработке шорткода ‘[mySC x y=»v» z]’ мы будем иметь значение $attr[‘y’] == ‘v’, $attr[0] == ‘x’ и $attr[1] == ‘z’.
Работа с параметрами
Использование параметров в виде $attr[‘pname’] не очень удобно. Было бы проще выполнить extract($attr) и использовать непосредственно $pname, но тогда необходим жёсткий контроль за содержимым массива. Без контроля пользователи получат возможность определять переменные внутри нашей функции.
Необходимую обработку массива осуществляет функция shortcode_atts:
$attr = shortcode_atts($defaults, $attr);
Она формирует массив из массива $defaults, заменяя его значения соответствующими значениями массива $attr, если в нём таковые имеются. Все ключи $attr, отсутствующие в $defaults, будут проигнорированы. Поэтому вызов можно выполнить иначе:
extract(shortcode_atts($defaults, $attr));
После этого все параметры $attr[‘pname’] будут доступны в виде переменных $pname.
Неудобство может возникнуть при работе с флаговыми атрибутами. Вводить шорткод в виде ‘[short a b]’ гораздо удобнее, чем ‘[short a=»true» b=»true»]’.
Выражения ‘[short a b]’ и ‘[short b a]’ равнозначны. Поэтому умолчания для числовых ключей смысла не имеют и чтобы shortcode_atts их не удалил, флаги следует как-то совместить с параметрами.
Например, можно преобразовать все числовые ключи к логическим параметрам, если значение по ключу присутствует среди ожидаемых атрибутов:
$defaults = array(‘a’ => false, ‘b’ => false, … );
…
$def_keys = array_keys($defaults);
for ($i = 0; isset($attr[$i]); $i++)
if (in_array($attr[$i], $def_keys))
$attr[$attr[$i]] = true;
extract(shortcode_atts($defaults, $attr));
В этом случае записи ‘[short a]’, ‘[short a=»1″]’ и ‘[short a=»true»]’ полностью идентичны. Умолчания для всех флагов должны быть ложными.
Ручная обработка
Для задействования шорткодов напрямую мы можем использовать функцию do_shortcode:
<?php echo do_shortcode($text); ?>
Такой код выдаст текст, предварительно обработав в нём все теги.
Практика
В качестве практического примера напишем небольшой плагин, реализующий шорткод, выводящий содержимое всех аргументов своей функции. Такой вариант будет полезен для изучения.
Расположим его в wp-content/plugins/short_debug.php. Вот его текст:
<?php
/*
* Plugin Name: short_debug
*/
add_shortcode(‘sdbg’, ‘shortdebug_shortcode’);
function shortdebug_shortcode ($attr, $text = null) {
$rv = ‘<hr><h3>DBG Shortcode</h3>’;
$rv .= ‘<p>$attr:<ul>’;
if ($attr)
foreach ((array)$attr as $k => $v)
$rv .= ‘<li>[‘.esc_html($k).’] => «’.esc_html($v).’»</li>’;
else
$rv .= ‘<code>[empty]</code>’;
$rv .= ‘</ul>$text: ‘.($text == null ? ‘<code>[null]</code>’ : ‘<b>’.esc_html($text).'</b>’).'</p><hr>’;
return $rv;
}
?>
Активируем плагин, создаём новую запись, пишем тестовую строку:
[sdbg arg_without_any_value arg_with_a_value=»value» arg=»val» arg=»VAL» another_standalone_arg]Некоторый текст[/sdbg]
Сохраняем или публикуем и переходим на просмотр поста. Результат выглядит так:
DBG Shortcode
$attr:
[0] => «arg_without_any_value»
[arg_with_a_value] => «value»
[arg] => «VAL»
[1] => «another_standalone_arg»
$text: Некоторый текст
Заметьте: первое значение arg=»val» затёрто вторым значением «VAL» — смысл имеет только последнее указание атрибута.
Обратите также внимание на употребление функции esc_html при выводе ключей и текста. Она лишает пользователей возможности оставлять собственный HTML-код. Подобная возможность создала бы лазейку для атак с подделкой запросов (CSRF) в отношении любого ресурса, используемого нашими посетителями.
Заключение
Шорткоды просты в создании. Лаконичны. Упрощают жизнь как пользователям, предоставляя широкие возможности в кратких формулировках, так и разработчикам, позволяя легко создать интерфейс для функционала различной сложности.
Всегда необходимо здравое планирование: запоминаться шорткоды должны быстро, читаться легко, необходимых параметров требовать поменьше. Желательно, чтобы умолчания были приемлемы в большинстве случаев.
И никогда не следует забывать о безопасности. В нашем простейшем случае это был контроль атрибутов и выводимого текста.