関連商品のテンプレートTWIGファイルをカスタマイズしたい
EC-CUBE4.0系の「関連商品プラグイン」を使用して表示される部分をカスタマイズしたいことがあり、どうすればできるのか調べたことをメモ。 使用しているEC-CUBEのバージョンは4.1.1。
テンプレートファイルの場所
今回、カスタマイズしたかったのは商品詳細ページに表示される一覧の部分だったので、以下のフロントのテンプレート「related_product.twig 」が対象となります。
商品詳細ページに表示される部分のテンプレート
/app/Plugin/RelatedProduct4/Resource/template/front/related_product.twig
ちなみに管理画面側のテンプレートをカスタマイズしたいときは、以下のadminフォルダにある「related_product.twig 」を使用します。
管理画面用テンプレート
/app/Plugin/RelatedProduct4/Resource/template/admin/related_product.twig
デフォルトのソース
何もいじっていなければ、テンプレートは以下のようになっているはずです。これをカスタマイズします。
- /app/Plugin/RelatedProduct4/Resource/template/front/related_product.twig
<script>
$(function () {
$('#RelatedProduct-product_area').appendTo($('.ec-layoutRole__main, .ec-layoutRole__mainWithColumn, .ec-layoutRole__mainBetweenColumn'));
});
</script>
<div id="RelatedProduct-product_area" class="ec-shelfRole">
<ul class="ec-shelfGrid">
{% for RelatedProduct in Product.RelatedProducts %}
{% set ChildProduct = RelatedProduct.ChildProduct %}
{% if ChildProduct.Status.id == constant("Eccube\\Entity\\Master\\ProductStatus::DISPLAY_SHOW") %}
<li class="ec-shelfGrid__item">
<a href="{{ url('product_detail', {id : ChildProduct.id}) }}">
<p class="ec-shelfGrid__item-image">
<img src="{{ asset(RelatedProduct.ChildProduct.main_list_image|no_image_product, 'save_image') }}">
</p>
<p>{{ RelatedProduct.ChildProduct.name }}</p>
<p>
{% if RelatedProduct.ChildProduct.hasProductClass %}
{% if RelatedProduct.ChildProduct.getPrice02Min == RelatedProduct.ChildProduct.getPrice02Max %}
{{ RelatedProduct.ChildProduct.getPrice02IncTaxMin|price }}
{% else %}
{{ RelatedProduct.ChildProduct.getPrice02IncTaxMin|price }} ~ {{ RelatedProduct.ChildProduct.getPrice02IncTaxMax|price }}
{% endif %}
{% else %}
{{ RelatedProduct.ChildProduct.getPrice02IncTaxMin|price }}
{% endif %}
</p>
</a>
<span>{{ RelatedProduct.content|raw }}</span>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
カスタマイズ後はEC-CUBEの管理画面にログインして以下の画面で「登録」ボタンを押さないとページに反映されないので注意してください。
- [コンテンツ管理]-[ページ管理]-[商品詳細ページ]
カスタマイズに使った変数
| 変数 | 内容 |
| {{ RelatedProduct.ChildProduct.id }} {{ ChildProduct.id }} |
商品ID |
| {{ RelatedProduct.ChildProduct.code_min } | 商品コード | {{ RelatedProduct.ChildProduct.name }} | 商品名 |
| {% for hoge in ChildProduct.ProductClasses %} {{hoge.id }} {% endfor %} |
商品クラスID |
カートに入れるために必要なProductClassのIDが取得できずに困りましたが、以下のページが参考になりました。<for>文を使って取得することが必要でした。
{% for hoge in Product.ProductClasses %}
{{hoge.id }}
{% endfor %}
デバッグしたいとき
Product.idなど、Productに関して取得できる変数や値の内容を知りたいということがありました。
.envファイルを開いてデバッグモードにして、商品詳細ページのテンプレート(detail.twig)に{{dump(Product)}} を追記して、商品詳細ページをブラウザで表示すると変数や配列に入っている値を確認できます。
デバッグモードに変更する方法と追記するコード
.envファイルの変更
#本番モード APP_ENV=prod APP_DEBUG=0 ↓ #デバッグモード APP_ENV=dev APP_DEBUG=1
テンプレートに追記するコード
Prodect関連の配列や値を確認したい場合。以下のコードをTWIGテンプレートに追記すると配列の内容が画面上に表示されます。
{{dump(Product)}}
参考ページ
作成したソース
<script>
$(function () {
$('#RelatedProduct-product_area').appendTo($('.ec-layoutRole__main, .ec-layoutRole__mainWithColumn, .ec-layoutRole__mainBetweenColumn'));
});
</script>
<div id="RelatedProduct-product_area" class="ec-shelfRole">
<h3>関連商品</h3>
<table class="table table-striped table-hover rp-list-table">
<thead>
<tr>
<td>商品コード</td><td>商品名</td><td>金額<small>(税込)</small></td><td>数量</td><td>カート</td>
</tr>
</thead>
<tbody>
{% for RelatedProduct in Product.RelatedProducts %}
{% set ChildProduct = RelatedProduct.ChildProduct %}
{% if ChildProduct.Status.id == constant("Eccube\\Entity\\Master\\ProductStatus::DISPLAY_SHOW") %}
<tr class="ec-productRole__actions test">
<form name="form{{ ChildProduct.id }}" id="productForm{{ ChildProduct.id }}" action="{{ url('product_add_cart', {id:ChildProduct.id}) }}" method="post">
<td><a href="{{ url('product_detail', {id : ChildProduct.id}) }}">{{ RelatedProduct.ChildProduct.code_min }}</a></td>
<td>{{ RelatedProduct.ChildProduct.name }}{% for ChildProductClass in ChildProduct.ProductClasses %} <small>(デバッグ用ClassID:{{ChildProductClass.id }})</small>{% endfor %}</td>
<td>
{% if RelatedProduct.ChildProduct.hasProductClass %}
{% if RelatedProduct.ChildProduct.getPrice02Min == RelatedProduct.ChildProduct.getPrice02Max %}
{{ RelatedProduct.ChildProduct.getPrice02IncTaxMin|price }}
{% else %}
{{ RelatedProduct.ChildProduct.getPrice02IncTaxMin|price }} ~ {{ RelatedProduct.ChildProduct.getPrice02IncTaxMax|price }}
{% endif %}
{% else %}
{{ RelatedProduct.ChildProduct.getPrice02IncTaxMin|price }}
{% endif %}
</td>
<td class="ec-numberInput"><input type="number" id="quantity{{ ChildProduct.id }}" name="quantity" required="required" min="1" maxlength="9" class="quantity form-control" value="1"></td>
<td><div class="ec-productRole__btn">
<button class="ec-blockBtn--action add-cart" data-cartid="{{ ChildProduct.id }}" form="productForm{{ ChildProduct.id }}" type="submit">{{ 'カートに入れる'|trans }}</button>
</div></td>
<!-- エラーになるので非表示 <input type="hidden" id="mode" name="mode" value="add_cart" />-->
<input type="hidden" id="product_id{{ ChildProduct.id }}" name="product_id" value="{{ ChildProduct.id }}">
{% for ChildProductClass in ChildProduct.ProductClasses %}
<input type="hidden" id="ProductClass{{ ChildProduct.id }}" name="ProductClass" value="{{ChildProductClass.id }}">
{% endfor %}
<input type="hidden" id="_token{{ ChildProduct.id }}" name="_token" value="{{ csrf_token('Eccube\\Form\\Type\\AddCartType') }}" />
</form>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
商品詳細ページで使用するときの注意事項
form id="form1"があるとうまく動かない
商品詳細ページにオリジナルのカートボタンを設置する際は、商品詳細ページのテンプレート(detail.twig)にあるメイン商品のカードボタン(<form id="form1">)をコメントアウトするなどして、無効または削除しないと関連商品プラグインのテンプレート(related_product.twig)に追加設置したカートボタンで商品がカートに入りませんでした。どうやらform1が優先されるみたいです。
モーダルがうまく動かないとき
「カートに入れる」ボタンを押したときに表示されていたモーダルウィンドウが表示されなくなってしまったときは、商品一覧のテンプレート(list.twig)を参考に商品詳細ページのテンプレート(detail.twig)にある以下の部分を変更したら動きました。これがモーダルウィンドウ(ec-modal)を発火させるトリガーの要素の指定みたいです。
$form = $('#form1');
↓
var $form = $(this).parents('.test').find('form');
この上あたりにある規格チェックや数量チェックの一部JSが邪魔してうまく修正できなかったので、そのチェック部分はコメントアウトしました。
その他参考ページ