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)を柔軟に
表示したい数に応じて 6
→ 8
や 3
など調整可能です。
他の絞り込み条件も追加可能
在庫あり/価格帯/タグなどの条件を .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では、フロント側でも柔軟に商品取得が可能です。
カテゴリ別の新着表示やスライダーなどに応用したい場合は、この方法を覚えておくと開発がぐっと効率的になります。
「テンプレートだけで完結する」という点でも、開発・保守のしやすさに大きく貢献するので、ぜひ実装に役立ててみてください。