【WordPress】query_postsでループ中の記事の画像やYoutubeサムネイルを表示

2014.4.23 Wordpress

wordpressでyoutubeサムネイルを取得

今、担当しているwordpressの案件で、
投稿記事をループしたところにYoutubeのサムネイルを出せないかな…と考えていましたが、やはり、できます!

それもかなり簡単に。メモ書きとして記していきます。

 

Youtubeのサムネイルにもアドレスがある

まずは取得すべきサムネイル画像のURLを知るところからでした。

http://i.ytimg.com/vi/動画のID/取得したいサムネイル番号.jpg

上記、オレンジ色になっている部分の「動画のID」を取得することを目標とします。

動画IDとは、

<iframe width=”560″ height=”315″ src=”//www.youtube.com/embed/【ここ】” frameborder=”0″ allowfullscreen></iframe>

Youtubeで「埋め込みコード」を取得して、この辺りにある半角英数字の羅列のことを言います
では、サムネイル番号とは。

以下の4種類のパターンから選べます。

  • 0.jpg (340px × 240px)
  • default.jpg (120px × 90px)
  • 1.jpg (120px × 90px)
  • 2.jpg (120px × 90px)
  • 3.jpg (120px × 90px)

サイズdefault~3までサイズが変わりませんが、各IDを取得してみたところ…
「3」と、その他のURLで、微妙に動画サムネイルの縮尺が違う程度でした。(たぶん気のせい)

 

ループ内で投稿記事のYoutubeサムネイルを取得

<?php
$youtubePost = esc_attr(get_the_content());
// ↑get_the_content()で投稿記事のデータを取得し $youtubePost へ入れる

preg_match('/www.youtube.[-_\/A-Za-z0-9]*/', $youtubePost, $youtubeUrl);
// ↑ $youtubePost の中の ”www.youtube”の後に続く文字列が、
// 英数字と-(ハイフン)、_(アンダーバー)を含む部分を抜き取って $youtubeUrl (配列)へ入れる。

$youtubeId = str_replace("www.youtube.com/embed/","",$youtubeUrl[0]);
// ↑ $youtubeUrlの1つ目のデータ(YouTubeのアドレスが入ってる)から
// "www.youtube.com/embed/"の部分を取り除き、IDのみを残して $youtubeId に入れる。
?>

get_the_contentで、ループ中の、出力した投稿のそれぞれの情報を取得していきます。
それを$youtubePostに代入。あとで使います。
get_the_content:WordPress私的マニュアル

preg_match$youtbePostを検索。get_the_contentsで取得した投稿情報のどこかで
/www.youtube.[-_\/A-Za-z0-9]*/」がヒットし、$youtubeUrlへ検索結果を代入します。

/www.youtube.[-_\/A-Za-z0-9]*/は正規表現で、www.youtube.のあとに半角英数字が数回続いているかどうか…という意味です。
preg_match – 正規表現によるマッチングを行う

次に、その$youtubeUrlの中の、「www.youtube.com/embed/」を「””」つまり空白に置換するのがstr_replaceです。
str_replace(“2:これを” , “3:これに入れ替える” , “1:この中の” )
といった感じで、言葉にして覚えればいいかな、と思います…

 

YoutubeIDを使ってサムネイルを表示

さて、では上記の$youtubeIdを使ってサムネイルを表示します。
必要に応じて get_permalink();なんかで記事へのリンクを付加しつつ、ループ内に下記のように記述します。

<?php
echo "<a href='" .esc_url(get_permalink()). "' >";
echo "<img class='y_thumbnail' src='http://img.youtube.com/vi/$youtubeId/0.jpg'></a>"  ;
?>

先ほどの$youtubeIdが、動画のIDとして必要な部分に入れてあります。
そのあとの「0.jpg」は必要に応じて「1.jpg」だったり、変えて出力していただければいいかと思います。

さらに、もしYoutubeサムネイルが取得できなかった場合に、記事中の画像を表示する…という、これでもか、的なループを作成したいと思います。
使うのはquery_postsです。サブループに出力したい場合はget_postsなどで置き換えてください。

僕はget_postsの使い方がヘタで、記事中の投稿画像のURLが取得できず、泣く泣くquery_postsにしました。
方法を知っている方はsatohmsysまでお願い致します…

ちなみに僕の場合は、
新着情報用カスタム投稿、更新した投稿を全部まとめて時間軸に並べたものを「新着情報」として、
TOPページに表示したかったので実装しました。

