WordPress Logo WordPress で Bootstrap 4 のカルーセルを使う

WordPress で Bootstrap 4 のカルーセルを使って、投稿に表示してある画像や images フォルダの画像、一覧ページのアイキャッチ画像をスライドショーのように表示することができます。

プラグインなどを使わずに簡単なスライドショー(カルーセル)を表示する方法についての覚え書きです。

編集画面で Bootstrap の HTML を直接記述する方法もありますが、デフォルトの編集画面のコードエディターでは色々と面倒です。

ここで掲載している実装方法は、大きく分けると JavaScript(jQuery)を使う方法と WordPress のテンプレートタグと PHP を使う方法の2種類です。

ショートコードを利用する方法を追加しました。2019年06月05日

また、WordPress で Bootstrap 4 のモーダルを使ったライトボックスの実装方法については「Bootstrap4 の使い方(4) WordPress で Lightbox」をご覧ください。

更新日:2019年06月12日

作成日:2019年05月29日

Bootstrap の読み込み

WordPress で Bootstrap 4 を使うには Bootstrap の JavaScript と CSS を読み込む必要があります。以下は functions.php で Bootstrap の JavaScript と CSS を読み込む例です。

function add_my_styles_and_scripts() {
  //bootstrap.min.css の読み込み
  wp_enqueue_style( 
    'my-template-bs-style', 
    '//stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css' ,
    array(),
    '4.1.3'
  );
  
  //スタイルシート style.css の読み込み
  wp_enqueue_style(
    'my-template-style',
    get_stylesheet_uri(),
    array('my-template-bs-style'),
    filemtime( get_theme_file_path( '/style.css' ) )
  );  

  //WordPress 本体の jQuery を登録解除
  wp_deregister_script( 'jquery');  
  
  //jQuery を CDN から読み込む
  wp_enqueue_script( 'jquery', 
    '//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js', 
    array(), 
    '3.3.1', 
    true //</body> 終了タグの前で読み込み
  );
  
  // Bootstrap の依存ファイル popper.min.js の読み込み
  wp_enqueue_script( 'popper', 
    '//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js', 
    array('jquery'), 
    '1.14.3', 
    true 
  );
  
  // Bootstrap JavaScript の読み込み 
  wp_enqueue_script( 'bootstrap', 
    '//stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js', 
    array('jquery', 'popper'), 
    '4.1.3', 
    true 
  );
  
  // base.js の読み込み(独自の JS ファイル) 
  wp_enqueue_script( 
    'base-script', 
    get_theme_file_uri( '/js/base.js' ), 
    array( 'jquery', 'bootstrap' ), 
    filemtime( get_theme_file_path( '/js/base.js' ) ), 
    true
  );
}
add_action( 'wp_enqueue_scripts', 'add_my_styles_and_scripts' );

Bootstrap4 の読み込み方法やWordPress での CSS や JavaScript ファイルの読み込み方法については以下をご覧ください。

編集画面で記述

以下のように Bootstrap のカルーセルの構造の HTML をコードエディターに直接記述することもできますが、場合によっては自動的に改行部分に p 要素が挿入されたりするなど扱いにくいのと毎回これらを記述するのも面倒です。

<div id="carouselx" class="carousel slide" data-ride="carousel"> 
  <ol class="carousel-indicators">
    <li data-target="#carouselx" data-slide-to="0" class="active"></li>
    <li data-target="#carouselx" data-slide-to="1"></li>
    <li data-target="#carouselx" data-slide-to="2"></li>
  </ol>
  <div class="carousel-inner">
    <div class="carousel-item active">
      <div class="carousel-caption d-none d-md-block">
        <h5>Caption Title1</h5>
        <p>Caption1</p>
      </div>
      <img src="http://localhost/wp5/wp-content/uploads/2019/05/sample01.jpg" alt="..."> 
    </div>
    <div class="carousel-item">
      <div class="carousel-caption d-none d-md-block">
        <h5>Caption Title2</h5>
        <p>Caption2</p>
      </div>
      <img src="http://localhost/wp5/wp-content/uploads/2019/05/sample02.jpg" alt="..."> 
    </div>
    <div class="carousel-item"> 
      <div class="carousel-caption d-none d-md-block">
        <h5>Caption Title3</h5>
        <p>Caption3</p>
      </div>
      <img src="http://localhost/wp5/wp-content/uploads/2019/01/sample03.jpg" alt="...">
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselx" role="button" data-slide="prev"> 
    <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="sr-only">前へ</span> 
  </a> 
  <a class="carousel-control-next" href="#carouselx" role="button" data-slide="next"> 
    <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="sr-only">次へ</span> 
  </a> 
</div>

編集画面で任意の位置にカルーセルを表示するには独自のショートコードを作成します。「ショートコードを利用」をご覧ください。

JavaScript での実装

JavaScript(jQuery)を使って投稿に挿入された画像を表示する方法です。

投稿に挿入された画像を正規表現で検索してそれらを全て表示する方法と、挿入された画像のリンクにクラスを指定してクラスが指定されてある画像のみを表示する方法が考えられます(他にもあるかと思います)。

クラスが指定されている画像を表示

この方法の場合、編集画面で画像を選択し「リンク設定」の「リンク先」で「メディアファイル」を選択し、「リンク CSS クラス」に任意のクラス名(この例では crsl)を指定する必要があります。

この指定したクラス名を元に JavaScript で画像を表示するかを判定します。

「リンク先」に「メディアファイル」を指定することで画像(img)要素にその元の画像へのリンクが設定されるので、リンクから画像の URL を取得することができます。

この方法では、カルーセルで表示する画像はアップロードしたオリジナルの画像になります(正規表現を使うなどして画像名の最後にサイズを指定すれば、他のイメージサイズの画像も表示できると思います)。

投稿編集画面で画像にリンク設定をする際のスクリーンショット

また、個別ページのテンプレートファイル(single.php など)にカルーセルを表示する位置を指定するために div 要素などを記述して id を指定しておきます。

この id を指定した要素に JavaScript でカルーセルの HTML を挿入します。

<div id="main">
  <h2>個別ページ(Single.php)</h2>
  <div id="carousel_position"></div><!-- カルーセルを挿入する要素 -->
  <section>
    <?php if(have_posts()) : ?>
    <?php while(have_posts()) : the_post(); ?>
    <div <?php post_class(); ?>>
      <h3><?php the_title(); ?></h3>
      <?php the_content(); ?>
    </div>
    <?php endwhile; ?>
    <?php endif; ?>
  </section>
</div> <!-- end of #main -->

以下を JavaScript のファイルに記述します。

crsl クラスを指定した画像が2つ以上ある場合にカルーセルで表示するようにしています。

内容は画像へ設定したリンクから画像の URL を取得し(キャプションを表示する場合は画像要素の alt 属性を取得)、カルーセルの HTML を生成しています。

15行目のカルーセルの HTML の最初の div 要素には data-ride="carousel" は指定せず最後にカルーセルを初期化しています。

コントロールやインディケータを表示しない場合は、6~8行目で false を指定します。

また、表示する画像要素(img)のクラスは class="d-block w-100" としていますが、画像のサイズ等により必要に応じて12行目の img_class の値を変更します。

