WordPressの便利な機能、ショートコード。投稿だけでなくウィジェットでも使えたら…というときに役立つ、2つのTIpsをお届け。
WordPressのショートコードAPIについて説明した記事で検証したとおり、WordPressのショートコードを使っていろいろなことができます。ただし、WordPressのデフォルトでは、ショートコードを使用できるのは投稿(およびページ)のみで、ほかの場所では使えません。
ウィジェットでショートコードを使用したくても、デフォルトではできません。しかし、本記事ではこの機能を有効にする方法を説明します。
テキストウィジェットでショートコードを使えるようにする
WordPressは、デフォルトで数個のウィジェットを提供しています。そのうちの1つは、その名のとおりウィジェットに任意のテキストを追加できる「テキスト」ウィジェットです。これはHTMLコードの追加にも使えます。
つまり、ウィジェットでJavaScriptコードを自由に使えるということで、とても効力を発揮するものです。ただし、サーバーに保存されたデータにアクセスするためのPHPスクリプトなどが必要な場合、ウィジェットはデフォルトのままでは役に立ちません。
これは投稿に似ています。だから投稿と同じように、ショートコードを使ってしたいことができるようにします。そのためにはwidget_textフィルターを使用します。このフィルターは「テキスト」ウィジェットの内容変更を可能にするために呼び出されます。ウィジェットでショートコードを解析するようWordPressに要求するために、ここで使用しましょう。
do_shortcode()関数のおかげでWordPressでショートコード解析ができます。これは、必須パラメーター1つとテキストの解析を受け入れ、解析したテキストを返します。つまり、widget_textフィルター内のコールバックとして、この関数を直接使用できます。
次に紹介するコードは、テーマのプラグインファイルやfunctions.phpファイルで使用できます。
<?php
add_filter('widget_text', 'do_shortcode');
?>
これで完了です。「テキスト」ウィジェットに入力したショートコードが解析されるようになりました。
新規ショートコードウィジェットを作成する
別の方法として、独自のウィジェットの作成もできます。デフォルトの「テキスト」ウィジェットが完璧に動作するので、(/wp-includes/default-widgets.phpファイルにある)以下からコードを借用するだけです。注意したいのは、独自のプラグインを作成すべきで、コアWordPressのコアファイルは決して変更しないことです。
<?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と名づけましたが、好きな名前をつけてください。また、このクラスのコンストラクタがウィジェットに関する一部の情報を設定してあるので、変更する必要があります。
<?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);
}
?>
ほかに変更するのは、ウィジェットの表示方法をWordPressに説明するwidget()メソッドにあります。表示するテキストが含まれている$text変数の内容を変更します。widget_textフィルターの呼び出しを削除し、コンテンツにdo_shortcode()関数を適用します。
<?php
$text = empty( $instance['text'] ) ? '' : do_shortcode($instance['text']);
?>
次に、ウィジェットを登録して、ほかのウィジェットと同じように追加できるようにします。WordPressがデフォルトのウィジェットを登録するときにトリガーされる、widgets_initアクションを使います。
<?php
add_action('widgets_init', function() {
register_widget('WP_Widget_Shortcodes');
});
?>
これで、利用可能なウィジェットのリストで、ウィジェットが表示されるようになります。ウィジェットは任意のエリアに追加でき、使用するすべてのショートコードを読み取ります。
最後に
ここまで書いてきたように、ウィジェットでショートコードを使えるようにするのはそれほど複雑なことではありません。ただし、すべてのショートコードがウィジェットが表示されている場所に適応するわけではありません。ショートコードに固定幅の要素が含まれている場合、問題になることがあります。
デフォルトの「テキスト」ウィジェットに対して実施した変更点は、最小限のものです。ウィジェットをカスタマイズしたい場合は、ほかも変更できます。さらに試したい場合は、サンプルとして作成したプラグインはここからダウンロードしてください。
(原文:Quick Tip: How to Use Shortcodes Within Widgets in WordPress)
[翻訳:柴田理恵/編集:Livit]