app/template/default/Block/category_nav_sp.twig line 1

Open in your IDE?
  1. {#
  2. This file is part of EC-CUBE
  3. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  4. http://www.ec-cube.co.jp/
  5. For the full copyright and license information, please view the LICENSE
  6. file that was distributed with this source code.
  7. #}
  8. {# ============================================================
  9. カテゴリナビゲーション(SP版)
  10. 機能:
  11. - カテゴリ一覧をツリー構造で表示
  12. - 在庫切れカテゴリの表示/非表示切り替え対応
  13. - カウント表示の動的切り替え対応(全商品数/在庫あり商品数)
  14. ============================================================ #}
  15. {# データ取得 #}
  16. {% set Categories = repository('Eccube\\Entity\\Category').getList() %}
  17. {% set CategoriesCount = repository('Eccube\\Entity\\Product').findProductsWithCategoriesCount() %}
  18. {% set CategoriesCountInStock = repository('Eccube\\Entity\\Product').findProductsWithCategoriesCountInStock() %}
  19. {% set Makers = repository('Plugin\\Maker42\\Entity\\Maker').findBy({}, {sort_no: 'desc' }, 5) %}
  20. {# ============================================================
  21. マクロ: hasStockInTree
  22. 目的: カテゴリまたはその子孫カテゴリに在庫あり商品があるか判定
  23. 引数:
  24. - Category: 判定対象のカテゴリエンティティ
  25. - CategoriesCountInStock: カテゴリごとの在庫あり商品数の配列
  26. 戻り値: 'true' または 'false' (文字列)
  27. ロジック:
  28. 1. 該当カテゴリ自体に在庫あり商品があれば 'true'
  29. 2. なければ子カテゴリを再帰的にチェック
  30. 3. 子孫のどこかに在庫があれば 'true'、なければ 'false'
  31. ============================================================ #}
  32. {% macro hasStockInTree(Category, CategoriesCountInStock) %}
  33.     {%- if CategoriesCountInStock[Category.id] is defined and CategoriesCountInStock[Category.id] > 0 -%}
  34.         true
  35.     {%- else -%}
  36.         {%- set found = 'false' -%}
  37.         {%- for ChildCategory in Category.children -%}
  38.             {%- if _self.hasStockInTree(ChildCategory, CategoriesCountInStock)|trim == 'true' -%}
  39.                 {%- set found = 'true' -%}
  40.             {%- endif -%}
  41.         {%- endfor -%}
  42.         {{ found }}
  43.     {%- endif -%}
  44. {% endmacro %}
  45. {# ============================================================
  46. マクロ: hasProductInTree
  47. 目的: カテゴリまたはその子孫カテゴリに商品があるか判定
  48. 引数:
  49. - Category: 判定対象のカテゴリエンティティ
  50. - CategoriesCount: カテゴリごとの全商品数の配列
  51. 戻り値: 'true' または 'false' (文字列)
  52. ロジック:
  53. 1. 該当カテゴリ自体に商品があれば 'true'
  54. 2. なければ子カテゴリを再帰的にチェック
  55. 3. 子孫のどこかに商品があれば 'true'、なければ 'false'
  56. ============================================================ #}
  57. {% macro hasProductInTree(Category, CategoriesCount) %}
  58.     {%- if CategoriesCount[Category.id] is defined and CategoriesCount[Category.id] > 0 -%}
  59.         true
  60.     {%- else -%}
  61.         {%- set found = 'false' -%}
  62.         {%- for ChildCategory in Category.children -%}
  63.             {%- if _self.hasProductInTree(ChildCategory, CategoriesCount)|trim == 'true' -%}
  64.                 {%- set found = 'true' -%}
  65.             {%- endif -%}
  66.         {%- endfor -%}
  67.         {{ found }}
  68.     {%- endif -%}
  69. {% endmacro %}
  70. {# ============================================================
  71. マクロ: tree
  72. 目的: カテゴリを再帰的にツリー表示
  73. 引数:
  74. - Category: 表示対象のカテゴリエンティティ
  75. - CategoriesCount: カテゴリごとの全商品数の配列
  76. - CategoriesCountInStock: カテゴリごとの在庫あり商品数の配列
  77. 出力するHTML属性:
  78. - data-count-all: 全商品数(JS用)
  79. - data-count-stock: 在庫あり商品数(JS用)
  80. - data-has-stock: 在庫有無フラグ(JS用)
  81. - no-stock-category: 在庫なしカテゴリのCSSクラス
  82. ============================================================ #}
  83. {% macro tree(Category, CategoriesCount, CategoriesCountInStock) %}
  84.     {% from _self import tree, hasStockInTree, hasProductInTree %}
  85.     {# カウント値を取得(未定義の場合は0) #}
  86.     {% set countAll = CategoriesCount[Category.id] is defined ? CategoriesCount[Category.id] : 0 %}
  87.     {% set countStock = CategoriesCountInStock[Category.id] is defined ? CategoriesCountInStock[Category.id] : 0 %}
  88.     {# カテゴリリンク
  89.     - data-count-all: JSで全商品数表示に切り替える際に使用
  90.     - data-count-stock: JSで在庫あり商品数表示に切り替える際に使用
  91.     - js-category-count: JSでカウント表示を更新するためのクラス #}
  92.     <a class="fs-6 js-category-link-sp" href="{{ url('product_list') }}?category_id={{ Category.id }}" data-count-all="{{ countAll }}" data-count-stock="{{ countStock }}">
  93.         {% if (Category.Parent == "") %}
  94.             <img class="menu-icon" src="/html/user_data/assets/img/category/{{ Category.id }}.png" alt="{{ Category.name }}">
  95.         {% endif %}
  96.         <span class="category-text">{{ Category.name }} (<span class="js-category-count">{{ countAll|number_format }}</span>)</span>
  97.     </a>
  98.     {% if Category.children|length > 0 %}
  99.         <ul>
  100.             {% for ChildCategory in Category.children %}
  101.                 {# 子カテゴリの在庫判定(子孫含む) #}
  102.                 {% set childHasStock = hasStockInTree(ChildCategory, CategoriesCountInStock)|trim %}
  103.                 {# 子カテゴリの商品有無判定(子孫含む) #}
  104.                 {% set childHasProduct = hasProductInTree(ChildCategory, CategoriesCount)|trim %}
  105.                 {# no-stock-category: 在庫なしカテゴリを非表示にするためのクラス
  106.                 no-product-category: 商品なしカテゴリを常に非表示にするためのクラス
  107.                 data-has-stock: JSで在庫状態を判定するための属性 #}
  108.                 <li class="{% if childHasStock == 'false' %}no-stock-category {% endif %}{% if childHasProduct == 'false' %}no-product-category{% endif %}" data-has-stock="{{ childHasStock }}">
  109.                     {{ tree(ChildCategory, CategoriesCount, CategoriesCountInStock) }}
  110.                 </li>
  111.             {% endfor %}
  112.         </ul>
  113.     {% endif %}
  114. {% endmacro %}
  115. {# マクロのインポート @see https://github.com/bolt/bolt/pull/2388 #}
  116. {% from _self import tree, hasStockInTree, hasProductInTree %}
  117. {# ============================================================
  118. カテゴリナビゲーション本体
  119. ============================================================ #}
  120. <div class="ec-headerCategoryArea">
  121.     <div class="ec-headerCategoryArea__heading">
  122.         <p>{{ 'カテゴリ一覧'|trans }}</p>
  123.     </div>
  124.     <div class="ec-itemNav">
  125.         <ul class="ec-itemNav__nav">
  126.             {% for Category in Categories %}
  127.                 {# 在庫判定(子孫含む) #}
  128.                 {% set hasStock = hasStockInTree(Category, CategoriesCountInStock)|trim %}
  129.                 {# 商品有無判定(子孫含む) #}
  130.                 {% set hasProduct = hasProductInTree(Category, CategoriesCount)|trim %}
  131.                 {# トップレベルカテゴリのli要素
  132.                 - no-stock-category: 在庫なしの場合に付与(JSで表示/非表示制御)
  133.                 - no-product-category: 商品なしの場合に付与(常に非表示)
  134.                 - data-has-stock: 在庫状態フラグ #}
  135.                 <li class="{% if hasStock == 'false' %}no-stock-category {% endif %}{% if hasProduct == 'false' %}no-product-category{% endif %}" data-has-stock="{{ hasStock }}">
  136.                     {{ tree(Category, CategoriesCount, CategoriesCountInStock) }}
  137.                 </li>
  138.             {% endfor %}
  139.         </ul>
  140.     </div>
  141.     <div class="ec-headerCategoryArea__heading">
  142.         <p>{{ 'メーカー一覧'|trans }}</p>
  143.     </div>
  144.     <div class="ec-itemNav maker_list">
  145.         <ul class="ec-itemNav__nav">
  146.             {% for Maker in Makers %}
  147.                 <li><a class='fs-6' href="{{ url('product_list') }}?maker_id={{ Maker.id }}">{{ Maker.name }}</a></li>
  148.             {% endfor %}
  149.         </ul>
  150.         <div class='py-2 px-2'>
  151.             <a href="{{ url('maker') }}"><button class='metroFamilyOrder-button01' type='button'>一覧を見る</button></a>
  152.         </div>
  153.     </div>
  154. </div>