【自動更新】新着商品ブロックの作成
次に、新規ブロックの作り方を紹介します。
デフォルトのレイアウトでは、新着商品ブロックはトップページに表示されていますので、TOPページの画面を見ながら修正します。
EC-CUBEのアップデートにより「新着商品(自動取得)」ブロック(auto_new_item.twig)がデフォルトで追加されました。商品IDの大きい順に最大5つの商品が掲載されるブロックで、このブロックをレイアウト管理からトップページに配置するだけで簡単に実装できるようになりました!
初期ブロック(作成前)と完成ブロック
- 初期ブロック
-
編集前 デフォルトの新着商品ブロックはこのような表示になっています。
新しく商品登録を行っても、手動でTwigを修正しない限り表示される商品は変わりません。
TwigとControllerのコードは以下に記載。
- 完成ブロック
-
編集後 新着商品(IDの大きい順)が左 → 右へ表示される。
またこの状態で新しく商品登録を行うと、自動的に新しい商品に入れ替わっていきます。
手順やコードなどは本記事に掲載。
初期状態の新着商品ブロック(new_item.twig)は以下のようになっています。
{#
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.
#}
<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-newItemRole__listItem">
<a href="{{ url('product_detail', {'id': '1'}) }}">
<img src="{{ asset('cube-1.png', 'save_image') }}">
<p class="ec-newItemRole__listItemTitle">{{ '彩のジェラート"CUBE"'|trans }}</p>
<p class="ec-newItemRole__listItemPrice">{{ '¥1,200(税込)'|trans }}</p>
</a>
</div>
<div class="ec-newItemRole__listItem">
<a href="{{ url('product_detail', {'id': '2'}) }}">
<img src="{{ asset('sand-1.png', 'save_image') }}">
<p class="ec-newItemRole__listItemTitle">{{ 'チェリーアイスサンド'|trans }}</p>
<p class="ec-newItemRole__listItemPrice">{{ '¥800(税込)'|trans }}</p>
</a>
</div>
<div class="ec-newItemRole__listItem">
<a href="{{ url('product_detail', {'id': '1'}) }}">
<img src="{{ asset(''|no_image_product , 'save_image') }}">
<p class="ec-newItemRole__listItemTitle">{{ '彩のジェラート"CUBE" NEO'|trans }}</p>
<p class="ec-newItemRole__listItemPrice">{{ '¥600(税込)'|trans }}</p>
</a>
</div>
</div>
</div>
</div>
3種類の商品それぞれを直接Twigに記載している。そのため、内容を変えるにはこちらのコードを都度修正する必要がある。
作成手順
- src/Eccube/Controller下にあるTopControllerを、app/Customize/Controller下に複製
- 複製したTopControllerを修正
- Repositoryを使って商品IDの大きい順に商品を抽出し、変数に格納する。
Repositoryについては こちらの記事 を参照ください。
- Repositoryを使って商品IDの大きい順に商品を抽出し、変数に格納する。
- 新着商品ブロックのTwigを修正
- Controllerで抽出・格納した商品を受け取り、格納順(商品IDの大きい順)に表示する。
- EC CUBE 管理画面にてキャッシュを削除
TopControllerの複製
前述の新規ページ作成ではControllerを新規に作成しましたが、トップページのControllerはすでに用意されているので、そちらを「app/Customize/Controller」下に複製してそちらを修正します。

src下のControllerを直接修正しても実装できますが、後で元に戻せなくなったりEC-CUBEのアップデート等で不具合が出たりする可能性があるため、オススメできません。
コピーしたTopControllerを修正
基本的には新規ページ作成時と同じですが、namespace と use の部分も変更する点に注意。
<?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の大きい順(降順)に3件取得。
$products = $this->productRepository->findby([], ['id' => 'DESC'], 3);
// 取得した商品データをTwigテンプレートに渡す。
return [
'Products' => $products,
];
}
}
Repositoryにはfindby()
というメソッドが用意されています。
findby()
の第1引数に空の配列[ ]
、第2引数に['id' => 'DESC']
、第3引数にと3
すると、
『商品テーブルのデータをIDの降順(大きい順)で3件取得』できます。
Repositoryの機能について、より詳しい説明は以下記事を参照ください。
新着商品ブロックのTwigを修正
<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>
前述のControllerの通り、「Products」にはIDの大きい順に3つの商品情報が格納されてます。
その商品データを、for文を用いて「product」として一つずつ取り出し、
- product.main_list_image
-
メイン画像
- product.id
-
商品ID
- product.name
-
商品名
- product.getPrice
-
価格
を順々に表示しています。
Twigテンプレートの書き方については以下記事を参照ください。
キャッシュを削除
ここまでで準備完了です。
管理画面からキャッシュを削除して、ページにアクセスしてみましょう。

以下のように、商品登録の新しい順(=商品IDの大きい順)に商品が表示されればOKです!

ここで作成した新着商品ブロックをトップページ以外でも使おうとすると、エラーもしくは意図しない表示になる可能性が高いです。
トップページはControllerを修正し、Twigの「Products」に新着商品情報が格納されるようになっていますが、他ページではそのようなControllerになっていないためです。
もし他のページでも同様に使いたい場合は、トップページ以外のControllerも同じように修正してください。
まとめ & 次のステップ
以上、新着商品の一覧ページとブロックの作り方を紹介しました。
トップページには新着商品を表示させておきたい方も多いと思います。
登録のたびに商品を入れ替えるというのもアリですが、頻繁に商品が入れ替わるような場合は今回のような設定をしておくと便利です。
また、応用すれば「古い商品順に表示させる」といったことも可能になります。(あまりそのような使い方はしないかもしれませんが。)
本格的なカスタマイズをお考えの方はぜひトライしてみてください!