$(function () {
  //Carousel 
  var carousel_class = '.crsl';  //「リンク CSS クラス」で指定したクラス
  if($(carousel_class).length > 1 ) { //.crsl を指定した要素が2つ以上ある場合以下を実行
    var img_count = $(carousel_class).length; //画像の数
    var show_control = true; //コントロールを表示(しない場合は false を指定)
    var show_indicators = true; //インディケータを表示(しない場合は false を指定)
    var show_caption = true; //キャプションを表示(しない場合は false を指定)
     
    var target_id = 'carousel_position';  //カルーセルを挿入する要素の ID
    var carousel_id = 'carouselExample'; //カルーセルの最も外側の div 要素の ID
    var img_class = 'd-block w-100'; //表示する画像のクラス(class 属性)の値
    
    //カルーセルの HTML の冒頭部分
    var carousel_html_prepend = '<div id="' + carousel_id + '" class="carousel slide"><div class="carousel-inner">';
    //コントロールの HTML
    var control = '<a class="carousel-control-prev" href="#' + carousel_id + '" role="button" data-slide="prev"><span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span></a><a class="carousel-control-next" href="#' + carousel_id + '" role="button" data-slide="next"><span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span></a>';
    //インディケータの HTML
    var indicators = '<ol class="carousel-indicators"><li data-target="#' + carousel_id + '" data-slide-to="0" class="active"></li>';
    for (var i = 0; i < img_count-1 ; i++) {
      indicators += '<li data-target="#' + carousel_id + '" data-slide-to="' + (i + 1) + '"></li>';
      if (i === img_count -2) {
        indicators += '</ol>';
      }
    }
    
    //それぞれの画像要素をカルーセルの HTML に追加
    $(carousel_class).each(function(n) {
      var active = n ===0 ? ' active' : '';
      var caption = '';
      if(show_caption) {
        caption = '<div class="carousel-caption d-none d-md-block"><p>' +  $(this).find('img').attr('alt') + ' </p></div>';
        carousel_html_prepend += '<div class="carousel-item' + active + '"><img class="' + img_class + '" src="' + $(this).attr('href') + '" alt="">' + caption + '</div>';
      } else {
        carousel_html_prepend += '<div class="carousel-item' + active + '"><img class="' + img_class + '" src="' + $(this).attr('href') + '" alt=""></div>';
      }
    });
    
    //カルーセルの HTML の最後に追加する部分ににコントロールやインディケータを追加
    var carousel_html_append = '</div>' + (show_control ? control : '')  +  (show_indicators ? indicators : '') + '</div>';
    //カルーセルの HTML 
    var carousel = carousel_html_prepend + carousel_html_append;
  
    //カルーセルをページへ挿入
    $('#' + target_id).prepend(carousel);
    //カルーセルを初期化して実行
    $('.carousel').carousel();
  }
});   

上記の jQuery の記述により、例えば挿入した3つの画像のリンクに crsl クラスを指定した場合、以下のような HTML が出力されます。

<div id="carouselExample" class="carousel slide">
  <div class="carousel-inner">
    <div class="carousel-item active"><img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/West-Side-Rail-Yard.jpg" alt="">
      <div class="carousel-caption d-none d-md-block">
        <p>画像の alt 属性の値</p>
      </div>
    </div>
    <div class="carousel-item"><img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/Manhattan-Bridge.jpg" alt="">
      <div class="carousel-caption d-none d-md-block">
        <p>画像の alt 属性の値</p>
      </div>
    </div>
    <div class="carousel-item"><img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/White-Rose.jpg" alt="">
      <div class="carousel-caption d-none d-md-block">
        <p>画像の alt 属性の値</p>
      </div>
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselExample" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span>
  </a>
  <a class="carousel-control-next" href="#carouselExample" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span>
  </a>
  <ol class="carousel-indicators">
    <li data-target="#carouselExample" data-slide-to="0" class="active"></li>
    <li data-target="#carouselExample" data-slide-to="1" class=""></li>
    <li data-target="#carouselExample" data-slide-to="2" class=""></li>
  </ol>
</div>

投稿に挿入されている全ての画像を表示

以下は指定された領域から投稿に挿入されている画像を正規表現で検索して表示する方法です。

この場合、画像にリンクを設定する必要はありませんが、挿入されている画像は全て表示されます。

但し、カルーセルに表示される画像は編集画面で指定したサイズの画像になります。

投稿編集画面で画像にサイズを設定する際のスクリーンショット

また、画像を検索する領域を指定する必要があります。body 全てを対象にすると意図しない画像も表示される可能性があるので、コンテンツ部分の要素の id を指定します。

以下は single.php の一部ですが、この例の場合は id が main の div 要素を対象にしています。

必要に応じて検索対象の id を変更します。

<div id="main"><!-- この要素内を検索対象 -->
  <h2>個別ページ(Single.php)</h2>
  <div id="carousel_position"></div>
  <section>
    <?php if(have_posts()) : ?>
    <?php while(have_posts()) : the_post(); ?>
    <div <?php post_class(); ?>>
      <h3><?php the_title(); ?></h3>
      <?php the_content(); ?>
    </div>
    <?php endwhile; ?>
    <?php endif; ?>
  </section>
</div> <!-- end of #main -->

内容的には前述の例とほぼ同じですが、最初に検索対象の領域から全ての img 要素を取得し、それらのうち src 属性の値に「/wp-content/uploads/」が含まれるものを search() を使って抽出しています。

そして対象とする画像が2つ以上ある場合にカルーセルを表示するようにしています。

異なる点は表示対象の画像要素の jQuery オブジェクトを取得後、それらを配列(target_images)に格納しているため、前述の例では jQuery の each() が使えましたが以下の例では for 文で処理しています。

$(function () {
  var target_element = '#main';  //画像を検索する対象の要素の ID に # を付けた値
  var images_found = $(target_element).find('img'); //見つかった画像要素
  var target_images = []; //対象とする画像を格納する配列の初期化
  //見つかった画像がアップロードフォルダのものかを判定してその場合は対象とする
  images_found.each(function() {
    var src = $(this).attr('src');
    //search() はマッチングがなければ-1を返す
    if(src.search('/wp-content\/uploads/') !== -1){
      target_images.push($(this));
    }
  });
  
  var target_images_count = target_images.length; //対象とする画像の数
  
  if(target_images_count > 1 ) { //対象とする画像が2つ以上ある場合以下を実行
    var show_control = true; //コントロールを表示(しない場合は false を指定)
    var show_indicators = true; //インディケータを表示(しない場合は false を指定)
    var show_caption = true; //キャプションを表示する(しない場合は false を指定)
     
    var target_id = 'carousel_position';  //カルーセルを挿入する要素の ID
    var carousel_id = 'carouselExample2'; //カルーセルの最も外側の div 要素の ID
    var img_class = 'd-block w-100'; //表示する画像のクラス(class 属性)の値
    
    //カルーセルの HTML の冒頭部分(jQuery で追加するので data-ride="carousel" は指定せず JavaScript でカルーセルを最後に初期化)
    var carousel_html_prepend = '<div id="' + carousel_id + '" class="carousel slide"><div class="carousel-inner">';
    //コントロールの HTML
    var control = '<a class="carousel-control-prev" href="#' + carousel_id + '" role="button" data-slide="prev"><span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span></a><a class="carousel-control-next" href="#' + carousel_id + '" role="button" data-slide="next"><span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span></a>';
    //インディケータの HTML
    var indicators = '<ol class="carousel-indicators"><li data-target="#' + carousel_id + '" data-slide-to="0" class="active"></li>';
    for (var i = 0; i < target_images_count-1 ; i++) {
      indicators += '<li data-target="#' + carousel_id + '" data-slide-to="' + (i + 1) + '"></li>';
      if (i === target_images_count -2) {
        indicators += '</ol>';
      }
    }
    
    //それぞれの画像要素をカルーセルの HTML に追加
    for (var j = 0; j < target_images_count ; j++) {
      var active = j ===0 ? ' active' : '';
      var caption = '';
      if(show_caption) {
        caption = '<div class="carousel-caption d-none d-md-block"><p>' + target_images[j].attr('alt') + ' </p></div>';
        carousel_html_prepend += '<div class="carousel-item' + active + '"><img class="' + img_class + '" src="' +  target_images[j].attr('src') + '" alt="">' + caption + '</div>';
      } else {
        carousel_html_prepend += '<div class="carousel-item' + active + '"><img class="' + img_class + '" src="' +  target_images[j].attr('src') + '" alt=""></div>';
      }
    }
    
    //カルーセルの HTML の最後に追加する部分ににコントロールやインディケータを追加
    var carousel_html_append = '</div>' + (show_control ? control : '')  +  (show_indicators ? indicators : '') + '</div>';
    //カルーセルの HTML 
    var carousel = carousel_html_prepend + carousel_html_append;
    //alert(carousel);
  
    //カルーセルをページへ挿入
    $('#' + target_id).prepend(carousel);
    //カルーセルを初期化して実行
    $('.carousel').carousel();
  }
});

