【WP】ウィジェット用のショートコードの表示位置がおかしい
ショートコードを作成してウィジェットでも使えるようにしたんですが、タイトルの表示位置がおかしいので原因を調べて対処しました。
現象
functions.phpに書いた問題が起きるショートコードです。
recommendというタグ(スラッグ)を付けた投稿をサイドバーにサムネイル付きで10件まで表示させるコードです。
function shortcode_recommend(){
?>
<div class="recommend_parent">
<?php query_posts('tag=recommend&showposts=10');?>
<?php if(have_posts()):while(have_posts()):the_post();?>
<div class="recommend_box">
<div class="recommend_thumb">
<a href="func/<?php echo get_permalink(); ?>">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail( array( 128, 72 ));
}else {
echo '<img src="' . get_template_directory_uri() . '/images/no_image.jpg' . '"width="128" height="72" alt="thumbnail" />';
}
?>
</a>
</div>
<div class="recommend_title">
<p>
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a>
</p>
</div>
</div>
<?php endwhile;endif;?>
</div>
<?php
}
add_shortcode('recommend','shortcode_recommend');
ショートコードをウィジェットで使うには以下のコードをfunctions.phpに記載する必要があるので記載しました。
// ショートコードをウィジェットで使えるようにする関数
add_filter('widget_text', 'do_shortcode' );
そうしておいてからウィジェットの管理画面でカスタムHTMLにショートコードを記載します。
[ recommend ]
※<pre>タグで囲んでも動作するので便宜上半角スペースで間を開けています
問題がなければウィジェットの設定画面で付けたタイトルは、通常は下図のように上部に表示されます。
ところが何故かタイトルが下に付きます。
ディベロッパーツールで確認すると、ウィジェットのタイトル(h2)は本来「recommentd_parent」の子要素とならないといけないのにsectionタグの子要素になっています。
原因判明
筆者の場合は初心者なのでほとんどが知識不足によるものなんですが、「ウィジェット ショートコード 位置 おかしい」で検索したらすぐに解決策が見つかりました。
はっきり言って良くわかないですが以下のように表示させたい部分をob_start();
とob_get_clean();
で囲んでやると正常に表示されるようになりました。
function shortcode_recommend(){
ob_start();
?>
<div class="recommend_parent">
<?php query_posts('tag=recommend&showposts=10');?>
<?php if(have_posts()):while(have_posts()):the_post();?>
<div class="recommend_box">
<div class="recommend_thumb">
<a href="func/<?php echo get_permalink(); ?>">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail( array( 128, 72 ));
}else {
echo '<img src="' . get_template_directory_uri() . '/images/no_image.jpg' . '"width="128" height="72" alt="thumbnail" />';
}
?>
</a>
</div>
<div class="recommend_title">
<p>
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"> <?php the_title(); ?></a>
</p>
</div>
</div>
<?php endwhile;endif;?>
</div>
<?php
return ob_get_clean();
}
add_shortcode('recommend','shortcode_recommend');
ob_startはPHPマニュアルによると以下のように記載されています。
ob_start — 出力のバッファリングを有効にする
バッファリングを有効にすると言われてもよく分かりませんが要はすぐに表示させずに一時的に保存しているというイメージです。
ただ、ob_startは保存するだけで出力されないのでob_get_cleanで出力します。
ob_get_clean — 現在のバッファの内容を取得し、出力バッファを削除する
このような処理をアウトプットバッファリングというそうです。
まとめ
ワードプレスの内部処理の順番によるものだと思いますが、正常に表示されていなかったコードではショートコードの方が先にHTMLとして出力され、その後、h2タグが出力されたためにレイアウトがおかしなことになったようです。