/o//commerce-media/accounts/-1/images/18557514?download=true
Septem layout templates is pack of 40+ responsive layout templates
for Liferay 7. 119 templates in total.
Exactly 41 responsive layout templates and each layout template
rows could be stacked differently depending on client device
resolution. So for example you could choose 2 columns layout where
rows stacks under each other when client has mobile phone (his
resolution is lower or equal to 767 pixels) or you could choose
stacking when client resolution is lower or equal to 991 pixels which
is typical for tables or desktop resolution stacking which is lower or
equal to 1199 pixels. So you could choose from 119 layout templates in total.
The following has evaluated to null or missing: ==> channel.items [in template "3192443#3192485#null" at line 63, column 30] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign channelId = channel.items[0].id [in template "3192443#3192485#null" at line 63, column 9] ----
1<style>
2 .help-and-support-link {
3 color: inherit;
4 cursor: pointer;
5 text-decoration: none;
6 }
7
8 .help-and-support-link:hover {
9 color: inherit;
10 text-decoration: none;
11 }
12
13 .help-and-support-link-icon {
14 color: rgb(133, 140, 148);
15 }
16
17 .help-and-support-link-arrow {
18 fill: rgb(133, 140, 148);
19 }
20</style>
21
22<#if (_CUSTOM_FIELD_Documentation.getData())?has_content && (_CUSTOM_FIELD_Documentation.getData())?starts_with("https")>
23 <a class="bg-whiteColor pb-2 pl-4 pr-4 pt-2" href="${_CUSTOM_FIELD_Documentation.getData()}" style="border-color: var(--neutral-9);border-style: solid; border-width: 0 0 2px 0;align-items:center;color:var(--body-color);cursor:pointer;display:flex;justify-content:space-between;text-decoration:none;" target="_blank">
24 <svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="doc" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="1" width="12" height="14"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.673 2.666c0-.733.594-1.333 1.327-1.333h4.78c.353 0 .693.14.94.393l3.22 3.22c.253.247.393.587.393.94v7.447c0 .733-.6 1.333-1.333 1.333H3.993c-.733 0-1.326-.6-1.326-1.333l.006-10.667Zm5.994-.333v3c0 .367.3.667.666.667h3L8.667 2.333Z" fill="#000"/></mask><g mask="url(#doc)"><path fill="var(--neutral-5)" d="M0 0h16v16H0z"/></g></svg>
25
26 <span class="copy-text ml-1">${languageUtil.get(locale, "installation-documentation", "Installation Documentation")}</span>
27
28 <svg class="link-arrow" style="margin-left:auto;" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="arrow" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="5" y="4" width="6" height="8"><path d="m6 10.584 2.587-2.587L6 5.41a.664.664 0 1 1 .94-.94L10 7.53c.26.26.26.68 0 .94l-3.06 3.06c-.26.26-.68.26-.94 0a.678.678 0 0 1 0-.946Z" fill="#000"/></mask><g mask="url(#arrow)"><path fill="var(--neutral-5)" d="M0 0h16v16H0z"/></g></svg>
29 </a>
30</#if>
31
32<#if (_CUSTOM_FIELD_Source.getData())?has_content && (_CUSTOM_FIELD_Source.getData())?starts_with("https")>
33 <a class="bg-whiteColor pb-2 pl-4 pr-4 pt-2" href="${_CUSTOM_FIELD_Source.getData()}" style="border-color: var(--neutral-9);border-style: solid; border-width: 0 0 2px 0;align-items:center;color:var(--body-color);cursor:pointer;display:flex;justify-content:space-between;text-decoration:none;" target="_blank">
34 <svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="code" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="1" y="4" width="14" height="8"><path fill-rule="evenodd" clip-rule="evenodd" d="m12.8 8-2.6 2.6a.656.656 0 0 0 0 .933c.26.26.673.26.933 0l3.06-3.067c.26-.26.26-.68 0-.94l-3.06-3.06a.656.656 0 0 0-.933 0 .656.656 0 0 0 0 .934L12.8 8ZM3.2 8l2.6 2.6c.26.26.26.673 0 .933a.656.656 0 0 1-.933 0l-3.06-3.067a.664.664 0 0 1 0-.94l3.06-3.06a.656.656 0 0 1 .933 0c.26.26.26.674 0 .934L3.2 8Z" fill="#000"/></mask><g mask="url(#code)"><path fill="var(--neutral-5)" d="M0 0h16v16H0z"/></g></svg>
35
36 <span class="copy-text ml-1">${languageUtil.get(locale, "source-code", "Source Code")}</span>
37
38 <svg class="link-arrow" style="margin-left:auto;" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="arrow" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="5" y="4" width="6" height="8"><path d="m6 10.584 2.587-2.587L6 5.41a.664.664 0 1 1 .94-.94L10 7.53c.26.26.26.68 0 .94l-3.06 3.06c-.26.26-.68.26-.94 0a.678.678 0 0 1 0-.946Z" fill="#000"/></mask><g mask="url(#arrow)"><path fill="var(--neutral-5)" d="M0 0h16v16H0z"/></g></svg>
39 </a>
40</#if>
41
42<#if (_CUSTOM_FIELD_Support.getData())?has_content && (_CUSTOM_FIELD_Terms.getData())?starts_with("https")>
43 <a class="bg-whiteColor pb-2 pl-4 pr-4 pt-2" href="${_CUSTOM_FIELD_Terms.getData()}" style="border-color: var(--neutral-9);border-style: solid; border-width: 0 0 2px 0;align-items:center;color:var(--body-color);cursor:pointer;display:flex;justify-content:space-between;text-decoration:none;" target="_blank">
44 <svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="support" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="1" width="12" height="14"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 1.333A5.67 5.67 0 0 0 2.333 7 5.67 5.67 0 0 0 8 12.666h.333v2C11.573 13.106 13.667 10 13.667 7A5.67 5.67 0 0 0 8 1.333ZM7.333 11V9.666h1.334V11H7.333Zm1.58-3.154c.007-.013.014-.026.02-.033.182-.266.435-.488.69-.712.592-.519 1.202-1.053.997-2.188-.193-1.127-1.093-2.053-2.22-2.22a2.668 2.668 0 0 0-2.953 1.86.61.61 0 0 0 .58.78h.133c.273 0 .493-.193.587-.433.213-.594.84-1 1.533-.854.64.134 1.107.767 1.047 1.42-.045.51-.41.79-.813 1.103-.251.195-.519.402-.734.684l-.007-.007c-.011.012-.02.028-.03.044-.007.013-.015.025-.023.036-.01.017-.022.034-.033.05l-.034.05c-.06.094-.106.187-.146.294a.104.104 0 0 1-.017.033.104.104 0 0 0-.017.033c-.006.007-.006.014-.006.02-.08.24-.134.527-.134.867h1.34a1.406 1.406 0 0 1 .12-.593.239.239 0 0 1 .027-.074c.027-.053.06-.106.093-.16Z" fill="#000"/></mask><g mask="url(#support)"><path fill="var(--neutral-5)" d="M0 0h16v16H0z"/></g></svg>
45
46 <span class="copy-text ml-1">${languageUtil.get(locale, "support-levels-and-informations", "Support Levels & Information")}</span>
47
48 <svg class="link-arrow" style="margin-left:auto;" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="arrow" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="5" y="4" width="6" height="8"><path d="m6 10.584 2.587-2.587L6 5.41a.664.664 0 1 1 .94-.94L10 7.53c.26.26.26.68 0 .94l-3.06 3.06c-.26.26-.68.26-.94 0a.678.678 0 0 1 0-.946Z" fill="#000"/></mask><g mask="url(#arrow)"><path fill="var(--neutral-5)" d="M0 0h16v16H0z"/></g></svg>
49 </a>
50</#if>
51
52<#if (CPDefinition_cProductId.getData())??>
53 <#assign productId = CPDefinition_cProductId.getData() />
54</#if>
55
56<#if themeDisplay?has_content>
57 <#assign scopeGroupId = themeDisplay.getScopeGroupId() />
58</#if>
59
60<#assign channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") />
61
62<#if channel?has_content>
63 <#assign channelId = channel.items[0].id />
64</#if>
65
66<#assign
67 productId = CPDefinition_cProductId.getData()
68 product = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&images.accountId=-1&nestedFields=categories,images,productSpecifications")
69 catalogName = product.catalogName
70 productImage = product.images![]
71 solutionHeaderImages = productImage?filter(image -> image.tags?seq_contains("app icon"))
72/>
73
74<#if product.productSpecifications?has_content>
75 <#assign
76 productSpecifications = product.productSpecifications
77 publisherUrlFiltered = productSpecifications?filter(specification -> stringUtil.equals(specification.specificationKey, "publisherwebsiteurl"))
78 supportEmailFiltered = productSpecifications?filter(specification -> stringUtil.equals(specification.specificationKey, "supportemailaddress"))
79 supportPhoneFiltered = productSpecifications?filter(specification -> stringUtil.equals(specification.specificationKey, "supportphone"))
80 />
81
82 <#if supportEmailFiltered?has_content>
83 <#assign
84 supportEmail = supportEmailFiltered[0].value
85 />
86 </#if>
87
88 <#if publisherUrlFiltered?has_content>
89 <#assign publisherUrl = publisherUrlFiltered[0].value?trim?replace(' ', '') />
90
91 <#if publisherUrl?starts_with("http://") || publisherUrl?starts_with("https://")>
92 <#assign sanitizedUrl = publisherUrl />
93 <#else>
94 <#assign sanitizedUrl = "https://" + publisherUrl />
95 </#if>
96 </#if>
97
98 <#if supportPhoneFiltered?has_content>
99 <#assign
100 supportPhone = supportPhoneFiltered[0].value
101 />
102 </#if>
103</#if>
104
105<div class="d-flex flex-column">
106 <div class="d-flex mb-3">
107 <span class="help-and-support-link-icon">
108 <@clay["icon"] symbol="envelope-closed" />
109 </span>
110
111 <a class="d-flex help-and-support-link justify-content-between w-100" id="help-and-support-link-contact-button" onClick="openModal()">
112 <span class="copy-text help-and-support-link ml-1">
113 ${languageUtil.get(locale, "publisher-support", "Publisher Support")}
114 </span>
115
116 <svg class="link-arrow help-and-support-link-arrow" fill="none" height="16" style="margin-left: auto" width="16" xmlns="http://www.w3.org/2000/svg">
117 <mask height="8"id="arrow" maskUnits="userSpaceOnUse" style="mask-type: alpha" width="6" x="5" y="4">
118 <path d="m6 10.584 2.587-2.587L6 5.41a.664.664 0 1 1 .94-.94L10 7.53c.26.26.26.68 0 .94l-3.06 3.06c-.26.26-.68.26-.94 0a.678.678 0 0 1 0-.946Z" fill="#000" />
119 </mask>
120
121 <g mask="url(#arrow)">
122 <path d="M0 0h16v16H0z" fill="var(--neutral-5)" />
123 </g>
124 </svg>
125 </a>
126 </div>
127
128 <div class="d-flex">
129 <span class="help-and-support-link-icon">
130 <@clay["icon"] symbol="document" />
131 </span>
132
133 <a class="d-flex w-100 justify-content-between help-and-support-link" href="https://www.liferay.com/en/legal/marketplace-terms-of-service" target="_blank">
134 <span class="copy-text ml-1 help-and-support-link">
135 ${languageUtil.get(locale, "terms-and-conditions", "Terms & Conditions")}
136 </span>
137
138 <svg class="link-arrow help-and-support-link-arrow" fill="none" height="16" style="margin-left: auto" width="16" xmlns="http://www.w3.org/2000/svg">
139 <mask height="8"id="arrow" maskUnits="userSpaceOnUse" style="mask-type: alpha" width="6" x="5" y="4">
140 <path d="m6 10.584 2.587-2.587L6 5.41a.664.664 0 1 1 .94-.94L10 7.53c.26.26.26.68 0 .94l-3.06 3.06c-.26.26-.68.26-.94 0a.678.678 0 0 1 0-.946Z" fill="#000" />
141 </mask>
142
143 <g mask="url(#arrow)">
144 <path fill="var(--neutral-5)" d="M0 0h16v16H0z" />
145 </g>
146 </svg>
147 </a>
148 </div>
149</div>
150
151<script>
152 function modalBody(){
153 return `
154 <#if catalogName?has_content>
155 <div class="align-items-center d-flex flex-row mb-3">
156 <span class="align-items-center d-flex justify-content-center modal-icon-background mr-3" style="background: #E2E2E4; border-radius:50%; height:40px; overflow:hidden; width:40px;">
157 <#if solutionHeaderImages?has_content>
158 <#list solutionHeaderImages as image>
159 <#assign imageSourceSplitedUrl = image.src?split("/o") />
160
161 <#if imageSourceSplitedUrl?has_content>
162 <#assign productThumbnail = "/o/${imageSourceSplitedUrl[1]}" />
163
164 <img alt="Slide ${image?index}" class="catalog-icon" src="${productThumbnail}" style="height: 40px; object-fit: contain; width: 40px;">
165 </#if>
166 </#list>
167 <#else>
168 <@clay["icon"]
169 style="fill:#6B6C7E;"
170 symbol="picture"
171 />
172 </#if>
173 </span>
174
175 <div class="d-flex flex-column">
176 <#if catalogName?has_content>
177 <h3 class="font-weight-bold mb-0">
178 ${catalogName}
179 </h3>
180 </#if>
181 </div>
182 </div>
183 </#if>
184
185 <#if sanitizedUrl?has_content && publisherUrl?has_content>
186 <div class="align-items-center d-flex flex-row mb-3">
187 <span class="align-items-center d-flex justify-content-center modal-icon-background mr-3" style="background: #E2E2E4; border-radius:50%; height:40px; width:40px;">
188 <@clay["icon"]
189 style="fill:#6B6C7E;"
190 symbol="globe"
191 />
192 </span>
193
194 <div class="d-flex flex-column">
195 <span class="text-black-50">Publisher website URL</span>
196
197 <a href="${sanitizedUrl}" target="_blank" class="font-weight-bold">
198 ${publisherUrl}
199 </a>
200 </div>
201 </div>
202 </#if>
203
204 <#if supportEmail?has_content>
205 <div class="align-items-center d-flex flex-row mb-3">
206 <span class="align-items-center d-flex justify-content-center modal-icon-background mr-3" style="background: #E2E2E4; border-radius:50%; height:40px; width:40px;">
207 <@clay["icon"] style="fill:#6B6C7E;"symbol="envelope-closed" />
208 </span>
209
210 <div class="d-flex flex-column">
211 <span class="text-black-50">Support Email</span>
212
213 <a class="font-weight-bold" href="mailto:${supportEmail}" target="_blank">
214 ${supportEmail}
215 </a>
216 </div>
217 </div>
218 </#if>
219
220 <#if supportPhone?has_content>
221 <div class="d-flex flex-row align-items-center mb-3">
222 <span class="align-items-center d-flex justify-content-center modal-icon-background mr-3" style="background: #E2E2E4; border-radius:50%; height:40px; width:40px;">
223 <@clay["icon"]
224 style="fill:#6B6C7E;"
225 symbol="phone"
226 />
227 </span>
228
229 <div class="d-flex flex-column">
230 <span class="text-black-50">Phone</span>
231
232 <a class="font-weight-bold" href="tel:${supportPhone}" target="_blank">
233 ${supportPhone}
234 </a>
235 </div>
236 </div>
237 </#if>
238 `
239 }
240
241 function openModal() {
242 Liferay.Util.openModal({
243 bodyHTML:modalBody(),
244 center: true,
245 headerCssClass:"pt-2",
246 headerHTML: "<h2>Publisher Support Contact Info</h2>",
247 size: "md",
248 })
249 }
250
251</script>
HTML Example
A paragraph is a self-contained unit of a discourse in writing dealing with a particular point or idea. Paragraphs are usually an expected part of formal writing, used to organize longer prose.