上記の jQuery の記述により、例えば以下のような HTML が出力されます。

<div id="carouselExample2" class="carousel slide">
  <div class="carousel-inner">
    <div class="carousel-item active"><img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/Yellow-Flower-and-Bee-1024x683.jpg" alt="">
      <div class="carousel-caption d-none d-md-block">
        <p>画像の alt 属性の値</p>
      </div>
    </div>
    <div class="carousel-item"><img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/Sea-Plane-and-Ferry-1-1024x683.jpg" alt="">
      <div class="carousel-caption d-none d-md-block">
        <p>画像の alt 属性の値</p>
      </div>
    </div>
    <div class="carousel-item"><img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/Midtown-building-wall-painting-1024x683.jpg" alt="">
      <div class="carousel-caption d-none d-md-block">
        <p>画像の alt 属性の値</p>
      </div>
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselExample2" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span>
  </a>
  <a class="carousel-control-next" href="#carouselExample2" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span>
  </a>
  <ol class="carousel-indicators">
    <li data-target="#carouselExample2" data-slide-to="0" class="active"></li>
    <li data-target="#carouselExample2" data-slide-to="1" class=""></li>
    <li data-target="#carouselExample2" data-slide-to="2" class=""></li>
  </ol>
</div>

PHP での実装

以下は PHP や WordPress の関数を使ってカルーセルで画像を表示する方法です。

JavaScript の場合のように挿入した画像のリンクにクラスを指定して表示を制御することはできませんが色々な方法があります(もっと効率の良い方法があるかも知れません)。

アップロードした画像を表示

投稿の個別ページなどのテンプレートで、get_children() を使ってそのページでアップロードした全ての画像を取得してカルーセルで表示する方法です。

記事に挿入(表示)していない画像でも、そのページでアップロードした画像は全て取得されます。逆に他のページでアップロードした画像を記事に表示している場合は、その画像は取得されません。

get_children() に以下のようなパラメータを指定して、そのページでアップロードした画像のオブジェクトの配列を取得し、foreach で1つずつ処理して wp_get_attachment_image_src() を使って画像の URL を取得します。

$args = array(  //現在の投稿の画像の添付ファイルを取得
  'post_parent' => get_the_ID(),  //現在の投稿
  'post_type' => 'attachment',  //添付ファイル
  'post_mime_type' => 'image',  //画像
  //'exclude' => get_post_thumbnail_id()  //アイキャッチ画像を除外する場合
);
$images = get_children($args);  //添付ファイル画像のオブジェクトを取得

取得する画像のサイズは wp_get_attachment_image_src() の第2パラメータにイメージサイズのキーワード('full' や 'large' など)を指定します(11行目で変更)。

取得して表示する画像のサイズにより img 要素に指定してある幅のクラス w-100 を変更したり適宜スタイルを変更する必要があるかも知れません(12行目で変更)。

また、carousel-item クラスの div 要素の1つには必ず active クラスを指定する必要があるので、以下の例では最初の画像に active クラスを指定しています。

この例では foreach を使っているので $counter と言う変数を使って最初の画像を判定していますが、他の例では for 文のカウンター変数で判定したりしています。

個別ページのテンプレート(single.php など)のカルーセルを表示したい箇所に以下を記述します。

アイキャッチ画像を取得する画像の対象から除外する場合は、7行目のコメントを外します。

<?php
//そのページでアップロードした画像を取得する例
$args = array(  //現在の投稿の画像の添付ファイルを取得
  'post_parent' => get_the_ID(),  //現在の投稿
  'post_type' => 'attachment',  //添付ファイル
  'post_mime_type' => 'image',  //画像
  //'exclude' => get_post_thumbnail_id()  //アイキャッチ画像を除外する場合
);
$images = get_children($args);  //添付ファイル画像のオブジェクトを取得 
  
$size  = 'large'; //イメージサイズ
$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID
 
if($images) {
   //カルーセルの HTML を出力
   echo '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<div class="carousel-inner">'. "\n" ; 
  $counter = 0;
  foreach($images as $image) {  //画像が取得できていれば以下を実行
    $src = esc_url(wp_get_attachment_image_src( $image->ID, $size )[0]); //URLを取得
    //最初の要素には active クラスを指定
    ($counter === 0) ? $active = ' active' : $active = '';
    echo '<div class="carousel-item'. $active .'">'. "\n" .
         '<img class="'. $img_class .'" src="'. $src . '" alt="">'. "\n</div>" ; 
    $counter ++;
  }
  echo '</div>'. "\n" .'</div>'. "\n" ; 
}  
?>

上記の例ではカルーセルの HTML を echo で出力していますが、以下は HTML を直接記述する例です。

どちらでも同じ表示結果になります。

<?php
//そのページでアップロードした画像を取得する例
$args = array(  //現在の投稿の画像の添付ファイルを取得
  'post_parent' => get_the_ID(),  //現在の投稿
  'post_type' => 'attachment',  //添付ファイル
  'post_mime_type' => 'image',  //画像
  //'exclude' => get_post_thumbnail_id()  //アイキャッチ画像を除外する場合
);
$images = get_children($args);  //画像のオブジェクトを取得  

$size  = 'large'; //イメージサイズ
$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID

if($images) : 
$counter = 0;
?>
<div id="<?php echo $carousel_id; ?>" class="carousel slide" data-ride="carousel"> 
  <div class="carousel-inner">
  <?php
  foreach($images as $image) {  //画像が取得できていれば以下を実行
    $src = esc_url(wp_get_attachment_image_src( $image->ID, $size )[0]); //URLを取得
    //最初の要素には active クラスを指定
    ($counter === 0) ? $active = ' active' : $active = '';
  ?>
  <div class="carousel-item<?php echo $active; ?>">
    <img class="<?php echo $img_class; ?>" src="<?php echo $src; ?>" alt="">
  </div>
  <?php 
  $counter ++;
  } endif;
  ?>
  </div>
</div>

コンテンツの画像を表示

投稿の個別ページなどのテンプレートで、そのページで表示(挿入)されている全ての画像を投稿オブジェクトの post_content プロパティから取得してカルーセルで表示する方法です。

前述の方法では他のページでアップロードした画像をページに挿入している場合は、その画像は取得できないため表示されませんが、この方法ではそれらの画像も表示することができます。

また、この場合に表示される画像のサイズは編集画面で設定した「画像サイズ」になります。

get_queried_object() で現在のページのオブジェクトを取得し、その post_content プロパティから img 要素を preg_match_all(正規表現)で検索して src 属性と alt 属性の値を取得してカルーセルを表示します。

<?php
//そのページのコンテンツから画像を取得する例
$current_post = get_queried_object();  //現在表示しているページのオブジェクトを取得
$srcs = array();  //画像の URL を格納する配列の初期化
$alts = array();  //代替テキストの値を格納する配列の初期化
if(preg_match_all(
  '/<img [^>]*src="([^">]*\/wp-content\/uploads\/[^">]*)"[^>]*alt="([^">]*)"[^>]*>/u', 
  $current_post->post_content,  //このページの投稿の post_content プロパティ
  $img_array  //結果を取得する配列名(多次元配列)
)){
  $srcs = $img_array[1]; //src 属性の値の配列(画像の URL)
  $alts = $img_array[2]; //alt 属性の値の配列(メディア設定の代替テキストの値)
} 

$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID

if($srcs) {
   echo '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<div class="carousel-inner">'. "\n" ; 

  for($i = 0; $i < count($srcs); $i++) {
    $src = esc_url($srcs[$i]) ;
    $alt = esc_attr($alts[$i]) ;
    ($i === 0) ? $active = ' active' : $active = '';
    echo '<div class="carousel-item'. $active .'">'. "\n" .
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. "\n</div>" ;
  }

  echo '</div>'. "\n" .'</div>'. "\n" ; 
}  
?>

