web-dev-qa-db-ja.com

[caption]内のネストされたショートコードが処理されない

ワードプレスのキャプションは現時点ではネストされたショートコードをサポートしていません(v3.6)。だから、私が書いたら

[caption]<img src=""> I love my [city][/caption]

市は処理されることになっているが、処理されていない場所。 どうすれば解決できますか?

チケット: #24990

2
Sisir

キャプションのショートコードの内側に フックがあります それによってあなたは全部をハイジャックすることができます。以下のほとんどは、コアのimg_caption_shortcode関数からコピーされたものです。

function nested_img_caption_shortcode($nada, $attr, $content = null) {

  extract(
    shortcode_atts(
      array(
      'id'    => '',
      'align' => 'alignnone',
      'width' => '',
      'caption' => ''
      ), 
      $attr, 
      'caption'
    )
  );

  $caption = do_shortcode($caption); // process nested shortcodes

  if ( 1 > (int) $width || empty($caption) )
          return $content;

  if ( $id ) $id = 'id="' . esc_attr($id) . '" ';

  return '<div ' . $id . 'class="wp-caption ' . esc_attr($align) . '" style="width: ' . (10 + (int) $width) . 'px">'
  . do_shortcode( $content ) . '<p class="wp-caption-text">' . $caption . '</p></div>';
}
add_filter('img_caption_shortcode', 'nested_img_caption_shortcode', 1, 3);
3
s_ha_dum

最新バージョンのWPは、キャプション引数のフィルタ処理性を本当に向上させているので、この新しい回答は最小のフットプリントと最も安全な操作になると思います。

私たちがする必要があるのは$atts['caption']ショートコードのためにshortcode_atts()の間に直接[caption]をフィルタリングすることです。キャプションのショートコードにのみ影響するshortcode_atts_captionフィルタを使ってこれを行うことができます。

おまけとして、私はdo_shortcode()を実行する前に特定のショートコードのキャプションをテストするコメントアウト行を追加しました。これは、キャプションで特定のショートコードのみを有効にしたい場合に便利です(私は ショートコードショートコード のみを有効にするためにそれを使用します)。ただし注意してください。do_shortcode()はあなたがテストしたものだけでなく、すべてのショートコードを処理します。

/**
 * Filter Caption shortcode attributes to enable the [shortcode] shortcode inside caption text
 * 
 * WP doesn't run do_shortcode on the 'caption' text value parsed out of [caption], which means
 * the [shortcode] shortcode doesn't work. 
 * 
 * @param array $out atts array as determined by WP to be returned after filtering
 * @param array $pairs 
 * @param array $atts
 * @return filtered $out atts
 */
 function wpse_113416_filter_shortcode_atts_caption($out, $pairs, $atts) {
    // OPTIONAL: Look for a specific shortcode before running do_shortcode
    // if (has_shortcode($out['caption'], 'shortcode_to_look_for')) 
        $out['caption'] = do_shortcode($out['caption']);

    return $out;
}
add_filter('shortcode_atts_caption', 'wpse_113416_filter_shortcode_atts_caption', 10, 3);
3
jerclarke

v3.6に導入された最新の関数has_shortcode()を使用する

add_filter( 'the_content', 'process_wp_caption_shortcodes' ); // hook it late

    function process_wp_caption_shortcodes( $content ){
        if( !function_exists    ( 'has_shortcode' ) )   // no luck for user using older versions :)
            return $content;

        if( has_shortcode( get_the_content(), 'caption' ) ){ // check with raw content
            // caption exists on the current post
            $content = do_shortcode( $content );
        }

        return $content;
    }

このソリューションは、ネストされたショートコードサポートを実装していないサードパーティのショットコードでも使用できます。

より良い解決策があれば歓迎しました!

2
Sisir