【EC-CUBE 4】商品をスライダー(カルーセル)で表示する方法

商品一覧をスライダー(カルーセル)表示する方法を紹介します。

EC-CUBEには「Slickスライダー」というjQueryプラグインが使われており、これを利用することで複雑なコードを書かなくても(管理画面でTwigテンプレートを修正するのみで)スライダー表示を実装できます。

トップページのメイン画像のような表示を、商品一覧に応用するイメージです。
本記事では以下ブロックの作り方(コード)を共有します。

4商品ずつ表示され、5商品目以降はスライダーで表示されます。
開発前にデバッグモードの設定をお薦めします

デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。

カスタマイズ後は、デバッグモードの解除を忘れないように。

【動作環境】
EC CUBEのバージョン:4.1.2
サーバー:Xserver

目次

スライダー実装までの手順

本記事では、以前に作成した新着商品ブロック(IDの大きい順に商品を表示)を修正し、スライダー表示に変更する手順を紹介します。

上記記事をベースに作成したControllerファイル および 新着商品ブロックのTwigテンプレート はこちら

トップページのControllerファイル(以下)をCustomize/Controllerに保存し、既存のControllerを上書きします。

<?php

/*
 * This file is part of EC-CUBE
 *
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
 *
 * http://www.ec-cube.co.jp/
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Customize\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Routing\Annotation\Route;
use Eccube\Controller\AbstractController;
use Eccube\Repository\ProductRepository;  // データベースのdtb_Productテーブルから情報を取得するためのリポジトリ。

class TopController extends AbstractController
{
    // ProductRepositoryのプロパティを宣言。
    /**
     * @var ProductRepository
     */
    protected $productRepository;

    // コンストラクタメソッド。このクラスがインスタンス化されるときに自動的に呼び出される。
    // ProductRepositoryを引数として受け取り、それをクラスのプロパティに格納する。
    /**
     * @param ProductRepository $productRepository
     */
    public function __construct(ProductRepository $productRepository) {
        $this->productRepository = $productRepository;
    }

    /**
     * @Route("/", name="homepage", methods={"GET"})
     * @Template("index.twig")
     */
    public function index()
    {
      // ProductRepositoryを使って、IDの大きい順(降順)に12件取得。
      $products = $this->productRepository->findby([], ['id' => 'DESC'], 12);

      // 取得した商品データをTwigテンプレートに渡す。
      return [
          'Products' => $products,
      ];
    }
}

前回の記事では、トップページのスペースの関係上、IDの大きな商品は3件のみ取得していました。
今回はスライダー表示のため、取得件数を12件に変更します。

以下コードを記載した新着商品ブロックを作成します。
商品数が増えたため、今回はfor文を使った表記に変更しました。(for文については こちら

<div class="ec-role">
    <div class="ec-newItemRole">
        <div class="ec-newItemRole__list">
            <div class="ec-newItemRole__listItem">
                <div class="ec-newItemRole__listItemHeading ec-secHeading--tandem">
                    <span class="ec-secHeading__en">{{ 'NEW ITEM'|trans }}</span>
                    <span class="ec-secHeading__line"></span>
                    <span class="ec-secHeading__ja">{{ '新着商品'|trans }}</span>
                    <a class="ec-inlineBtn--top" href="{{ url('product_list') }}">{{ 'more'|trans }}</a>
                </div>
            </div>
            {% for Product in Products %}
                <div class="ec-newItemRole__listItem">
                    <a href="{{ url('product_detail', {'id': Product.id}) }}">
                        <img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}">
                        <p class="ec-newItemRole__listItemTitle">{{ Product.name }}</p>
                        <p class="ec-newItemRole__listItemPrice">
                            {% if Product.hasProductClass %}
                                {% if Product.getPrice02Min == Product.getPrice02Max %}
                                    {{ Product.getPrice02IncTaxMin|price }}
                                {% else %}
                                    {{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }}
                                {% endif %}
                            {% else %}
                                {{ Product.getPrice02IncTaxMin|price }}
                            {% endif %}
                        </p>
                    </a>
                </div>
            {% endfor %}
        </div>
    </div>
</div>

トップページのレイアウトに上記ブロックを挿入すると、以下のような表示になると思います。

IDが大きい順に、12個商品がずらっと並ぶ
STEP

Slickスライダーを利用するためのコードを追記

新着商品ブロック(new_item.twig)を開き、Slickスライダーの設定を行います。

ます、EC-CUBEのトップページでSlickスライダーを使う箇所に、以下のようなHTMLコードを記述します。