以下は HTML を直接記述する例です。

<?php
//そのページのコンテンツから画像を取得する例
$current_post = get_queried_object();  //現在表示しているページのオブジェクトを取得
$srcs = array();  //画像の URL を格納する配列の初期化
$alts = array();  //代替テキストの値を格納する配列の初期化
if(preg_match_all(
  '/<img [^>]*src="([^">]*\/wp-content\/uploads\/[^">]*)"[^>]*alt="([^">]*)"[^>]*>/u', 
  $current_post->post_content,  //このページの投稿の post_content プロパティ
  $img_array  //結果を取得する配列名(多次元配列)
)){
  $srcs = $img_array[1]; //src 属性の値の配列(画像の URL)
  $alts = $img_array[2]; //alt 属性の値の配列(メディア設定の代替テキストの値)
}

$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID

if($srcs): 
?>
<div id="<?php echo $carousel_id; ?>" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner">
<?php 
 for($i = 0; $i < count($srcs); $i++) {
    $src = esc_url($srcs[$i]) ;
    $alt = esc_attr($alts[$i]) ;
    ($i === 0) ? $active = ' active' : $active = '';
?>
  <div class="carousel-item<?php echo $active; ?>">
    <img class="<?php echo $img_class; ?>" src="<?php echo $src; ?>" alt="<?php echo $alt; ?>">
  </div>
   <?php 
  } endif;
  ?> 
  </div>
</div>

関連ページ:コンテンツの全ての画像の取得

images フォルダの画像を表示

テーマのディレクトリ(/wp-content/themes/テーマ名)に配置してある画像用のフォルダ images にある画像を取得してカルーセルで表示する方法です。

例えばテーマディレクトリ内の images フォルダに「top」と言うフォルダ(/wp-content/themes/テーマ名/images/top)を作成してそこに配置した画像を全て取得してカルーセルで表示します。

ファイルの取得方法の詳細は「テーマディレクトリの画像の取得」をご覧ください。

以下の例ではカルーセルで表示する img 要素の alt 属性($alt)に画像ファイルの名前を使用しています。

<?php
//images ディレクトリから画像を取得する例
$image_dir = '/images/top/';
$dirName = get_stylesheet_directory(). $image_dir ;
$dir = @dir($dirName);
if($dir) {
  $imageFileNames = array();  //画像名を格納する配列を初期化
  while(FALSE !== ($fileName = $dir->read())){
    $path = $dir->path. '/' .$fileName;
    if(preg_match('/image/i', mime_content_type($path))){
      $imageFileNames[] = $fileName;
    }
  }
  
  $img_class = 'd-block w-100'; //img 要素のクラス
  $carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID
  
  if($imageFileNames) {
     echo '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" .
          '<div class="carousel-inner">'. "\n" ; 
    sort($imageFileNames, SORT_STRING) ;  //ファイル名をソート(並び替え)
    for($i = 0; $i < count($imageFileNames); $i++) {
      //パスとファイル名で URL を生成して src 属性の値とする
      $src = get_stylesheet_directory_uri(). $image_dir . esc_attr($imageFileNames[$i]) ;
      //alt 属性にはファイル名から拡張子を除去したものを指定
      $alt = str_replace(array('.jpg', '.jpeg','.png',), '', $imageFileNames[$i]);
      ($i === 0) ? $active = ' active' : $active = '';
      echo '<div class="carousel-item'. $active .'">'. "\n" .
           '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. "\n</div>" ;
      }
    echo '</div>'. "\n" .'</div>'. "\n" ; 
  }
}else{
  echo '<p> Error: 指定した'. $image_dir .'は存在しません。</p>';
} 
?>

WP_Query を使って表示

WP_Query を使ってアップロードされた画像全体からパラメータで条件を指定して取得した画像を表示する方法です。

WP_Query オブジェクトを生成する際にパラメータに「'post_type' => 'attachment'」と「'post_status' =>'inherit'」を指定することで添付ファイルのオブジェクトを取得することができます。

<?php 
  $args = array( //添付画像を取得する条件のパラメータ
    'post_type' => 'attachment', //投稿タイプ:メディア(添付ファイル)
    'post_status' =>'inherit', //投稿の状態:継承(添付ファイルやリビジョン)
    'post_mime_type' => 'image', //MIME タイプ:画像
    'posts_per_page' => 5 //取得件数:5件
  );
  $image = new WP_Query( $args ); //上記条件の WP_Query オブジェクトを生成
?>

詳細は「WP_Query でまとめて添付ファイルを取得」をご覧ください。

以下はサブループを使ってカルーセルを表示する例です。

そのページの内容とは別のループ(サブループ)で表示するので、どのページで表示しても表示される画像は同じ(WP_Query のパラメータで指定したもの)になります。

<?php 
$args = array( //添付画像を取得する条件のパラメータ
  'post_type' => 'attachment', //投稿タイプ:メディア(添付ファイル)
  'post_status' =>'inherit', //投稿の状態:継承(添付ファイルやリビジョン)
  'post_mime_type' => 'image', //MIME タイプ:画像
  'posts_per_page' => 5 //取得件数:5件
);
$image = new WP_Query( $args ); //上記条件の WP_Query オブジェクトを生成

//添付画像ファイルのサブループ
if ( $image->have_posts() ) : 
$counter = 0;  
$size  = 'large'; //イメージサイズ
$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID
?>
<div id="<?php echo $carousel_id; ?>" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner">
  <?php 
    while ( $image->have_posts() ) : $image->the_post(); 
    //サイズは $size でイメージサイズ('full' 'medium' など)を指定可能
    $src = esc_url(wp_get_attachment_image_src( $image->ID, $size )[0]) ;  
    ($counter === 0) ? $active = ' active' : $active = ''; 
  ?>
  <div class="carousel-item<?php echo $active; ?>">
    <!-- クラスは $img_class で指定。画像に設定した「タイトル」を alt 属性に出力 -->
    <img class="<?php echo $img_class; ?>" src="<?php echo $src; ?>" alt="<?php the_title_attribute(); ?>">
  </div>
  <?php $counter++;  ?>
  <?php endwhile; ?>
  </div>
</div>
<?php endif; ?>
<?php wp_reset_postdata(); ?>

ループでアイキャッチ画像を取得して表示

フロントページやアーカイブページでループを使って指定したイメージサイズのアイキャッチ画像の URL を取得してカルーセルで表示する方法です。

表示する画像のサイズは get_the_post_thumbnail_url() の第2パラメータで変更可能です。

投稿記事を出力するループの中でもアイキャッチ画像の URL は取得できますが、投稿記事を表示するループの前にカルーセルを表示したい場合は投稿記事とは別のループを作成します(後述)。

以下は記事の一覧を表示してそのループの中でアイキャッチ画像のフルサイズの画像の URL などを取得して、一覧記事の後にアイキャッチ画像をカルーセル表示する例です。

この例ではカルーセルで表示するフルサイズのアイキャッチ画像に投稿へのリンクを付け、リンクの title 属性には投稿のタイトルを指定しています。

