トップへ戻る
BLOGS

WordPress スライダーブロックの制作 (レンダリング編)

WordPress スライダーブロックの制作 (レンダリング編)

今回も前回の続きでWordPressのブロック制作です

今回は画像を並べてスライダーを挿入するプラグインを作成していきます

最終的にスライダーの実装にはJavaScriptライブラリの「Swiper」を使用していきます

Swiper は<div>タグなどに指定のクラス名を設定することでスライダーのスタイルや仕様を変更することが可能なので最終的には管理画面のインスペクターの設定などを使用しユーザーの好みのスライダーをブロックとして追加できるようにしたいと思います

※本記事はMacを使用したWordPressのローカル環境であり、Node.jsのインストール環境での開発を想定した記事です

前回の記事で環境構築を行い、edit.js を編集して管理画面の設定と編集画面のUIを作成していたので今回はその続きです

「Swiper」の導入

公式サイト:Getting Started With Swiper

Swiperファイルの入手

今回Swiperの設置方法はダウンロード方式で行いたいと思います

CDNで配置するのが簡単ですが、公式が書き換わった際に動作しなくなるなどの問題も多いためこのほうが安全な手段だと思います

必要なファイルは以下の二種類です

  • 「swiper-bundle.min.css」
  • 「swiper-bundle.min.js」

これらを環境に合わせて配置し、それぞれのファイルを読み込みます

Swiperの初期化

スライダーの実装にはnew 演算子と Swiper() メソッドを使って初期化する必要があります

swiperの書式

let スライダーインスタンス(変数) = new Swiper('セレクタ', {
    オプション(オブジェクト)
});

Swiper() メソッドにはスライダーのコンテナ要素(セレクタ)を指定します(今回の例では.wp-block-oja-custom-slider .swiper-container)

そしてオブジェクト形式で必要なオプションを指定して実行します。Swiper() メソッドはスライダーのインスタンス(Swiper オブジェクト)を生成しリターンします

これらのファイルも作成します

Swiper初期化ファイル作成

init-swiper.js

const sliderElems = document.querySelectorAll(
	".wp-block-oja-custom-slider .swiper-container"
);

