- Создание шорткодов в WordPress CMS
- do_shortcode() │ WP 2.5.0
- Возвращает
- Использование
- Видео с примерами
- Примеры
- #1 Обработает все шорткоды в тексте
- #2 Обработка отдельного шорткода
- #3 Контентный шорткод
- #4 Включение шорткодов в виджете «Текст»
- #5 Обработка только указанного шорткода в контенте
- Заметки
- Список изменений
- Код do_shortcode() do shortcode WP 6.2.2
- Cвязанные функции
- Шорткоды
- WordPress: PHP Include Using A Shortcode
- Using A Plugin
Создание шорткодов в WordPress CMS
Начиная с версии 2.5, разработчики WordPress ввели понятие «Shortcodes API». Этот функционал позволяет создавать и использовать макрокоды в страницах сайта или в записях блога. Например, простая и короткая запись добавит на странице целую фотогалерею.
Более подробно прочитать о шорткодах и узнать, как создавать простые шорткоды, вы можете из документации WordPress.
- Подключение сторонних скриптов и запуск только при наличии шорткода на странице.
- Многоуровневый шорткод.
- Составной шорткод.
- Вложенность шорткодов.
Подготовка почвы
Прежде чем начать создавать что-либо, предлагаю свой вариант размещения файлов:
Практически в каждом руководстве предлагают создавать шорткоды прямо в файле functions.php. Скажу сразу: я — противник такого подхода. Вместо этого настоятельно рекомендую вынести все шорткоды в отдельный файл (includes/shortcodes.php) и подключить его в functions.php одной строкой. Это значительно разгрузит functions.php и сделает код более читабельным.
Заметка: WordPress, конечно, поддерживает подключение файлов через require, но очень не рекомендует делать этого. Вместо этого предлагается использовать get_template_part().
Подключение скриптов
Многие начинающие разработчики очень часто совершают эту ошибку — подключают скрипты, необходимые для работы того или иного шорткода, сразу при объявлении шорткода. Т. е. скрипты загружаются всегда, даже если этого шорткода нет на странице.
function foobar_func( $atts ) < return "foo and bar"; >add_shortcode( 'foobar', 'foobar_func' ); function foo_script () < wp_register_script( 'foo-js', get_template_directory_uri() . '/includes/js/foo.js'); wp_enqueue_script( 'foo-js' ); >add_action( 'wp_enqueue_scripts', 'foo_script');
Это полностью рабочий вариант, но скрипт будет загружаться на каждой странице, даже если он там не нужен (т. е. нет шорткода).
Во избежание таких ситуаций, предлагаю пользоваться следующим подходом:
- Определить шорткод как отдельный класс.
- Добавить флаг, который определит есть ли данный шорткод на странице.
- Загружать скрипт только по флагу присутствия шорткода.
class foobar_shortcode < static $add_script; static function init () < add_shortcode('foobar', array(__CLASS__, 'foobar_func')); add_action('init', array(__CLASS__, 'register_script')); add_action('wp_footer', array(__CLASS__, 'print_script')); >static function foobar_func( $atts ) < self::$add_script = true; return "foo and bar"; >static function register_script() < wp_register_script( 'foo-js', get_template_directory_uri() . '/includes/js/foo.js'); >static function print_script () < if ( !self::$add_script ) return; wp_print_scripts('foo-js'); >> foobar_shortcode::init();
В отличие от предыдущего варианта реализации, этот шорткод инициализируется, но все скрипты подгружаются только при наличии шорткода на странице.
Вложенные шорткоды
Есть еще пара проблем, с которыми могут столкнуться начинающие разработчики:
- Создание многоуровневого шорткода (состоящий из нескольких).
- Использование шорткода внутри такого же шорткода.
Создание многоуровневого шорткода
Проблема заключается в том, что такой шорткод состоит из нескольких более мелких шорткодов и необходимо предотвратить возможность использования их как отдельных шорткодов (кроме случаев, когда это необходимо).
Возьмем к примеру, шорткод, который создает прайсинг таблицу. Для этого необходимо подготовить три отдельных шоркода:
[price]
— [plan title=’Plan 1’ price=’99’]
— [option] Option 1 [/option]
— [option] Option 2 [/option]
— [option] … [/option]
— [/plan]
— [plan title=’Plan 2’ price=’499’]
— [option] Option 1 [/option]
— [option] Option 2 [/option]
— [option] … [/option]
— [/plan]
…
[/price]
В данном примере используется три шорткода: [price] [plan] [option].
add_shortcode( ‘price’, ‘price_code’ );
add_shortcode( ‘plan’, ‘plan_code’ );
add_shortcode( ‘option’, ‘option_code’ );
Для предотвращения использования внутренних шорткодов в качестве отдельных предлагается следующая схема:
Price -> вывод кода на страницу
Plan -> получение данных
Option -> получение данных
Т. е. вывод кода на страницу происходит только во внешнем шорткоде, внутренние же просто возвращают полученные данные. Пример такой реализации приведен ниже.
Описание функции внешнего шорткода:
function price_code ($atts, $content) < // инициализация глобальных переменных для прайс планов $GLOBALS['plan-count'] = 0; $GLOBALS['plans'] = array(); // чтение контента и выполнение внутренних шорткодов do_shortcode($content); // подготовка HTML кода $output = ''; if(is_array($GLOBALS['plans'])) < foreach ($GLOBALS['plans'] as $plan) < $planContent = ''; $planContent .= $plan; $planContent .= ''; $output .= $planContent; > > $output .= ''; // вывод HTML кода return $output; >
Описание функций внутренних шорткодов:
function plan_code ($atts, $content) < // получаем параметры шорткода extract(shortcode_atts(array( 'title' =>'', // Plan title name 'price' => '0', // Plan price ), $atts)); // Подоготавливаем HTML: заголовок плана $plan_title = ''; $plan_title .= ' '.$title.'
'; $plan_title .= ''; // Подоготавливаем HTML: стоимость $f_price = round(floatval($price), 2); $f_price = ($f_Price > 0) ? $f_Price : 0; $s_price = '$'.$f_Price; $price_plan = ''; $price_plan .= ' '.$s_price.'
'; $price_plan .= ' '.$text.''; $price_plan .= ''; // инициализация глобальных переменных для опций $GLOBALS['plan-options-count'] = 0; $GLOBALS['plan-options'] = array(); // читаем контент и выполняем внутренние шорткоды do_shortcode($content); // Подоготавливаем HTML: опции $plan_options = ''; if (is_array($GLOBALS['plan-options'])) < foreach ($GLOBALS['plan-options'] as $option) < $plan_options .= $option; >> $s_OptionsDiv.= ''; // Подоготавливаем HTML: компонуем контент $plan_div = $plan_title; $plan_div .= $price_plan; $plan_div .= $plan_options; // сохраняем полученные данные $i = $GLOBALS['plan-count'] + 1; $GLOBALS['plans'][$i] = $plan_div; $GLOBALS['plan-count'] = $i; // ничего не выводим return true; > function option_code ($atts, $content) < // Подоготавливаем HTML $plan_option = ''; $plan_option .= ' '.do_shortcode($content).'
'; $plan_option .= ''; // сохраняем полученные данные $i = $GLOBALS['plan-options-count'] + 1; $GLOBALS['plan-options'][$i] = $plan_option; $GLOBALS['plan-options-count'] = $i; // ничего не выводим return true; >
При этом подходе шорткод будет работать только в сборе, т. е. при правильном использовании, в других случаях ничего не будет выведено на экран (соответственно, ничего не сломается).
Конечно же, вы можете еще оптимизировать и усовершенствовать этот шорткод, но все же, думаю, основную идею продемонстрировать мне удалось.
Повторяющиеся шорткоды
Проблема заключается в следующем: нужно внутри шорткода использовать такой же шорткод. Наиболее частым примером в моей практике был шорткод для создания колонки. Т.е., к примеру, нужно реализовать разделение страницы на 2 части с помощью колонок и в первую колонку разделить еще на 2 колонки.
[column_half]
[column_half] Content [/column_half]
[column_half] Content [/column_half]
[/column_half]
[column_half] Content [/column_half]
К сожалению, для WordPress уже такая вложенность “не по зубам”. Верстка разлетится уже на втором контенте. Происходит это потому что при открытии шорткода WordPress сразу же ищет вторую (закрывающую) часть этого шорткода, т.е. в данном примере первая колонка будет закрыта на первом же вложенном шорткоде.
Для решения этой проблемы, к сожалению, нет других вариантов, нежели просто добавить новые шорткоды. Но, переписывать функции нет смысла, можно просто инициализировать шорткод на уже имеющиеся функции:
add_shortcode( 'column_half', 'column_half_code' ); add_shortcode( 'column_half_inner', 'column_half_code' ); function column_half_code ( $atts, $content ) < return "
Заключение
В данной статье я рассмотрел наиболее частые проблемы, с которыми сам когда-либо сталкивался. Если же у вас есть что добавить, исправить, либо предложить свой вариант решения той или иной проблемы, не стесняйтесь писать в комментариях к этой статье.
Автор: Дмитрий Кабаков, Senior Front-end Developer.
do_shortcode() │ WP 2.5.0
Находит в переданном тексте зарегистрированные шорткоды и обрабатывает их. Функция обработает только шорткоды, о которых WP знает (которые зарегистрированы как шорткоды). Шорткоды регистрируются с помощью функции add_shortcode(). Т.е. конструкции вида [some_name] не будут удалены или обработаны, если в WordPress не добавлен шорткод some_name . Если тег шорткода неизвестен, то контент вернется как есть (шорткод в нем не будет обработан). Такое может получиться, например, когда Плагин отключен, но его шорткод используется в контенте.
Возвращает
Использование
do_shortcode( $content, $ignore_html );
$content(строка) (обязательный) Текст в котором нужно преобразовать шорткоды. $ignore_html(строка) Игнорировать ли шорткоды внутри HTML. Если поставить true, то шорткоды внутри HTML обработаны не будут.
По умолчанию: false
Видео с примерами
Примеры
#1 Обработает все шорткоды в тексте
Из файла shortcodes.php . Прикрепляет функцию do_shortcode() к фильтру the_content , который срабатывает при выводе контента поста:
add_filter( 'the_content', 'do_shortcode', 11 );
#2 Обработка отдельного шорткода
Использование шоткода в PHP файле, за пределами контента, когда нужно получить вывод шоткода отдельно. Этот пример показывает как обработать шорткод из кода PHP. Например, если нужно вывести шорткод в где-то произвольном месте шаблона.
echo do_shortcode( '[somename]' );
echo do_shortcode( '[contact-form-7 title="quote"]' );
#3 Контентный шорткод
echo do_shortcode( '[iscorrect]'. $text_to_be_wrapped_in_shortcode .'[/iscorrect]' );
#4 Включение шорткодов в виджете «Текст»
#5 Обработка только указанного шорткода в контенте
Допустим мы хотим добавить поддержку шорткодов в комментариях, но нам не нужно чтобы там можно было использовать все возможные шорткоды. Нам нужно чтобы там работал только наш шорткод, назовем его [myshort] . Реализовать такую задачу можно оставив зарегистрированным только нужный нам шорткод перед вызовом функции apply_shortcodes(). Все зарегистрированные шорткоды хранятся в глобальной переменной $shortcode_tags.
// Обрабатываем шорткод [myshort] в контенте комментария. // after wpautop add_filter( 'comment_text', 'do_shortcodes_in_comment_content', 11, 2 ); function do_shortcodes_in_comment_content( $content, $comm )< if( 'comment' === $comm->comment_type ) < $save = $shortcodes = & $GLOBALS['shortcode_tags']; $shortcodes = [ 'myshort' =>$shortcodes['myshort'] ]; $content = apply_shortcodes( $content ); $shortcodes = $save; // return back > return $content; >
Заметки
Список изменений
Код do_shortcode() do shortcode WP 6.2.2
function do_shortcode( $content, $ignore_html = false ) < global $shortcode_tags; if ( false === strpos( $content, '[' ) ) < return $content; >if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) < return $content; >// Find all registered tag names in $content. preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches ); $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] ); if ( empty( $tagnames ) ) < return $content; >$content = do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ); $pattern = get_shortcode_regex( $tagnames ); $content = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $content ); // Always restore square braces so we don't break things likeЧитайте также: Php дата формата mysql