<section>
  <?php if(have_posts()) :
  //アイキャッチ画像のフルサイズの URL を格納する配列の初期化
  $thumbnails_src = array();
  //アイキャッチ画像のメディアで設定したタイトルを格納する配列の初期化
  $thumbnails_alt = array();
  //アイキャッチ画像の属する投稿へのリンクを格納する配列の初期化
  $permalinks = array();
  //アイキャッチ画像の属する投稿のタイトルを格納する配列の初期化
  $titles = array();
  ?>
  <?php while(have_posts()) : the_post(); ?>
  <div>
  <h3><?php the_title(); ?></h3>
  <?php
  //投稿にアイキャッチ画像があれば
  if ( has_post_thumbnail() ):
    
  $size  = 'large'; //イメージサイズ
  $img_class = 'd-block w-100'; //img 要素のクラス
  $carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID
    
  //イメージサイズ($size)で指定したアイキャッチ画像の URL を取得して配列に追加
  $thumbnails_src[] = esc_url( get_the_post_thumbnail_url( get_the_ID(), $size ) );
  //アイキャッチ画像のメディアの設定で指定したタイトルを取得して配列に追加
  $thumbnails_alt[] = esc_html( get_post( get_post_thumbnail_id() )->post_title );
  //アイキャッチ画像の属する投稿へのリンクを取得して配列に追加
  $permalinks[] = esc_url( get_permalink() );
  //アイキャッチ画像の属する投稿のタイトルを取得して配列に追加
  $titles[] = the_title_attribute('echo=0');
  ?>
  <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
  <?php endif; ?>
  <?php the_excerpt(); ?>
  </div>
  <?php endwhile; ?>
  <?php endif; ?>
  <div>
  <?php if($thumbnails_src):  //カルーセルの表示 ?> 
  <div id="<?php echo $carousel_id; ?>" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner">  
  <?php  
    for($i = 0; $i < count($thumbnails_src); $i++) {
      $src = $thumbnails_src[$i] ;
      $alt = $thumbnails_alt[$i] ;
      $link = $permalinks[$i] ;
      $link_title = $titles[$i];
      ($i === 0) ? $active = ' active' : $active = '';
  ?>
    <div class="carousel-item<?php echo $active; ?>">
      <a href="<?php echo $link; ?>" title="<?php echo $link_title; ?>">
        <img class="<?php echo $img_class; ?>" src="<?php echo $src; ?>" alt="<?php echo $alt; ?>">
      </a>
    </div>
    <?php } endif; ?>
    </div>
    </div>
  </div>
</section>

21行目の「アイキャッチ画像のメディアの設定で指定したタイトル」は、get_post() の引数に get_post_thumbnail_id() でアイキャッチ画像の ID を指定して、アイキャッチ画像のオブジェクトを取得し、その post_title プロパティから取得しています。

25行目の投稿のタイトルは画像のリンク(a 要素)の title 属性に出力するので the_title_attribute() を使って取得しています。

一覧記事の前にカルーセルを表示

一覧記事の前にカルーセルを表示するには、一覧記事のループの前で別のループを使ってアイキャッチ画像の情報を取得します。

通常のループを使うので取得されるアイキャッチ画像の情報は、通常のループで表示される記事のアイキャッチ画像のものになります。異なる条件でのアイキャッチ画像の情報を取得するには、別途サブループを使う必要があります。

以下は一覧記事の前にカルーセルを表示する例です。

<?php
//アイキャッチ画像のフルサイズの URL を格納する配列の初期化
$thumbnails_src = array();
//アイキャッチ画像のメディアで設定したタイトルを格納する配列の初期化
$thumbnails_alt = array();
//アイキャッチ画像の属する投稿へのリンクを格納する配列の初期化
$permalinks = array();
//アイキャッチ画像の属する投稿のタイトルを格納する配列の初期化
$titles = array();
  
$size  = 'large'; //イメージサイズ
$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselExample'; //カルーセル(の最も外側の div 要素)の ID

//ループを使って表示する投稿のアイキャッチ画像の URL などを取得
if(have_posts()) {
  while(have_posts()) {
    the_post();
    if ( has_post_thumbnail() ){
      //イメージサイズ($size)で指定したアイキャッチ画像の URL を取得して配列に追加
      $thumbnails_src[] = esc_url(get_the_post_thumbnail_url(get_the_ID(),$size)); 
      //アイキャッチ画像の元の画像のメディアの設定で指定したタイトルを取得して配列に追加
      $thumbnails_alt[] = esc_html(get_post(get_post_thumbnail_id())->post_title);
      //アイキャッチ画像の属する投稿へのリンクを取得して配列に追加
      $permalinks[] = esc_url( get_permalink() );
      //アイキャッチ画像の属する投稿のタイトルを取得して配列に追加
      $titles[] = the_title_attribute('echo=0');
    } 
  }
}
?>  
<div>
<!-- ループで取得した情報を使ってカルーセルを表示 -->
<?php if($thumbnails_src): ?> 
  <div id="<?php echo $carousel_id; ?>" class="carousel slide" data-ride="carousel">
    <div class="carousel-inner">  
    <?php  
      for($i = 0; $i < count($thumbnails_src); $i++) {
        $src = $thumbnails_src[$i] ;
        $alt = $thumbnails_alt[$i] ;
        $link = $permalinks[$i] ;
        $link_title = $titles[$i];
        ($i === 0) ? $active = ' active' : $active = '';
    ?>
    <div class="carousel-item<?php echo $active; ?>">
      <a href="<?php echo $link; ?>" title="<?php echo $link_title; ?>">
        <img class="<?php echo $img_class; ?>" src="<?php echo $src; ?>" alt="<?php echo $alt; ?>">
      </a>
    </div>
    <?php } endif; ?>
    </div>
  </div>
</div>
<!-- 投稿記事一覧のループ -->
<section>
<?php if(have_posts()) :?>
<?php while(have_posts()) : the_post(); ?>
  <div>
  <h3><?php the_title(); ?></h3>
  <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
  <?php the_excerpt(); ?>
  </div>
<?php endwhile; ?>
<?php endif; ?>
</section>

コントロールやキャプションの表示

以下は前述の例に、コントロールやインディケーター及びキャプションを表示する例です。

コントロールとインディケータでは carousel クラスの div 要素の id(以下の例では carouselX/変数 $carousel_id で指定)をそれぞれ href 属性と data-target 属性で指定する必要があります。

コントロール
前後画像への矢印アイコン(クリックすると前後へ移動)
carousel-control-prev、carousel-control-next クラスと href 属性にカルーセルの id を指定
インディケーター
画像(の数)を表すアイコン(クリックするとその画像へ移動)
carousel-indicators クラスを指定した ol 要素を配置し、画像の数だけ li 要素を記述
キャプション
画像の上に表示される文字
carousel-item クラスを指定した要素内に carousel-caption クラスを指定した要素を配置

詳細は「Bootstrap4 の使い方(5) Components (3)」をご覧ください。

<?php
//アイキャッチ画像のフルサイズの URL を格納する配列の初期化
$thumbnails_src = array();
//アイキャッチ画像のメディアで設定したタイトルを格納する配列の初期化
$thumbnails_alt = array();
//アイキャッチ画像の属する投稿へのリンクを格納する配列の初期化
$permalinks = array();
//アイキャッチ画像の属する投稿のタイトルを格納する配列の初期化
$titles = array();
//アイキャッチ画像の属する投稿の抜粋を格納する配列の初期化
$excerpts = array();
  
$size  = 'large'; //イメージサイズ
$img_class = 'd-block w-100'; //img 要素のクラス
$carousel_id = 'carouselX'; //カルーセル(の最も外側の div 要素)の ID
  