//取得した要素が1以上であればそれぞれの要素に対して以下を実行
if (sliderElems && sliderElems.length > 0) {
	for (let element of sliderElems) {
		//data 属性の値をパラメータの値として使用する変数に格納
		let elementSpeed = element.getAttribute("data-speed"), //遷移時間
			elementDirection = element.getAttribute("data-direction"), //スライドする方法。’horizontal’(横)か’vertical’(縦)
			elementAutoPlay = element.getAttribute("data-autoplay"), //自動再生
			elementLoop = element.getAttribute("data-loop"), //ループ
			elementEffect = element.getAttribute("data-effect"), //スライドエフェクト
			elementSlidesPerView = element.getAttribute("data-slides-per-view"), //ビューの表示枚数
			elementSlidesPerGroup = element.getAttribute("data-slides-per-group"), //指定した数のスライドがグループ化されて、同時にスライドする
			elementSpaceBetween = element.getAttribute("data-space-between"), //スライド同士の距離を設定
			elementCenteredSlides = element.getAttribute("data-centered-slides"); //三枚以上のスライドで、最初のスライド(アクティブなスライド)をセンターにする

		//data 属性が設定されていない場合は初期値(デフォルト)を設定及び型を変換
	if (!elementSpeed) {
		elementSpeed = 300;
	}
	if (!elementDirection) {
		elementDirection = "horizontal";
	}
	if (elementAutoPlay) {
		elementAutoPlay = parseInt(elementAutoPlay);
	} else {
		elementAutoPlay = 999999999;
	}
	if (elementLoop == "true") {
		elementLoop = true;
	} else {
		elementLoop = false;
	}
	if (!elementEffect) {
		elementEffect = "slide";
	}
	if (!elementSlidesPerView) {
		elementSlidesPerView = 1;
	}
	if (elementCenteredSlides == "true") {
		elementCenteredSlides = true;
	} else {
		elementCenteredSlides = false;
	}

	let swiperSlider = new Swiper(element, {
		direction: elementDirection,
		speed: parseInt(elementSpeed),
		autoplay: {
			delay: elementAutoPlay,
		},
		loop: elementLoop,
		effect: elementEffect,
		slidesPerView: parseInt(elementSlidesPerView),
		centeredSlides: elementCenteredSlides,
		pagination: {
			el: ".swiper-pagination",
			type: "bullets",
			clickable: true,
		},
		navigation: {
			nextEl: ".swiper-button-next",
			prevEl: ".swiper-button-prev",
		},
		scrollbar: {
			el: ".swiper-scrollbar",
		},
	});
}

これで必要なファイルが揃いました

今回は assetsディレクトリを新たに作成し、その中に上記のファイルをそれぞれリネームするなどして配置し読み込みます

  • swiper-bundle.min.css => swiper.css
  • swiper-bundle.min.js => swiper.js

custom-slider.php

//Swiper のファイル群を読み込み
function add_oja_swiper_scripts() {
  $dir = dirname( __FILE__ );

  //Swiper の JavaScript ファイルの読み込み(エンキュー)
  wp_enqueue_script(
    'swiper-slider',
    plugins_url( '/assets/swiper.js', __FILE__ ),
    array(),
    filemtime( "$dir/assets/swiper.js" ),
    true
  );

  //Swiper を初期化するためのファイルの読み込み(エンキュー)
  wp_enqueue_script(
    'swiper-slider-init',
    plugins_url( '/assets/init-swiper.js', __FILE__ ),
    //依存ファイルに上記 Swiper の JavaScript を指定
    array('swiper-slider'),
    filemtime( "$dir/assets/init-swiper.js" ),
    true
  );

  //Swiper の CSS ファイルの読み込み(エンキュー)
  wp_enqueue_style(
    'swipe-style',
    plugins_url( '/assets/swiper.css', __FILE__ ),
    array(),
    filemtime( "$dir/assets/swiper.css"  )
  );

}
add_action('enqueue_block_assets', 'add_oja_swiper_scripts');

さてここからはダイナミックブロックなのでPHP側で定義した属性値を用いてHTMLタグをレンダリングしていくわけですが、その方法としてそもそも「Swiper」のマークアップ方法を見ていきます

スライダーマークアップ例

swiperのマークアップ

<!-- スライダーのメインのコンテナー -->
<div class="swiper-container"> 
 
  <!-- スライダーのラッパー -->
  <div class="swiper-wrapper"> 
    <!-- スライド .swiper-slide の中に画像を配置 -->
    <div class="swiper-slide"><img src="images/sample_01.jpg" alt=""></div>
    <div class="swiper-slide"><img src="images/sample_02.jpg" alt=""></div>
    <div class="swiper-slide"><img src="images/sample_03.jpg" alt=""></div>
  </div>
  
  <!-- ページネーションの表示 -->
  <div class="swiper-pagination"></div>
  
  <!-- ナビゲーションボタンの表示 -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
  
  <!-- スクロールバーの表示 -->
  <div class="swiper-scrollbar"></div>
</div>

上記のように基本的に指定のクラス名とタグでマークアップすることでスライダーとして実装が可能です

それではPHPで定義したregister_block_type()で定義したrender_callbackの関数を定義していきます

PHPでレンダリング

custom-slider.php

<?php
function oja_slider_render_func($attributes, $content) {

  //属性 imageUrl が空なら何も表示しない
  if (empty($attributes['imageUrl'])) {
    return '';
  }

  //属性 imageUrl が空でなければスライダーのマークアップを組み立てる
  $output = '<div class="wp-block-oja-custom-slider">';
  $output .= '<div class="swiper-container">';
  $output .= '<div class="swiper-wrapper">';

  $imageUrl = $attributes['imageUrl'];
  $imageCaption = $attributes['imageCaption'];
  $imageAlt = $attributes['imageAlt'];

  for($i = 0; $i < count($imageUrl); $i ++) {
    $img_url     = esc_url($imageUrl[$i]);
    $img_caption = $imageCaption[$i] ? esc_html($imageCaption[$i]): '';
    $img_alt     = $imageAlt[$i] ? esc_attr($imageAlt[$i]): '';
    if($img_alt !=="") {
      $output .= '<div class="swiper-slide"><img className="card_image" src="'. $img_url . '" alt="' . $img_alt . '" />';
    } else {
      $output .= '<div class="swiper-slide"><img className="card_image" src="'. $img_url . '" alt="" aria-hidden="true" />';
    }
    //キャプションを表示する場合
    if($attributes['showCaption']) {
      if($img_caption) {
        $output .= '<div class="caption">'. $img_caption . '</div>';
      }
    }
    $output .= '</div>';
  }

  $output .= '</div>';
  //ページネーションを表示する場合
  if($attributes['showPagination']) {
    $output .= '<div class="swiper-pagination"></div>';
  }
  //ナビゲーションボタンを表示する場合
  if($attributes['showNavigationButton']) {
    $output .= '<div class="swiper-button-prev"></div><div class="swiper-button-next"></div>';
  }
  //スクロールバーを表示する場合
  if($attributes['showScrollbar']) {
    $output .= '<div class="swiper-scrollbar"></div>';
  }
  $output .= '</div></div>';
  return $output;
}

簡単に説明を

PHPでのレンダリングは引数を2つ取れます
attributesで定義した属性値と、記事本文の$contentです

$contentは今回は使用しません
まず画像が選択されていない場合は何もせずreturnします

 if (empty($attributes['imageUrl'])) {
    return '';
  }

そして一旦、属性値を変数化しておき、それをfor文で一つづつエスケープしながら取り出してHTMLを組み立てます

$imageUrl = $attributes['imageUrl'];
$imageCaption = $attributes['imageCaption'];
$imageAlt = $attributes['imageAlt'];
for($i = 0; $i < count($imageUrl); $i ++) {
 $img_url     = esc_url($imageUrl[$i]);
 $img_caption = $imageCaption[$i] ? esc_html($imageCaption[$i]): '';
 $img_alt     = $imageAlt[$i] ? esc_attr($imageAlt[$i]): '';
...以下略
}

ここまで記述できたら実際の画面でレンダリング出来ているか確認してみましょう

スライダーオプションの追加

Swiper のライブラリはスライダーに対して様々なオプションを設定することが可能です

その方法は

<div class="swiper-container" data-loop="true" data-effect="cube" data-speed="1000"> 

上記のようにスライダーをラップしているタグに対してdata-xxxx 属性を使ってマークアップすることで実装できます

まずは属性値の定義からです

PHPに属性値を追加

custom-slider.php(追加)

// attributes: に追加

//スライダー自動再生
      'slideAutoPlay' => [
        'type' => 'number',
        'default' => 0
      ],
      //スライダースピード
      'slideSpeed' => [
        'type' => 'number',
        'default' => 300
      ],
      //スライダーのループ設定
      'slideLoopEnable' => [
        'type' => 'boolean',
        'default' => true
      ],
      //スライダーのエフェクト
      'slideEffect' => [
        'type' => 'string',
        'default' => 'slide'
      ],
      //スライダーの画像表示枚数
      'slidesPerView' => [
        'type' => 'number',
        'default' => 1
      ],
      //スライダー画像の中央寄せ
      'slideCentered' => [
        'type' => 'boolean',
        'default' => false
      ],

それぞれattributesに追加し、これらの値を使用したインスペクターを実装しそれを反映させるようにPHPでレンダリングするという流れですね

インスペクターを追加する

先に作成したインスペクターを返す関数に追加で書き足していきます

<PanelBody>でくくられた部分がひとまとまりになるため、グループ分けできて見やすくなると思います

edit.js(Inspector関数に追加)

<PanelBody
          title='スライダー詳細設定'
          initialOpen={false}
        >
          <PanelRow>   
            <RangeControl
              label='自動再生'
              value={attributes.slideAutoPlay}
              onChange={(val) => setAttributes({ slideAutoPlay: val })}
              min={0}
              max={8000}
              step={100}
              help="自動生成しない場合は0を指定"
            />
          </PanelRow>
          <PanelRow>   
            <RangeControl
              label='スライドスピード'
              value={attributes.slideSpeed}
              onChange={(val) => setAttributes({ slideSpeed: val })}
              min={100}
              max={1000}
              step={100}
            />
          </PanelRow>
          <PanelRow>
            <SelectControl
              label="エフェクト"
              value={attributes.slideEffect}
              options={[
                {label: "Slide", value: 'slide'},
                {label: "Fade", value: 'fade'},
                {label: "Cube", value: 'cube'},
                {label: "Coverflow", value: 'coverflow'},
                {label: "Flip", value: 'flip'},
              ]}
              onChange={(val) => setAttributes({ slideEffect: val })}
            />
          </PanelRow>
          <PanelRow>
            <CheckboxControl
              label="ループ"
              checked={attributes.slideLoopEnable}
              onChange={(val) => setAttributes({ slideLoopEnable: val })}
            />
          </PanelRow>
          <PanelRow>
            <RangeControl
              label='表示枚数'
              value={attributes.slidesPerView}
              onChange={(val) => setAttributes({ slidesPerView: val })}
              min={1}
              max={5}
            />
          </PanelRow>
          <PanelRow>
            <CheckboxControl
              label="中央配置"
              checked={attributes.slideCentered}
              onChange={(val) => setAttributes({ slideCentered: val })}
            />
          </PanelRow>
        </PanelBody>

それぞれのvalue値などはswiperの公式を見てみてください

最後にPHPのレンダリング関数を書き換えます

rendercallbackの変更

custom-slider.php (関数の書き換え)

<?php
function oja_slider_render_func($attributes, $content) {

  //属性 imageUrl が空なら何も表示しない
  if (empty($attributes['imageUrl'])) {
    return '';
  }

  //スライダーのオプション(attributes の値により data 属性を追加)
  $slider_options = '';

  if($attributes['slideAutoPlay'] !== 0) {
    $slider_options .= 'data-autoplay="'.$attributes['slideAutoPlay'].'"';
  }

  $slider_options .= ' data-speed="'.$attributes['slideSpeed'].'"';

  if($attributes['slideLoopEnable']) {
    $slider_options .= ' data-loop="true"';
  }

  if($attributes['slideEffect'] !== 'slide') {
    $slider_options .= ' data-effect="' .$attributes['slideEffect']. '"';
  }
  $slider_options .= ' data-slidesPerView="' .$attributes['slidesPerView'] . '"';

  if($attributes['slideCentered']) {
    $slider_options .= ' data-centeredSlides="true"';
  }
  //属性 imageUrl が空でなければスライダーのマークアップを組み立てる
  $output = '<div class="wp-block-oja-custom-slider">';
  $output .= '<div class="swiper-container"'. $slider_options .'>';
  $output .= '<div class="swiper-wrapper">';

  $imageUrl = $attributes['imageUrl'];
  $imageCaption = $attributes['imageCaption'];
  $imageAlt = $attributes['imageAlt'];

  for($i = 0; $i < count($imageUrl); $i ++) {
    $img_url     = esc_url($imageUrl[$i]);
    $img_caption = $imageCaption[$i] ? esc_html($imageCaption[$i]): '';
    $img_alt     = $imageAlt[$i] ? esc_attr($imageAlt[$i]): '';
    if($img_alt !=="") {
      $output .= '<div class="swiper-slide"><img className="card_image" src="'. $img_url . '" alt="' . $img_alt . '" />';
    } else {
      $output .= '<div class="swiper-slide"><img className="card_image" src="'. $img_url . '" alt="" aria-hidden="true" />';
    }
    //キャプションを表示する場合
    if($attributes['showCaption']) {
      if($img_caption) {
        $output .= '<div class="caption">'. $img_caption . '</div>';
      }
    }
    $output .= '</div>';
  }

  $output .= '</div>';
  //ページネーションを表示する場合
  if($attributes['showPagination']) {
    $output .= '<div class="swiper-pagination"></div>';
  }
  //ナビゲーションボタンを表示する場合
  if($attributes['showNavigationButton']) {
    $output .= '<div class="swiper-button-prev"></div><div class="swiper-button-next"></div>';
  }
  //スクロールバーを表示する場合
  if($attributes['showScrollbar']) {
    $output .= '<div class="swiper-scrollbar"></div>';
  }
  $output .= '</div></div>';
  return $output;
}

今回のまとめです

前回からここまでで一通りプラグインブロックとして、画像のアップロードを行う事ができる管理画面の実装に始まり、スライダーライブラリを利用してフロントエンドで実際に画像を表示する
また、表示したスライダーを管理画面からオプションとして変更するといったところまでが完成しました

スライダーや画像を扱うブロックの基礎となる部分が練り込まれているためここからまた本記事を参考にオリジナルブロックを作成する事ができればと思います

次回は今回のスライダーに投稿記事を載せれるように魔改造したいです

お疲れさまでした

コメントをお待ちしております

お気軽にコメントをどうぞ。

CAPTCHA