-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathproduct.html.twig
More file actions
140 lines (122 loc) · 6.47 KB
/
Copy pathproduct.html.twig
File metadata and controls
140 lines (122 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
{% extends 'base.html.twig' %}
{% set ogImages = getImagesData({
source_id: attr('product', 'id'),
source_type: 'product',
filters: 'default',
limit: 1,
}) %}
{% block og_image %}{{ ((ogImages|first)?.sources|first)?.url ?: parent() }}{% endblock %}
{% block og_type %}product{% endblock %}
{% block body %}
{% set productId = attr('product', 'id') %}
{% set product = resources('/api/front/products/' ~ productId) %}
{# The accessories the merchant picked for this product. The product resource carries none,
so they are read through the core loop, which answers them in the picked order. Read once
into a variable: the strip below is rendered only when there is something to show. #}
{% set accessoryIds = loop('accessories', 'accessory', {product: productId, visible: 1, limit: 8})|map(accessory => accessory.ACCESSORY_ID) %}
{# Cross-selling browses the category the product is filed under by default. #}
{% set defaultCategory = product.productCategories|filter(productCategory => productCategory.defaultCategory)|first.category|default(null) %}
{# The brand of a product reaches its own resource with its position only, so the brand is
read here — filtered on visibility, since a brand the merchant hid has no page to link to. #}
{% set brand = resources('/api/front/brands', {'products.id': productId, visible: true})|first|default(null) %}
{{ theme_hook('product.top', {product: product}) }}
<div class="ProductPage">
<div class="pt-2 pb-3 md:pt-5 md:pl-5">
<twig:Molecules:Breadcrumb:Base :items="breadcrumb" />
</div>
<div class="container-l">
<div class="ProductPage-grid">
<twig:Layouts:ProductDetails:Base
:product="product"
:brand="brand"
title="{{ SEOnePageH1()|default(null) ?: attr('product', 'title') }}"
/>
{{ theme_hook('product.details.bottom', {product: product}) }}
<section id="description" class="ProductPage-description">
<twig:Molecules:Accordion:Base id="product-details" multiple>
{% if product.i18ns.description|default('') %}
<twig:Molecules:Accordion:Item value="description" open>
<twig:Molecules:Accordion:Trigger iconClosed="plus" iconOpen="minus">
{{ 'Description'|trans }}
</twig:Molecules:Accordion:Trigger>
<twig:Molecules:Accordion:Content>
<div class="wysiwyg wysiwyg-theme min-w-0">
{{ product.i18ns.description|raw }}
</div>
</twig:Molecules:Accordion:Content>
</twig:Molecules:Accordion:Item>
{% endif %}
{# A free text feature carries its value inline instead of pointing at a
feature_av, and an untranslated one yields an empty title: both are
skipped rather than rendered as a dangling label. #}
{% set features = product.featureProducts|default([])|map(featureProduct => {
label: featureProduct.feature.i18ns.title|default(''),
value: featureProduct.is_free_text|default(false)
? featureProduct.free_text_value|default('')
: featureProduct.featureAv.i18ns.title|default(''),
})|filter(feature => feature.label is not empty and feature.value is not empty) %}
{% if features is not empty %}
<twig:Molecules:Accordion:Item value="features">
<twig:Molecules:Accordion:Trigger iconClosed="plus" iconOpen="minus">
{{ 'Features'|trans }}
</twig:Molecules:Accordion:Trigger>
<twig:Molecules:Accordion:Content>
<dl class="ProductPage-features">
{% for feature in features %}
<dt>{{ feature.label }} :</dt>
<dd>{{ feature.value }}</dd>
{% endfor %}
</dl>
</twig:Molecules:Accordion:Content>
</twig:Molecules:Accordion:Item>
{% endif %}
</twig:Molecules:Accordion:Base>
</section>
</div>
</div>
<div class="container-l">
<twig:Organisms:Blocks:Base itemType="product" itemId="{{ productId }}" />
</div>
{% if accessoryIds is not empty %}
<div class="mt-12">
<twig:Layouts:CrossSelling:Base
:productIds="accessoryIds"
title="{{ 'Accessories'|trans }}"
/>
</div>
{% endif %}
{% if defaultCategory %}
<div class="bg-lighter mt-12">
<twig:Layouts:CrossSelling:Base
:categoryId="defaultCategory.id"
title="{{ 'In the same category'|trans }}"
/>
</div>
{% endif %}
<twig:Layouts:ReinsuranceModule:Base :items="[
{
icon: 'reinsurance-delivery',
strongText: 'Free delivery'|trans,
text: 'For any order over €100'|trans,
linkLabel: 'See conditions'|trans,
link: '#',
},
{
icon: 'reinsurance-payment',
strongText: 'Secure payment'|trans,
text: 'Credit card, Paypal'|trans,
linkLabel: 'See conditions'|trans,
link: '#',
},
{
icon: 'reinsurance-satisfied',
strongText: 'Satisfied or refunded'|trans,
text: 'Exchange or refund offered within 30 days'|trans,
linkLabel: 'See conditions'|trans,
link: '#',
},
]" />
</div>
<twig:Organisms:AddToCartToast:Base />
{{ theme_hook('product.bottom', {product: product}) }}
{% endblock %}