<ul>
<?php
  $Args = array(
  'post_type' => array('取得したい投稿タイプ' , '取得したい投稿タイプ'),
  'posts_per_page' => 10 ,
  'order_by' => 'modified' //更新日時を基準に取得
)
 query_posts($Args);    
    if(have_posts()): while(have_posts()): the_post();    

     $youtubePost = esc_attr(get_the_content());              
     preg_match('/www.youtube.[-_\/A-Za-z0-9]*/', $youtubePost , $youtubeUrl);              
     $youtubeId = str_replace("www.youtube.com/embed/" , "" , $youtubeUrl[0]);

 ?>

<a href="<?php the_permalink(); ?>">
    <li>
      <?php
        $imgset = array(
         'post_type' => 'attachment' ,
         'post_mine_type' => 'image' ,
         'post_parent' => $post -> ID ,
          'numberposts' => 1
          );
          $images = get_children($imgset);//$imgsetでループ出力中の投稿情報を取得
          $image = array_shift($images); //配列の先頭から1つPick

           if($image){//投稿から画像抽出
             echo wp_get_attachment_image($image->ID , 'thumbnail');//アタッチメント情報のHTMLテキストをthumbnailサイズで取得する
             } elseif($youtubeId){
                  echo "<img class='y_thumbnail' src='http://img.youtube.com/vi/$youtubeId/0.jpg'>";
               } else{//デフォルトのNoimage画像出力
                    echo '<img src="' .
                    get_bloginfo('template_url') .
                    '/img/post_thumbnail/eyecatch' .
                      rand(1 , 8) .
                      '.png" alt="" class="newmov-thumb" />';
                  }

      ?>
    <div class="newmov-data_wrap">
       <div>
         <h2>
            <?php //投稿のカスタムタクソノミ(menu)
             $terms = get_the_terms( get_the_ID(), 'menu' );
              if ( !empty($terms) ) {
               if ( !is_wp_error( $terms ) ) {
                 foreach( $terms as $term ) {
                   echo '<span class="mov-menu">' . $term->name . '</span>';//$term->nameでタクソノミ名出力
                 }
               }
            }
            ;?>

             <span><?php the_title(); ?></span>
          </h2>
        </div>

       <?php the_excerpt(); ?>

     </div>
   </li>
 </a>

<?php endwhile; endif; wp_reset_query();?>
</ul>

3行目ぐらいの$Argsが、その直後のquery_postsのループの条件を指定しています。
今回は<li>タグをまるごと<a>で囲ってしまっています。

そのあとに登場する$imgsetは、get_childrenで取得したい情報を指定します。画像を取得する指定です。
get_children:WordPress私的マニュアル – Elearn.jp

配列で取得できるので、一番最初の値である投稿IDを呼び出すためにarray_shiftで抽出。
それを元にwp_get_attachment_image($image->ID , ‘thumbnail’)で、出力中の投稿の画像を取得します。
まるで食物連鎖のようです…
wp_get_attachment_image:WordPress私的マニュアル

ここはif($image)で条件分岐。投稿中の画像が取得できたら出力。
できなかったら、elseif($youtubeId)~の処理(Youtubeサムネイルを出力)

もしそれも取得できないならelse{}内の処理で、デフォルトの「No Image」イメージを出力…といった形です。
最後のelse{}内の処理は、カスタマイズしているテーマの都合で、「No Image」イメージが数カラー存在するため、
ランダムで出力するためにrand (1 , 8) と記述しています。ここはどうでもいいです。

 

 

いかがでしたでしょうか?
ちょうど探していたものが見つかるとは、こうもキモチの良いものなんですよね~

Youtubeサムネイル取得は、functions.phpに記述して関数にしてしまっても楽です。
頻繁に使うなら関数にすべきですね!

今回の参考記事はこちらです WordPressでiframeで埋め込んだYouTube動画のサムネイルを取得して表示する | memocarilog

 

でわ!

プロフィール

東京でWebデザイナー・コーダーとして、フロントエンド的なことからグラフィックデザイン的なことをして、ごにょごにょと小さく活動中。Webクリエイターでは珍しい(?) HIPHOP, R&B好き。休日はよくカフェや漫画喫茶に出向いたりパン屋に行ったり、主に散歩しています。だいたいラーメンを食べて帰ってくる、そんな過ごし方です(都内のオススメ散歩コース募集中!)。デザインのトレンドやデザイン思考、HTML、CSSからSASS、Javascript、Wordpress構築などコーディングのTIPSなどをブログにアップしていきます。その他のことはtwitter( @satohmsys )まで。