app/template/default/Block/category_nav_pc.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. カテゴリナビゲーション(PC版)
  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. {# ============================================================
  20. マクロ: hasStockInTree
  21. 目的: カテゴリまたはその子孫カテゴリに在庫あり商品があるか判定
  22. 引数:
  23. - Category: 判定対象のカテゴリエンティティ
  24. - CategoriesCountInStock: カテゴリごとの在庫あり商品数の配列
  25. 戻り値: 'true' または 'false' (文字列)
  26. ロジック:
  27. 1. 該当カテゴリ自体に在庫あり商品があれば 'true'
  28. 2. なければ子カテゴリを再帰的にチェック
  29. 3. 子孫のどこかに在庫があれば 'true'、なければ 'false'
  30. ============================================================ #}
  31. {% macro hasStockInTree(Category, CategoriesCountInStock) %}
  32.     {%- if CategoriesCountInStock[Category.id] is defined and CategoriesCountInStock[Category.id] > 0 -%}
  33.         true
  34.     {%- else -%}
  35.         {%- set found = 'false' -%}
  36.         {%- for ChildCategory in Category.children -%}
  37.             {%- if _self.hasStockInTree(ChildCategory, CategoriesCountInStock)|trim == 'true' -%}
  38.                 {%- set found = 'true' -%}
  39.             {%- endif -%}
  40.         {%- endfor -%}
  41.         {{ found }}
  42.     {%- endif -%}
  43. {% endmacro %}
  44. {# ============================================================
  45. マクロ: hasProductInTree
  46. 目的: カテゴリまたはその子孫カテゴリに商品があるか判定
  47. 引数:
  48. - Category: 判定対象のカテゴリエンティティ
  49. - CategoriesCount: カテゴリごとの全商品数の配列
  50. 戻り値: 'true' または 'false' (文字列)
  51. ロジック:
  52. 1. 該当カテゴリ自体に商品があれば 'true'
  53. 2. なければ子カテゴリを再帰的にチェック
  54. 3. 子孫のどこかに商品があれば 'true'、なければ 'false'
  55. ============================================================ #}
  56. {% macro hasProductInTree(Category, CategoriesCount) %}
  57.     {%- if CategoriesCount[Category.id] is defined and CategoriesCount[Category.id] > 0 -%}
  58.         true
  59.     {%- else -%}
  60.         {%- set found = 'false' -%}
  61.         {%- for ChildCategory in Category.children -%}
  62.             {%- if _self.hasProductInTree(ChildCategory, CategoriesCount)|trim == 'true' -%}
  63.                 {%- set found = 'true' -%}
  64.             {%- endif -%}
  65.         {%- endfor -%}
  66.         {{ found }}
  67.     {%- endif -%}
  68. {% endmacro %}
  69. {# ============================================================
  70. マクロ: tree
  71. 目的: カテゴリを再帰的にツリー表示
  72. 引数:
  73. - Category: 表示対象のカテゴリエンティティ
  74. - CategoriesCount: カテゴリごとの全商品数の配列
  75. - CategoriesCountInStock: カテゴリごとの在庫あり商品数の配列
  76. 出力するHTML属性:
  77. - data-count-all: 全商品数(JS用)
  78. - data-count-stock: 在庫あり商品数(JS用)
  79. - data-has-stock: 在庫有無フラグ(JS用)
  80. - no-stock-category: 在庫なしカテゴリのCSSクラス
  81. ============================================================ #}
  82. {% macro tree(Category, CategoriesCount, CategoriesCountInStock) %}
  83.     {% from _self import tree, hasStockInTree, hasProductInTree %}
  84.     {# カウント値を取得(未定義の場合は0) #}
  85.     {% set countAll = CategoriesCount[Category.id] is defined ? CategoriesCount[Category.id] : 0 %}
  86.     {% set countStock = CategoriesCountInStock[Category.id] is defined ? CategoriesCountInStock[Category.id] : 0 %}
  87.     {# カテゴリリンク
  88.     - data-count-all: JSで全商品数表示に切り替える際に使用
  89.     - data-count-stock: JSで在庫あり商品数表示に切り替える際に使用
  90.     - js-category-count: JSでカウント表示を更新するためのクラス #}
  91.     <a class="left-menu-link js-category-link" href="{{ url('product_list') }}?category_id={{ Category.id }}" data-count-all="{{ countAll }}" data-count-stock="{{ countStock }}">
  92.     {# トップレベルカテゴリのみアイコン表示 #}
  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.     {# 子カテゴリがある場合、サブメニューを表示 #}
  99.     {% if Category.children|length > 0 %}
  100.         {% set childCount = Category.children|length %}
  101.         {# 子カテゴリ数に応じてカラム表示クラスを設定
  102.         - 16個以上: 3列表示
  103.         - 8-15個: 2列表示
  104.         - 7個以下: 1列表示
  105.         ※ 孫カテゴリ以降は常に1列 #}
  106.         {% if Category.Parent == "" %}
  107.             {# トップレベルカテゴリの子(1階層目) #}
  108.             {% if childCount >= 16 %}
  109.                 {% set submenuClass = 'js-submenu-three-column' %}
  110.             {% elseif childCount >= 8 %}
  111.                 {% set submenuClass = 'js-submenu-two-column' %}
  112.             {% else %}
  113.                 {% set submenuClass = '' %}
  114.             {% endif %}
  115.         {% elseif Category.Parent.Parent == "" %}
  116.             {# 2階層目(孫カテゴリ)は常に1列 #}
  117.             {% set submenuClass = '' %}
  118.         {% else %}
  119.             {# 3階層目以降も常に1列 #}
  120.             {% set submenuClass = '' %}
  121.         {% endif %}
  122.         <ul class="{{ submenuClass }}" data-child-count="{{ childCount }}">
  123.             {% for ChildCategory in Category.children %}
  124.                 {# 子カテゴリの在庫判定(子孫含む) #}
  125.                 {% set childHasStock = hasStockInTree(ChildCategory, CategoriesCountInStock)|trim %}
  126.                 {# 子カテゴリの商品有無判定(子孫含む) #}
  127.                 {% set childHasProduct = hasProductInTree(ChildCategory, CategoriesCount)|trim %}
  128.                 {# no-stock-category: 在庫なしカテゴリを非表示にするためのクラス
  129.                 no-product-category: 商品なしカテゴリを常に非表示にするためのクラス
  130.                 data-has-stock: JSで在庫状態を判定するための属性 #}
  131.                 <li class="{% if childHasStock == 'false' %}no-stock-category {% endif %}{% if childHasProduct == 'false' %}no-product-category{% endif %}" data-has-stock="{{ childHasStock }}">
  132.                 {{ tree(ChildCategory, CategoriesCount, CategoriesCountInStock) }}
  133.             </li>
  134.         {% endfor %}
  135.         </ul>
  136.     {% endif %}
  137. {% endmacro %}
  138. {# マクロのインポート @see https://github.com/bolt/bolt/pull/2388 #}
  139. {% from _self import tree, hasStockInTree, hasProductInTree %}
  140. {# ============================================================
  141. カテゴリナビゲーション本体
  142. ============================================================ #}
  143. <div class="category_list">
  144.     <dl>
  145.         <dt>カテゴリ一覧</dt>
  146.     </dl>
  147. </div>
  148. <div class="ec-categoryNaviRole">
  149.     <div class="ec-itemNav">
  150.         <ul class="ec-itemNav__nav">
  151.             {% for Category in Categories %}
  152.                 {# トップレベルカテゴリの子カテゴリ数に応じてクラスを設定 #}
  153.                 {% set topChildCount = Category.children|length %}
  154.                 {% if topChildCount >= 16 %}
  155.                     {% set topLevelClass = 'js-has-very-many-children' %}
  156.                 {% elseif topChildCount >= 8 %}
  157.                     {% set topLevelClass = 'js-has-many-children' %}
  158.                 {% else %}
  159.                     {% set topLevelClass = '' %}
  160.                 {% endif %}
  161.                 {# 在庫判定(子孫含む) #}
  162.                 {% set hasStock = hasStockInTree(Category, CategoriesCountInStock)|trim %}
  163.                 {# 商品有無判定(子孫含む) #}
  164.                 {% set hasProduct = hasProductInTree(Category, CategoriesCount)|trim %}
  165.                 {# トップレベルカテゴリのli要素
  166.                 - no-stock-category: 在庫なしの場合に付与(JSで表示/非表示制御)
  167.                 - no-product-category: 商品なしの場合に付与(常に非表示)
  168.                 - data-has-stock: 在庫状態フラグ #}
  169.                 <li class="{{ topLevelClass }}{% if hasStock == 'false' %} no-stock-category{% endif %}{% if hasProduct == 'false' %} no-product-category{% endif %}" data-child-count="{{ topChildCount }}" data-has-stock="{{ hasStock }}">
  170.                     {{ tree(Category, CategoriesCount, CategoriesCountInStock) }}
  171.                 </li>
  172.             {% endfor %}
  173.         </ul>
  174.     </div>
  175. </div>