//ループで表示する投稿のアイキャッチ画像の URL を取得
if(have_posts()) {
  while(have_posts()) {
     the_post();
    if ( has_post_thumbnail() ){
      //イメージサイズ($size)で指定したアイキャッチ画像の URL を取得して配列に追加
      $thumbnails_src[] = esc_url(get_the_post_thumbnail_url(get_the_ID(),$size)); 
      //アイキャッチ画像のメディアの設定で指定した画像のタイトルを取得して配列に追加
      $thumbnails_alt[] = esc_html(get_post(get_post_thumbnail_id())->post_title);
      //アイキャッチ画像の属する投稿へのリンクを取得して配列に追加
      $permalinks[] = esc_url( get_permalink() );
      //アイキャッチ画像の属する投稿のタイトルを取得して配列に追加
      $titles[] = the_title_attribute('echo=0');
      //アイキャッチ画像の属する投稿の抜粋を取得して配列に追加
      $excerpts[] = strip_tags(get_the_excerpt());
    } 
  }
}
?>
<!-- カルーセル ここから--> 
<?php if($thumbnails_src): ?>
<?php $counts = count($thumbnails_src); //画像の総数 ?>
<div id="<?php echo $carousel_id; ?>" class="carousel slide" data-ride="carousel">
  <!-- インディケーター ここから-->
  <ol class="carousel-indicators">
    <?php for($i = 0; $i < $counts; $i++) { ?>
    <li data-target="#<?php echo $carousel_id; ?>" data-slide-to="<?php echo $i; ?>" <?php ($i ===0)? print 'class="active"' : print '';   ?>></li>
    <?php } ?>
  </ol>
  <!-- インディケーター ここまで-->
  <div class="carousel-inner">
  <?php  
  for($i = 0; $i < $counts; $i++) {
    $src = $thumbnails_src[$i] ;
    $alt = $thumbnails_alt[$i] ;
    $link = $permalinks[$i] ;
    $link_title = $titles[$i]; 
    $cap_excerpt = $excerpts[$i]; 
  ?>
    <div class="carousel-item <?php ($i ===0)? print 'active' : print ''; ?>">
      <a href="<?php echo $link; ?>" title="<?php echo $link_title; ?>">
        <img class="<?php echo $img_class; ?>" src="<?php echo $src; ?>" alt="<?php echo $alt; ?>">
        <!-- キャプション ここから-->
        <div class="carousel-caption d-none d-md-block">
          <h5><?php echo $link_title; ?></h5>
          <p><?php echo $cap_excerpt; ?></p>
        </div>
        <!-- キャプション ここまで-->
      </a>
    </div> 
   <?php } ?> 
  </div>
  <!-- コントロール ここから-->
  <a class="carousel-control-prev" href="#<?php echo $carousel_id; ?>" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">前へ</span>
  </a>
  <a class="carousel-control-next" href="#<?php echo $carousel_id; ?>" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">次へ</span>
  </a>
  <!-- コントロール ここまで-->
</div>
<?php endif;  ?>
<!-- カルーセル ここまで--> 
<!-- 投稿記事一覧のループ -->
<section>
<?php if(have_posts()) :?>
<?php while(have_posts()) : the_post(); ?>
  <div>
  <h3><?php the_title(); ?></h3>
  <a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(); ?></a>
  <?php the_excerpt(); ?>
  </div>
<?php endwhile; ?>
<?php endif; ?>
</section>

以下は出力例です。

<div id="carouselX" class="carousel slide" data-ride="carousel">
  <!-- インディケーター ここから-->
  <ol class="carousel-indicators">
    <li data-target="#carouselX" data-slide-to="0" class="active"></li>
    <li data-target="#carouselX" data-slide-to="1" class=""></li>
    <li data-target="#carouselX" data-slide-to="2" class=""></li>
    <li data-target="#carouselX" data-slide-to="3" class=""></li>
    <li data-target="#carouselX" data-slide-to="4" class=""></li>
    <li data-target="#carouselX" data-slide-to="5" class=""></li>
  </ol>
  <!-- インディケーター ここまで-->
  <div class="carousel-inner">
    <div class="carousel-item active">
      <a href="http://localhost/wp5/news/attached-file-test1/" title="投稿のタイトル">
        <img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/xxxxx-1024x768.jpg" alt="画像のタイトル">
        <!-- キャプション ここから-->
        <div class="carousel-caption d-none d-md-block">
          <h5>投稿のタイトル</h5>
          <p>投稿の抜粋</p>
        </div>
        <!-- キャプション ここまで-->
      </a>
    </div> 
    <div class="carousel-item">
      <a href="http://localhost/wp5/news/%e6%8a%95%e7%a8%bf%e3%82%b5%e3%83%b3%e3%83%97%e3%83%ab5/" title="投稿のタイトル">
        <img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/05/yyyyy-1024x683.jpg" alt="画像のタイトル">
        <!-- キャプション ここから-->
        <div class="carousel-caption d-none d-md-block">
          <h5>投稿のタイトル</h5>
          <p>投稿の抜粋</p>
        </div>
        <!-- キャプション ここまで-->
      </a>
    </div> 
       
    ・・・中略・・・ 
       
    <div class="carousel-item">
      <a href="http://localhost/wp5/news/first-post/" title="投稿のタイトル">
        <img class="d-block w-100" src="http://localhost/wp5/wp-content/uploads/2019/01/zzzzz-1024x682.jpg" alt="画像のタイトル">
        <!-- キャプション ここから-->
        <div class="carousel-caption d-none d-md-block">
          <h5>投稿のタイトル</h5>
          <p>投稿の抜粋</p>
        </div>
        <!-- キャプション ここまで-->
      </a>
    </div> 
  </div>
  <!-- コントロール ここから-->
  <a class="carousel-control-prev" href="#carouselX" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">前へ</span>
  </a>
  <a class="carousel-control-next" href="#carouselX" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">次へ</span>
  </a>
  <!-- コントロール ここまで-->
</div>

ショートコードでの実装

内容は「PHP での実装」とほぼ同じですが、以下はショートコードを使った実装例です。

functions.php にショートコードを作成して、投稿の編集画面やテンプレートにショートコードを記述すれば表示できるので便利です。

関連ページ:WordPress ショートコードの作成

コンテンツの画像を表示

内容的には「コンテンツの画像を表示」と同じで、そのページに挿入されている全ての画像を投稿オブジェクトの post_content プロパティから取得してカルーセルで表示します。

但し、この例の場合、functions.php に記述するため get_queried_object() で現在のページのオブジェクトを取得するのは適切ではないので global $post を使います。

以下は、そのページに挿入されている画像をカルーセル表示するショートコードを作成する方法です。

カルーセルを表示するには、投稿記事の表示したい位置に [carousel] と言うショートコードタグを記述するか、テンプレートの表示したい位置に以下を記述します。

投稿に画像が添付されていない場合は何も表示されません。

<?php echo do_shortcode('[carousel]'); ?>

carousel 言う名前のショートコードを作成するために以下を functions.php に記述します。

function carousel_cb($atts) {
  //ショートコードの属性(ユーザーの値とデフォルトを結合)
  extract(shortcode_atts(array(
    'carousel_id' => 'carousel-01', //カルーセル(の最も外側の div 要素)の ID
    'img_class' => 'd-block w-100', //img 要素のクラス    
    'show_control' => true, //コントロールを表示(しない場合は 0 または空文字''を指定)
    'show_indicators' => true, //インディケータを表示(しない場合は 0 または空文字''を指定)
    'show_caption' => true, //キャプションを表示(しない場合は 0 または空文字''を指定)
  ), $atts));
  
  global $post;
  $current_post = $post;  //投稿のオブジェクトを取得
  $srcs = array();  //画像の URL を格納する配列の初期化
  $alts = array();  //代替テキストの値を格納する配列の初期化
  
  if(preg_match_all(
    '/<img [^>]*src="([^">]*\/wp-content\/uploads\/[^">]*)"[^>]*alt="([^">]*)"[^>]*>/u', 
    $current_post->post_content,  //この投稿の post_content プロパティ
    $img_array  //結果を取得する配列名(多次元配列)
  )){
    $srcs = $img_array[1]; //src 属性の値の配列(画像の URL)
    $alts = $img_array[2]; //alt 属性の値の配列(メディア設定の代替テキストの値)
  } 

  $output = ''; //出力する HTML

  if($srcs) {
    $counts = count($srcs); //画像の総数 
    
    if($show_indicators) { //インディケーターを表示する場合
      $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<ol class="carousel-indicators">'. "\n";
      $indicator = '';
      for($i = 0; $i < $counts; $i++) {
        ($i === 0 ) ? $class = 'class="active"' : '';
        $indicator .= '<li data-target="#'. $carousel_id . '" data-slide-to="' . $i . '" ' .$class . '></li>'. "\n";
      }
      $output .= $indicator . '</ol>'. "\n". '<div class="carousel-inner">'. "\n"; 
    }else{ //インディケーターを表示しない場合
      $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<div class="carousel-inner">'. "\n" ; 
    }
    
    $div_img = ''; //carousel-item クラスの div 要素と img 要素及びキャプションの要素
    
    for($i = 0; $i < $counts; $i++) {
      $src = esc_url($srcs[$i]) ;
      $alt = esc_attr($alts[$i]) ;
      ($i === 0) ? $active = ' active' : $active = '';
      if($show_caption){  //キャプションに画像の代替テキストを表示する場合
        $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. 
         '<div class="carousel-caption d-none d-md-block"><p>' . $alt . '</p></div>'. "\n</div>" ; 
      }else{ //キャプションを表示しない場合
        $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. "\n</div>" ;
      }
    }
    
    if($show_control) {  //コントロールを表示する場合
      $control = '<a class="carousel-control-prev" href="#'. $carousel_id .'" role="button" data-slide="prev">' .
        '<span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span></a>'. "\n".
        '<a class="carousel-control-next" href="#'. $carousel_id .'" role="button" data-slide="next">' .
        '<span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span></a>'. "\n";
      $output = $output . $div_img . '</div>'. "\n" . $control . '</div>'. "\n" ; 
    }else{  //コントロールを表示しない場合
      $output = $output . $div_img . '</div>'. "\n" .'</div>'. "\n" ; 
    } 
  }  
   return $output;
}
add_shortcode('carousel', 'carousel_cb');
ショートコードの属性

