От автора: шорткоды позволяют выполнять множество задач в WordPress. Однако по умолчанию в WP шорткоды можно использовать только в постах и страницах. Использовать шорткоды в виджетах по умолчанию невозможно. В этой небольшой статье я расскажу вам, как включить данную функцию.
Как включить шорткоды в текстовых виджетах
В WP по умолчанию доступно несколько виджетов. Один из них – текстовый виджет. Как понятно из его названия, виджет предназначен для какого-либо текста. Также в такой виджет можно добавлять HTML код.
В текстовый виджет можно добавить код JS, довольно мощная вещь. Тем не менее, если вам необходим, к примеру, PHP для получения каких-либо данных с сервера, по умолчанию такой виджет делать это не умеет.
То же самое с постами. Именно поэтому нам хотелось бы использовать шорткоды. В этом нам поможет фильтр widget_text. Данный фильтр позволяет редактировать контент в текстовых виджетах. Ниже мы с его помощью будем заставлять WP парсить шорткоды в этом виджете.
Парсингом шорткодов в WP занимается функция do_shortcode(). Функция принимает один обязательный параметр, текст для парсинга, и возвращает готовый результат. То есть данную функцию можно напрямую использовать в виде колбэк функции в фильтре widget_text. Код ниже можно использовать в файле плагина или в файле темы functions.php.
1 2 3 |
<?php add_filter('widget_text', 'do_shortcode'); ?> |
И все. Теперь текстовый виджет будет парсить любой существующий шорткод.
Как создать новый виджет шорткодов
Можно пойти по другому пути и создать свой собственный виджет. Текстовый виджет отлично работает, поэтому мы просто можем адаптировать его код (найти можно тут /wp-includes/default-widgets.php). Нам необходимо создать свой собственный плагин. Никогда не модифицируйте ядро WP.
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<?php class WP_Widget_Text extends WP_Widget { public function __construct() { $widget_ops = array('classname' => 'widget_text', 'description' => __('Arbitrary text or HTML.')); $control_ops = array('width' => 400, 'height' => 350); parent::__construct('text', __('Text'), $widget_ops, $control_ops); } /** * @param array $args * @param array $instance */ public function widget( $args, $instance ) { /** This filter is documented in wp-includes/default-widgets.php */ $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base ); /** * Filter the content of the Text widget. * * @since 2.3.0 * * @param string $widget_text The widget content. * @param WP_Widget $instance WP_Widget instance. */ $text = apply_filters( 'widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance ); echo $args['before_widget']; if ( ! empty( $title ) ) { echo $args['before_title'] . $title . $args['after_title']; } ?> <div class="textwidget"><?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?></div> <?php echo $args['after_widget']; } /** * @param array $new_instance * @param array $old_instance * @return array */ public function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags($new_instance['title']); if ( current_user_can('unfiltered_html') ) $instance['text'] = $new_instance['text']; else $instance['text'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text']) ) ); // wp_filter_post_kses() expects slashed $instance['filter'] = ! empty( $new_instance['filter'] ); return $instance; } /** * @param array $instance */ public function form( $instance ) { $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '' ) ); $title = strip_tags($instance['title']); $text = esc_textarea($instance['text']); ?> <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></p> <p><label for="<?php echo $this->get_field_id( 'text' ); ?>"><?php _e( 'Content:' ); ?></label> <textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo $text; ?></textarea></p> <p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox" <?php checked(isset($instance['filter']) ? $instance['filter'] : 0); ?> /> <label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p> <?php } } ?> |
В коде нужно внести лишь пару изменений. Во-первых, необходимо изменить имя класса. Я назову класс WP_Widget_Shortcodes, а вы можете подобрать любое удобное для вас имя. В конструкторе класса создаются отдельные переменные для виджета, поэтому их необходимо также исправить.
1 2 3 4 5 6 7 |
<?php public function __construct() { $widget_ops = array('classname' => 'widget_shortcodes', 'description' => __('Arbitrary text or HTML with shortcodes.')); $control_ops = array('width' => 400, 'height' => 350); parent::__construct('shortcodes', __('Shortcodes'), $widget_ops, $control_ops); } ?> |
Во-вторых, нам нужно изменить метод widget(), который говорит WP, как отображать виджет. Необходимо изменить контент переменной $text, в которой хранится текст для отображения. Мы удаляем вызов фильтра widget_text и вызываем функцию do_shortcode() для контента.
1 2 3 |
<?php $text = empty( $instance['text'] ) ? '' : do_shortcode($instance['text']); ?> |
Чтобы мы могли добавить виджет, как и любой другой, его необходимо зарегистрировать. Сделать это можно с помощью экшена widgets_init, который вызывается во время регистрации WP виджетов по умолчанию.
1 2 3 4 5 |
<?php add_action('widgets_init', function() { register_widget('WP_Widget_Shortcodes'); }); ?> |
Теперь наш виджет появился в общем списке. Можете разместить его в любой подходящей области, виджет будет парсить ваши шорткоды.
Заключительные слова
Как видно, активировать шорткоды в виджетах не так уж и сложно, но к этому вопросу нужно подходить осторожно. На деле, не все шорткоды будут располагаться на месте виджета. Проблемы могут возникнуть, если шорткод имеет фиксированную ширину.
Обратите внимание на то, что вносимые нами изменения в текстовый виджет были минимальны. Вы же можете менять что угодно для настройки виджета под себя. Скачать для дальнейших экспериментов фильтр и созданный нами виджет вы сможете по ссылке.
Автор: Jérémy Heleine
Источник: //www.sitepoint.com/
Редакция: Команда webformyself.