Twigで簡単!EC-CUBEの商品を特定カテゴリで最新順に取得する方法

EC-CUBEでECサイトを構築していると、
特定のカテゴリに属する商品だけを、最新順で取得して表示したいケースは少なくありません。

たとえば、

  • 「○○特集」や「おすすめ商品」カテゴリをスライダーで表示したい
  • カテゴリごとに「新着商品」コーナーを作りたい
  • 更新された順に自動で表示順が変わるようにしたい

といった場合には、テンプレート上で柔軟に商品を取得する方法を知っておくと便利です。

本記事では、Twigテンプレートの中で「特定カテゴリの商品を最新順で最大6件取得する方法」について、実際のコードとあわせて詳しく解説します。

商品を取得するTwigコード

以下が、Twigファイル内で商品を取得する記述です。

{% set Products = repository(‘Eccube\\Entity\\Product’)
.createQueryBuilder(‘p’)
.innerJoin(‘p.ProductCategories’, ‘pc’)
.where(‘pc.Category = :category_id’)
.andWhere(‘p.Status = 1’)
.setParameter(‘category_id’, category_id)
.orderBy(‘p.update_date’, ‘DESC’)
.setMaxResults(6)
.getQuery()
.getResult()
%}

解説

処理内容意味
repository(‘Eccube\\Entity\\Product’)商品エンティティのリポジトリを呼び出す
createQueryBuilder(‘p’)商品にエイリアスpを設定してクエリビルダー開始
innerJoin(‘p.ProductCategories’, ‘pc’)商品とカテゴリを内部結合(カテゴリに属する商品のみ対象)
where(‘pc.Category = :category_id’)指定カテゴリIDに属する商品だけを対象にする
andWhere(‘p.Status = 1’)公開中(Status=1)の商品に絞る
setParameter(‘category_id’, category_id)プレースホルダに実際のカテゴリIDを代入
orderBy(‘p.update_date’, ‘DESC’)更新日が新しい順(降順)に並び替え
setMaxResults(6)最大6件までを取得(件数は任意で調整可)
getQuery()->getResult()最終的なクエリ実行と結果取得

このようにすることで、テンプレート上で商品一覧を簡単に絞り込み、しかもコントローラを変更せずにロジックを実現できます。

実用例:新着スライダーの表示などに応用

このTwigは、「トップページの新着スライダー」「カテゴリ別のおすすめ商品一覧」などに非常に便利です。

たとえば、以下のように取得した商品をループで表示すればOKです。

{% set Products = repository(‘Eccube\\Entity\\Product’)
.createQueryBuilder(‘p’)
.innerJoin(‘p.ProductCategories’, ‘pc’)
.where(‘pc.Category = :category_id’)
.andWhere(‘p.Status = 1’)
.setParameter(‘category_id’, category_id)
.orderBy(‘p.update_date’, ‘DESC’)
.setMaxResults(6)
.getQuery()
.getResult()
%}
<div class=”card-wrap”>
{% for Product in Products %}
<div class=”card”>
<img src=”{{ asset(Product.main_list_image|no_image_product, ‘save_image’) }}” alt=”{{ Product.name }}”>
<h3>{{ Product.name }}</h3>
<p>¥{{ Product.getPrice02IncTaxMin|number_format }} ~</p>
</div>
{% endfor %}
</div>

このループの中では、商品画像や名前、価格などを自由にレイアウトすることが可能です。

注意点と応用

取得カテゴリIDは変数にすると再利用性UP

コントローラや親テンプレートから category_id を渡すようにすると、他のカテゴリでも使い回しできます。

公開状態のチェック(Status = 1)

商品の「非公開」もDB上には存在しているため、明示的に Status を条件に入れることで、不要な商品を除外できます。

件数制限(setMaxResults)を柔軟に

表示したい数に応じて 683 など調整可能です。

他の絞り込み条件も追加可能

在庫あり/価格帯/タグなどの条件を .andWhere() で追加すれば、さらに柔軟なフィルタが可能になります。

おまけ ECCUBE(Symfony + Doctrine + Twig)の仕組み

全体の流れ(ざっくり3ステップ)

①Entity(エンティティ):データの「構造」を定義
②Controller(コントローラ):データを「取得・加工」して Twig に渡す
③Twig(テンプレート):データを「表示」する

1. Entity(Eccube/Entity/Product)

エンティティは、データベースと1対1で結びつく「PHPのクラス」です。
たとえば Product エンティティにはこんなプロパティがあります:

class Product
{
/**
* 商品名
*/
private $name;

/**
* 税込価格(下限・上限)
*/
private $price02Min;
private $price02Max;

/**
* 公開ステータスなど
*/
private $status;

// Getter / Setter メソッドも定義されてる
public function getName() { return $this->name; }
public function getPrice02IncTaxMin() { return $this->price02IncTaxMin; }
//
}

2. Controller(PHPの処理)

コントローラでは、商品をDBから取り出して、Twig に渡す処理を行います。

public function index(Application $app)
{
$Products = $app[‘orm.em’]->getRepository(Product::class)
->findBy([‘status’ => 1], [‘update_date’ => ‘DESC’], 6);

return $app->render(‘Product/index.twig’, [
‘Products’ => $Products,
]);
}

ここでやっているのは:

  • DBから「公開中」の商品を6件だけ取得
  • それを Products という変数で Twig に渡す

このとき、各 Product には getName()getPrice02IncTaxMin() などのメソッドでアクセス可能です。

3. Twig(表示)

Twigでは、コントローラから渡された Products をループ処理などで表示します。

{% for Product in Products %}
<div class=”card”>
<h2>{{ Product.name }}</h2>
<p>価格: ¥{{ Product.getPrice02IncTaxMin|number_format }}</p>
</div>
{% endfor %}

ここでは、

  • Product.name:商品名
  • Product.getPrice02IncTaxMin:税込価格の最小値

を表示しているわけです。

まとめ

EC-CUBEでは、フロント側でも柔軟に商品取得が可能です。

カテゴリ別の新着表示やスライダーなどに応用したい場合は、この方法を覚えておくと開発がぐっと効率的になります。

「テンプレートだけで完結する」という点でも、開発・保守のしやすさに大きく貢献するので、ぜひ実装に役立ててみてください。

トラックバックURL