<div class="ec-sliderRole">
    <div class="custom-carousel">
        {% for Product in Products %}
            <div class="ec-newItemRole__listItem item slick-slide">
            {# 省略 #}
            </div>
        {% endfor %}
    </div>
</div>
  1. 全体を “ec-sliderRole” クラスで囲う。
  2. さらに “custom-carousel” クラスで囲う。(ここのクラス名は何でもOK)
  3. スライダー表示させる個々の要素に “item” と “slick-slide” クラスを追加

以下は修正後の新着商品ブロックのコードです。

<div class="ec-role">
    <div class="ec-newItemRole">
        <div class="ec-newItemRole__list">
            <div class="ec-newItemRole__listItem">
                <div class="ec-newItemRole__listItemHeading ec-secHeading--tandem">
                    <span class="ec-secHeading__en">{{ 'NEW ITEM'|trans }}</span>
                    <span class="ec-secHeading__line"></span>
                    <span class="ec-secHeading__ja">{{ '新着商品'|trans }}</span>
                    <a class="ec-inlineBtn--top" href="{{ url('product_list') }}">{{ 'more'|trans }}</a>
                </div>
            </div>
            <div class="ec-sliderRole">
                <div class="custom-carousel">
                    {% for Product in Products %}
                        <div class="ec-newItemRole__listItem item slick-slide">
                            <a href="{{ url('product_detail', {'id': Product.id}) }}">
                                <img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}">
                                <p class="ec-newItemRole__listItemTitle">{{ Product.name }}</p>
                                <p class="ec-newItemRole__listItemPrice">
                                    {% if Product.hasProductClass %}
                                        {% if Product.getPrice02Min == Product.getPrice02Max %}
                                            {{ Product.getPrice02IncTaxMin|price }}
                                        {% else %}
                                            {{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }}
                                        {% endif %}
                                    {% else %}
                                        {{ Product.getPrice02IncTaxMin|price }}
                                    {% endif %}
                                </p>
                            </a>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
    </div>
</div>
STEP

Slickスライダーを実装するためのJQueryを追記

次に、新着商品ブロックの上方に以下のJQueryを記述します。
4行目の引数には、STEP2で設定したクラス名を記述します。

{% block javascript %}
<script type="text/javascript">
    $(document).ready(function(){
    $('.custom-carousel').slick({
        // ここに各種オプションを記載
    });
    });
</script>
{% endblock %}

Slickスライダーでは、一度に表示させる要素数や自動スクロールのオン・オフなど、各種オプションを設定できます。

Slickスライダーの代表的なオプション
slidesToShow

一度に表示するスライド数を指定

slidesToScroll

一度のスクロールで移動するスライド数を指定

autoplay

自動スクロールさせるかどうかを設定

autoplaySpeed

自動スクロールの速度(ミリ秒単位)を指定

arrows

ナビゲーション矢印の表示/非表示を設定

dots

ドットナビゲーションの表示/非表示を設定

centerMode

アクティブなスライドをセンターに配置

centerPadding

センターモード時のサイドのパディングを設定

responsive

ブレークポイント(画面幅)ごとの設定を指定

今回は以下のようなオプションを設定しました。

  • 一度に表示するスライド(商品)は4点(slidesToShow: 4
  • 一度のスクロールで移動するスライド(商品)は4点(slidesToScroll: 4
  • 自動スクロールさせる(autoplay: true
  • 自動スクロールは2秒(2,000ミリ秒)ごとに行う(autoplaySpeed: 2000
  • スライダーの下方にドットナビゲーションを表示(dots: true
{% block javascript %}
<script type="text/javascript">
    $(document).ready(function(){
    $('.custom-carousel').slick({
        slidesToShow: 4,
        slidesToScroll: 4,
        autoplay: true,
        autoplaySpeed: 2000,
        dots: true,
    });
    });
</script>
{% endblock %}

以上で実装完了です。
コード全体は以下に纏めています。

デザインなどは、CSSやSlickスライダーのオプションなどを適宜設定してください。

【実装コード】新着商品を4個ずつスライダー表示

全体のコードは以下の通りです。
以下コードを記載した新規ブロックを作成し、トップページに表示させればOKです。
(トップページのControllerも修正しておくこと)

{% block javascript %}
<script type="text/javascript">
    $(document).ready(function(){
    $('.custom-carousel').slick({
        slidesToShow: 4,
        slidesToScroll: 4,
        autoplay: true,
        autoplaySpeed: 2000,
        dots: true,
    });
    });
</script>
{% endblock %}

<div class="ec-role">
    <div class="ec-newItemRole">
        <div class="ec-newItemRole__list">
            <div class="ec-newItemRole__listItem">
                <div class="ec-newItemRole__listItemHeading ec-secHeading--tandem">
                    <span class="ec-secHeading__en">{{ 'NEW ITEM'|trans }}</span>
                    <span class="ec-secHeading__line"></span>
                    <span class="ec-secHeading__ja">{{ '新着商品'|trans }}</span>
                    <a class="ec-inlineBtn--top" href="{{ url('product_list') }}">{{ 'more'|trans }}</a>
                </div>
            </div>
            <div class="ec-sliderRole">
                <div class="custom-carousel">
                    {% for Product in Products %}
                        <div class="ec-newItemRole__listItem item slick-slide">
                            <a href="{{ url('product_detail', {'id': Product.id}) }}">
                                <img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}">
                                <p class="ec-newItemRole__listItemTitle">{{ Product.name }}</p>
                                <p class="ec-newItemRole__listItemPrice">
                                    {% if Product.hasProductClass %}
                                        {% if Product.getPrice02Min == Product.getPrice02Max %}
                                            {{ Product.getPrice02IncTaxMin|price }}
                                        {% else %}
                                            {{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }}
                                        {% endif %}
                                    {% else %}
                                        {{ Product.getPrice02IncTaxMin|price }}
                                    {% endif %}
                                </p>
                            </a>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
    </div>
</div>

実装後、以下のような表示になっていればOKです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次