web-dev-qa-db-ja.com

ハートビートAPIの実装

デフォルトでは、the_contentフィルタを介してコンテンツを実行すると、oEmbedコンテンツが自動的にチェックされます。しかしheartbeat_receivedを通してデータを返すとき、oEmbedのためのフィルタはうまくいかないようです。

例えば ​​-

function test_heartbeat_received( $response, $data ) {
    if( $data['test_heartbeat'] == 'test' ) {
        $content = "https://Twitter.com/WordPress/status/456502643738030080";

        // Doesn't work
        global $wp_embed;
        $content = $wp_embed->autoembed( $content );
        $response['test_heartbeat'] = $content;

        // Also doesn't work
        $response['test_heartbeat'] = apply_filters( 'the_content', $content );
    }
    return $response;
}
add_filter( 'heartbeat_received', 'test_heartbeat_received', 10, 2 );
add_filter( 'heartbeat_nopriv_received', 'test_heartbeat_received', 10, 2 );

Heartbeatを使わずにまったく同じことをするのはうまくいくようです。コンテンツフィルタは、oEmbedなしで、フォーマットが存在するときに適用されています。

助言がありますか?

ありがとうございます。

4
Elliott

問題:

これがうまくいかない理由は、WP_Embed::shortcode()メソッドのこの部分です:

 if( $post_ID ) {
    .... cut ...

    // Use oEmbed to get the HTML
    $html = wp_oembed_get( $url, $attr );

    ... cut ...
 }

Heartbeat APIで自動実装しようとすると、$post_IDnullなので、wp_oembed_get()はアクティブになりません。

キャッシングなし:

投稿エディタでTwitterリンクを自動設定すると、指定された$post_IDに対して、埋め込まれたHTMLが投稿メタテーブルの次のようなキーの下にキャッシュされます。_oembed_7bc759c5dcea2e4b77c939fc109996fbと次のような値。

<blockquote class="Twitter-Tweet" width="550">
   <p>
      WordPress 3.9 “Smith” is now available with a smoother media editing experience, 
      live widget previews, and more: 
      <a href="http://t.co/mEbgUFdpyG">http://t.co/mEbgUFdpyG</a>
   </p>
   &mdash; WordPress (@WordPress) 
   <a href="https://Twitter.com/WordPress/statuses/456502643738030080">April 16, 2014</a>  
</blockquote>
<script async src="//platform.Twitter.com/widgets.js" charset="utf-8"></script>

各埋め込みリンクは、それがデフォルトの埋め込みハンドラの一部ではない場合でも、postメタテーブル内の独自の行を取得します。

$post_IDがない場合は、このキャッシュメカニズムはスキップされます。そのため、セットアップ用にキャッシュを検討することをお勧めします。

考えられる回避策:

i)あなたの文字列の中で、'|^\s*(https?://[^\s"]+)\s*$|im'の全てのマッチを取り、それをwp_oembed_get()関数を通して実行し、元の文字列からのリンクを置き換える必要があります。

ii)test_heartbeat_receivedコールバック内で、それを特定の投稿に関連付けることもできます。

global $wp_embed, $post;
$post = get_post( 3147 ); // Post ID: 3147

$content = $wp_embed->autoembed( $content );
$response['test_heartbeat'] = $content;

不足している$post_ID部分を回避し、その投稿にデフォルトのキャッシュを使用する。その投稿を更新すると、埋め込みキャッシュがクリアされることを忘れないでください。

たとえば、上の方法で2つのTwitterリンクを試してみます。

$content = "
    <div>
        https://Twitter.com/WordPress/status/456502643738030080
    </div>
    <div> 
        https://Twitter.com/WordPress/status/459387231870799872 
    </div>
    ";

自動アセンブル処理が終わると、postメタテーブルにpost_id: 3147に割り当てられた2つの行が表示されます。

oembed rows

5
birgire
function test_heartbeat_received( $response, $data ) {
    if( $data['test_heartbeat'] == 'test' ) {
        $embed_code = wp_oembed_get('https://Twitter.com/WordPress/status/456502643738030080');
        $response['test_heartbeat'] = apply_filters( 'the_content', $embed_code );
    }
    return $response;
}
add_filter( 'heartbeat_received', 'test_heartbeat_received', 10, 2 );
add_filter( 'heartbeat_nopriv_received', 'test_heartbeat_received', 10, 2 );

これを追加した後にも試すことができます(混合コンテンツの場合)。

http://wpengineer.com/2487/disable-oembed-wordpress/

function div_wrapper($content) {
     // match any iframes
        $pattern = '~<iframe.*</iframe>|<embed.*</embed>~';
        preg_match_all($pattern, $content, $matches);

        foreach ($matches[0] as $match) {
            // wrap matched iframe with div
            $wrappedframe = apply_filters( 'the_content', $match );    
            //replace original iframe with new in content
            $content = str_replace($match, $wrappedframe, $content);
        }

        return $content;    
    }
    add_filter('the_content', 'div_wrapper');
0
ravi patel