ショートコードでは属性を指定してその値をパラメータとして利用できます。

ここでの例ではカルーセルの id 属性や画像要素のクラス属性の値、画像のサイズ、コントロールの表示・非表示などに属性を指定してカルーセルを制御できるようにしています。

この他にもカルーセルの画像表示の間隔や自動的に開始するかどうかなども設定できると思います(参照:カルーセルのオプション)。

この例の場合、そのページの全ての画像を表示するので基本的にはそのページに1つだけ挿入することを想定しています。

もし複数のカルーセルを表示する場合は、属性の carousel_id(デフォルトは carousel-01)に別の id を指定する必要があります。

また、必要に応じて img 要素のクラスを属性の img_class で指定することができます(デフォルトは d-block w-100)。

images フォルダの画像を表示

内容的には「images フォルダの画像を表示」と同じで、テーマのディレクトリ(/wp-content/themes/テーマ名)に配置してある画像用のフォルダ images にある画像を取得してカルーセルで表示します。

デフォルトでは /wp-content/themes//images/carousel/ にある画像を表示するので、必要に応じて画像フォルダをショートコードの属性で image_dir="/images/xxxx/ として指定します。

カルーセルを表示するには、投稿記事の表示したい位置に [carousel_images image_dir="/images/xxxx/] と言うショートコードタグを記述するか、テンプレートの表示したい位置に以下を記述します。

<?php echo do_shortcode('[carousel_images image_dir="/images/xxxx/"]'); ?>

以下を functions.php に記述して carousel_images と言うショートコードを作成します。

function carousel_images_cb($atts) {
  //ショートコードの属性(ユーザーの値とデフォルトを結合)
  extract(shortcode_atts(array(
    'image_dir' => '/images/carousel/', //デフォルトの画像フォルダのパス
    'carousel_id' => 'carousel-01', //カルーセル(の最も外側の div 要素)の ID
    'img_class' => 'd-block w-100', //img 要素のクラス    
    'show_control' => true, //コントロールを表示(しない場合は 0 または空文字''を指定)
    'show_indicators' => true, //インディケータを表示(しない場合は 0 または空文字''を指定)
    'show_caption' => true, //キャプションを表示(しない場合は 0 または空文字''を指定)
  ), $atts));
 
  $dirName = get_stylesheet_directory(). $image_dir ;
  $dir = @dir($dirName);
  if($dir) {
    $imageFileNames = array();  //画像名を格納する配列を初期化
    while(FALSE !== ($fileName = $dir->read())){
      $path = $dir->path. '/' .$fileName;
      if(preg_match('/image/i', mime_content_type($path))){
        $imageFileNames[] = $fileName;
      }
    }
    
    $output = ''; //出力する HTML

    if($imageFileNames) {
      $counts = count($imageFileNames); //画像の総数 
      sort($imageFileNames, SORT_STRING) ;  //ファイル名をソート(並び替え)
      if($show_indicators) { //インディケーターを表示する場合
        $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<ol class="carousel-indicators">'. "\n";
        $indicator = '';
        for($i = 0; $i < $counts; $i++) {
          ($i === 0 ) ? $class = 'class="active"' : '';
          $indicator .= '<li data-target="#'. $carousel_id . '" data-slide-to="' . $i . '" ' .$class . '></li>'. "\n";
        }
        $output .= $indicator . '</ol>'. "\n". '<div class="carousel-inner">'. "\n"; 
      }else{ //インディケーターを表示しない場合
        $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<div class="carousel-inner">'. "\n" ; 
      }

      $div_img = ''; //carousel-item クラスの div 要素と img 要素及びキャプションの要素

      for($i = 0; $i < $counts; $i++) {
        //パスとファイル名で URL を生成して src 属性の値とする
        $src = get_stylesheet_directory_uri(). $image_dir . esc_attr($imageFileNames[$i]) ;
        //alt 属性にはファイル名から拡張子を除去したものを指定
        $alt = str_replace(array('.jpg', '.jpeg','.png',), '', $imageFileNames[$i]);
        ($i === 0) ? $active = ' active' : $active = '';
        if($show_caption){  //キャプションに画像の代替テキストを表示する場合
          $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
           '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. 
           '<div class="carousel-caption d-none d-md-block"><p>' . $alt . '</p></div>'. "\n</div>" ; 
        }else{ //キャプションを表示しない場合
          $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
           '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. "\n</div>" ;
        }
      }

      if($show_control) {  //コントロールを表示する場合
        $control = '<a class="carousel-control-prev" href="#'. $carousel_id .'" role="button" data-slide="prev">' .
          '<span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span></a>'. "\n".
          '<a class="carousel-control-next" href="#'. $carousel_id .'" role="button" data-slide="next">' .
          '<span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span></a>'. "\n";
        $output = $output . $div_img . '</div>'. "\n" . $control . '</div>'. "\n" ; 
      }else{  //コントロールを表示しない場合
        $output = $output . $div_img . '</div>'. "\n" .'</div>'. "\n" ; 
      } 
    }
    return $output;
  }else{
    return '<p> Error: 指定した'. $image_dir .'は存在しません。</p>';
  } 
  
}
add_shortcode('carousel_images', 'carousel_images_cb');

WP_Query を使って表示

内容的には「WP_Query を使って表示 」と同じで、アップロードされた画像全体からパラメータで条件を指定して取得した画像をカルーセルで表示します。

カルーセルを表示するには、投稿記事の表示したい位置に [carousel_wpquery] と言うショートコードタグを記述するか、テンプレートの表示したい位置に以下を記述します。

<?php echo do_shortcode('[carousel_wpquery posts_per_page=10]'); ?>
//属性の posts_per_page を使って表示件数を 10 とする場合の例

以下を functions.php に記述して carousel_wpquery と言うショートコードを作成します。

function carousel_wpquery_cb($atts) {
  //ショートコードの属性(ユーザーの値とデフォルトを結合)
  extract(shortcode_atts(array(
    'posts_per_page' => 5, //表示件数:5件
    'image_size' => 'large', //イメージサイズ
    'carousel_id' => 'carousel-01', //カルーセル(の最も外側の div 要素)の ID
    'img_class' => 'd-block w-100', //img 要素のクラス    
    'show_control' => true, //コントロールを表示(しない場合は 0 または空文字''を指定)
    'show_indicators' => true, //インディケータを表示(しない場合は 0 または空文字''を指定)
    'show_caption' => true, //キャプションを表示(しない場合は 0 または空文字''を指定)
  ), $atts));
  
  
  $args = array( //添付画像を取得する条件のパラメータ
    'post_type' => 'attachment', //投稿タイプ:メディア(添付ファイル)
    'post_status' =>'inherit', //投稿の状態:継承(添付ファイルやリビジョン)
    'post_mime_type' => 'image', //MIME タイプ:画像
    'posts_per_page' => $posts_per_page, //取得件数:5件
  );
  $image = new WP_Query( $args ); //上記条件の WP_Query オブジェクトを生
  
  $output = ''; //出力する HTML
  
  if ( $image->have_posts() ){
    
    if($show_indicators) { //インディケーターを表示する場合
      $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<ol class="carousel-indicators">'. "\n";
      $indicator = '';
      for($i = 0; $i < $posts_per_page; $i++) {
        ($i === 0 ) ? $class = 'class="active"' : '';
        $indicator .= '<li data-target="#'. $carousel_id . '" data-slide-to="' . $i . '" ' .$class . '></li>'. "\n";
      }
      $output .= $indicator . '</ol>'. "\n". '<div class="carousel-inner">'. "\n"; 
    }else{ //インディケーターを表示しない場合
      $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<div class="carousel-inner">'. "\n" ; 
    }
    
    $counter = 0;  
    $div_img = ''; //carousel-item クラスの div 要素と img 要素及びキャプションの要素
    
    while ( $image->have_posts() ){
      $image->the_post();
      $src = esc_url(wp_get_attachment_image_src( $image->ID, $image_size )[0]) ; 
      $alt = the_title_attribute( array('echo'=>false) );  //画像のタイトル
      //画像が属する投稿のタイトルは以下のようにして取得可能
      //$alt = the_title_attribute( array('echo'=>false, 'post'=>get_post($image->ID)->post_parent) ); 
      ($counter === 0) ? $active = ' active' : $active = '';
      if($show_caption){  //キャプションに画像の代替テキストを表示する場合
        $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. 
         '<div class="carousel-caption d-none d-md-block"><p>' . $alt . '</p></div>'. "\n</div>" ; 
      }else{ //キャプションを表示しない場合
        $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '">'. "\n</div>" ;
      }
      $counter++;
    }
    if($show_control) {  //コントロールを表示する場合
      $control = '<a class="carousel-control-prev" href="#'. $carousel_id .'" role="button" data-slide="prev">' .
        '<span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span></a>'. "\n".
        '<a class="carousel-control-next" href="#'. $carousel_id .'" role="button" data-slide="next">' .
        '<span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span></a>'. "\n";
      $output = $output . $div_img . '</div>'. "\n" . $control . '</div>'. "\n" ; 
    }else{  //コントロールを表示しない場合
      $output = $output . $div_img . '</div>'. "\n" .'</div>'. "\n" ; 
    }
  }
  wp_reset_postdata();
  return $output;
 }
add_shortcode('carousel_wpquery', 'carousel_wpquery_cb'); 

ループでアイキャッチ画像を取得して表示

内容的には「ループでアイキャッチ画像を取得して表示」と同じで、フロントページやアーカイブページでループを使って指定したイメージサイズのアイキャッチ画像の URL を取得してカルーセルで表示します。

カルーセルを表示するには、アーカイブのテンプレートの表示したい位置に以下を記述します。表示される画像の数はループで表示される投稿の数になります。

<?php echo do_shortcode('[carousel_archive]'); ?>

以下を functions.php に記述して carousel_archive と言うショートコードを作成します。

function carousel_archive_cb($atts) {
  //ショートコードの属性(ユーザーの値とデフォルトを結合)
  extract(shortcode_atts(array(
    'image_size' => 'large', //イメージサイズ
    'carousel_id' => 'carousel-01', //カルーセル(の最も外側の div 要素)の ID
    'img_class' => 'd-block w-100', //img 要素のクラス    
    'show_control' => true, //コントロールを表示(しない場合は 0 または空文字''を指定)
    'show_indicators' => true, //インディケータを表示(しない場合は 0 または空文字''を指定)
    'show_caption' => true, //キャプションを表示(しない場合は 0 または空文字''を指定)
  ), $atts));
  
  //アイキャッチ画像のフルサイズの URL を格納する配列の初期化
  $thumbnails_src = array();
  //アイキャッチ画像のメディアで設定したタイトルを格納する配列の初期化
  $thumbnails_alt = array();
  //アイキャッチ画像の属する投稿へのリンクを格納する配列の初期化
  $permalinks = array();
  //アイキャッチ画像の属する投稿のタイトルを格納する配列の初期化
  $titles = array();
  
  global $post; //投稿のオブジェクト
  
  //ループを使って表示する投稿のアイキャッチ画像の URL などを取得
  if(have_posts()) {
    while(have_posts()) {
      the_post();
      if ( has_post_thumbnail() ){
        //イメージサイズ($size)で指定したアイキャッチ画像の URL を取得して配列に追加
        $thumbnails_src[] = esc_url(get_the_post_thumbnail_url(get_the_ID(),$image_size)); 
        //アイキャッチ画像の元の画像のメディアの設定で指定したタイトルを取得して配列に追加
        $thumbnails_alt[] = esc_html(get_post(get_post_thumbnail_id())->post_title);
        //アイキャッチ画像の属する投稿へのリンクを取得して配列に追加
        $permalinks[] = esc_url( get_permalink() );
        //アイキャッチ画像の属する投稿のタイトルを取得して配列に追加
        $titles[] = the_title_attribute('echo=0');
      } 
    }
  }
  
  $output = ''; //出力する HTML

  if($thumbnails_src) {
    $counts = count($thumbnails_src); //画像の総数 
    
    if($show_indicators) { //インディケーターを表示する場合
      $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<ol class="carousel-indicators">'. "\n";
      $indicator = '';
      for($i = 0; $i < $counts; $i++) {
        ($i === 0 ) ? $class = 'class="active"' : '';
        $indicator .= '<li data-target="#'. $carousel_id . '" data-slide-to="' . $i . '" ' .$class . '></li>'. "\n";
      }
      $output .= $indicator . '</ol>'. "\n". '<div class="carousel-inner">'. "\n"; 
    }else{ //インディケーターを表示しない場合
      $output = '<div id="'. $carousel_id .'" class="carousel slide" data-ride="carousel">'. "\n" . '<div class="carousel-inner">'. "\n" ; 
    }
    
    $div_img = ''; //carousel-item クラスの div 要素と img 要素及びキャプションの要素
    
    for($i = 0; $i < $counts; $i++) {
      $src = $thumbnails_src[$i] ; //アイキャッチ画像の URL
      $alt = $thumbnails_alt[$i] ; //画像のメディアの設定で指定したタイトル
      $link = $permalinks[$i] ; //投稿へのリンク
      $link_title = $titles[$i]; //投稿のタイトル
      ($i === 0) ? $active = ' active' : $active = '';
      if($show_caption){  //キャプションに画像の代替テキストを表示する場合
        $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
         '<a href="'. $link . '" title="' . $link_title . '">'.
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $alt . '"></a>'. 
         '<div class="carousel-caption d-none d-md-block"><p>' . $link_title . '</p></div>'. "\n</div>" ; 
      }else{ //キャプションを表示しない場合
        $div_img .= '<div class="carousel-item'. $active .'">'. "\n" .
         '<a href="'. $link . '" title="' . $link_title . '">'.
         '<img class="'. $img_class .'" src="'.$src. '" alt="'. $link_title . '"></a>'. "\n</div>" ;
      }
    }
    
    if($show_control) {  //コントロールを表示する場合
      $control = '<a class="carousel-control-prev" href="#'. $carousel_id .'" role="button" data-slide="prev">' .
        '<span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="sr-only">前へ</span></a>'. "\n".
        '<a class="carousel-control-next" href="#'. $carousel_id .'" role="button" data-slide="next">' .
        '<span class="carousel-control-next-icon" aria-hidden="true"></span><span class="sr-only">次へ</span></a>'. "\n";
      $output = $output . $div_img . '</div>'. "\n" . $control . '</div>'. "\n" ; 
    }else{  //コントロールを表示しない場合
      $output = $output . $div_img . '</div>'. "\n" .'</div>'. "\n" ; 
    } 
  }  
   return $output; 
}
add_shortcode('carousel_archive', 'carousel_archive_cb');