处理模板时发生错误。
The following has evaluated to null or missing:
==> product.images  [in template "3192443#3192485#null" at line 17, column 24]

----
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: productImage = product.images?filter(...  [in template "3192443#3192485#null" at line 17, column 9]
----
1<#if themeDisplay?has_content> 
2	<#assign scopeGroupId = themeDisplay.getScopeGroupId() /> 
3</#if> 
4 
5<#assign channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${scopeGroupId}'") /> 
6 
7<#if channel?has_content> 
8	<#assign channelId = channel.items[0].id /> 
9</#if> 
10 
11<#if (CPDefinition_cProductId.getData())??> 
12	<#assign productId = CPDefinition_cProductId.getData() /> 
13</#if> 
14 
15<#assign 
16	product = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/"+ channelId +"/products/"+ productId +"?accountId=-1&images.accountId=-1&nestedFields=images") 
17	productImage = product.images?filter(item -> item.tags?seq_contains("app icon"))![] 
18/> 
19 
20<#if productImage?has_content> 
21	<#assign productThumbnail = productImage[0].src?split("/o") /> 
22	<#if productThumbnail?has_content && productThumbnail?size gte 2> 
23		<#assign productThumbnail1 = "/o/${productThumbnail[1]}"!"" /> 
24	<#else> 
25		<#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" /> 
26	</#if> 
27<#else> 
28	<#if product.urlImage?has_content> 
29		<#assign productThumbnail = product.urlImage?split("/o") /> 
30		<#if productThumbnail?has_content && productThumbnail?size gte 2> 
31			<#assign productThumbnail1 = "/o/${productThumbnail[1]}"!"" /> 
32		<#else> 
33			<#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" /> 
34		</#if> 
35	<#else> 
36		<#assign productThumbnail1 = "/o/commerce-media/default/?groupId=${scopeGroupId}" /> 
37	</#if> 
38</#if> 
39 
40${productThumbnail1} 

Liferay Portal Security SSO NTLM - Draft
18611318
描述

NTLM (NT LAN Manager) is a suite of Microsoft protocols that provide authentication, integrity, and confidentiality for users. Though Microsoft has adopted Kerberos in modern versions of Windows server, NTLM is still used when authenticating to a workgroup. @product@ supports NTLM v2 authentication. NTLM v2 is more secure and has a stronger authentication process than NTLMv1.
Note: NTLM authentication is deprecated in Liferay 7.1 and may be removed in future versions. Users should migrate to Kerberos.

NTLM (NT LAN Manager) is a suite of Microsoft protocols that provide authentication, integrity, and confidentiality for users. Though Microsoft has adopted Kerberos in modern versions of Windows server, NTLM is still used when authenticating to a workgroup. @product@ supports NTLM v2 authentication. NTLM v2 is more secure and has a stronger authentication process than NTLMv1.
Note: NTLM authentication is deprecated in Liferay 7.1 and may be removed in future versions. Users should migrate to Kerberos.

DEVELOPER
处理模板时发生错误。
The string doesn't match the expected date/time/date-time format. The string to parse was: "0". The expected format was: "yyyy-MM-dd'T'HH:mm:ss'Z'".
The nested reason given follows:
Unparseable date: "0"

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign parsedDate = createDate?datet...  [in template "3192443#3192485#null" at line 58, column 17]
	~ Reached through: #nested  [in template "3192443#3192485#null" in macro "section" at line 243, column 17]
	~ Reached through: @section title=languageUtil.get(local...  [in template "3192443#3192485#null" at line 56, column 1]
----
1<#assign 
2	channel = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels?accountId=-1&filter=name eq 'Marketplace Channel' and siteGroupId eq '${themeDisplay.getScopeGroupId()}'") 
3 
4	product = restClient.get( 
5		"/headless-commerce-delivery-catalog/v1.0/channels/" + channel.items[0].id + 
6		"/products/" + CPDefinition_cProductId.getData() + 
7		"?accountId=-1&nestedFields=categories,productSpecifications,skus&skus.accountId=-1&skus.currencyCode=USD" 
8
9 
10	catalogName = product.catalogName!"" 
11	categories = product.categories![] 
12	createDate = product.createDate!0 
13	productSpecifications = product.productSpecifications![] 
14 
15	liferayVersions = productSpecifications?filter(item -> stringUtil.equals(item.specificationKey, "liferay-version")) 
16	platformOffering = categories?filter(item -> stringUtil.equals(item.vocabulary?replace(" ", "-"), "marketplace-liferay-platform-offering")) 
17
18 
19<#assign 
20	publisherDetailsResponse = restClient.get("/c/publisherdetailses?filter=publisherName eq '${catalogName}'") 
21	redirectPath = "https://marketplace.liferay.com/e/publisher-details/29282497" 
22/> 
23 
24<#if publisherDetailsResponse.items?has_content> 
25	<#assign 
26		publisherDetails = publisherDetailsResponse.items[0] 
27		profileImageURL = publisherDetails.publisherProfileImage?replace("https://", "http://") 
28	/> 
29</#if> 
30 
31<#assign 
32	appDocumentationURL = getSpecificationValue("appdocumentationurl") 
33	appInstallationGuideURL = getSpecificationValue("appinstallationguideurl") 
34	appUsageTerms = getSpecificationValue("appusagetermsurl") 
35	cpuValue = getSpecificationValue("cpu") 
36	developerName = getSpecificationValue("developer-name", catalogName) 
37	publisherURL = (getSpecificationValue("publisherwebsiteurl")?trim?replace(" ", ""))!"" 
38	ramValue = getSpecificationValue("ram") 
39	sourceCode = getSpecificationValue("source-code-url") 
40	supportEmail = getSpecificationValue("supportemailaddress") 
41	supportPhone = getSpecificationValue("supportphone") 
42	type = getSpecificationValue("type")?lower_case 
43
44<@section title = languageUtil.get(locale, "developer")> 
45	<#if publisherDetails?has_content> 
46		<a class = "bg-neutral-8" href = "${redirectPath}/${publisherDetails.id}"> 
47			${developerName} 
48		</a> 
49	<#else> 
50		<a class = "bg-neutral-8" href = "/?developer-name=${developerName}"> 
51			${developerName} 
52		</a> 
53	</#if> 
54</@section> 
55 
56<@section title = languageUtil.get(locale, "publisher-date", "Publisher Date")> 
57	<#if createDate?has_content> 
58		<#assign parsedDate = createDate?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'") /> 
59 
60		<p>${parsedDate?string("MMMM d, yyyy")}</p> 
61	</#if> 
62</@section> 
63 
64<@section title = languageUtil.get(locale, "deployment-method", "Deployment Method")> 
65	<#list platformOffering as offering> 
66		<p>${offering.name}</p> 
67	</#list> 
68</@section> 
69 
70<@section title = languageUtil.get(locale, "app-type", "App Type")> 
71	<#if type == 'client-extension'> Client Extension </#if> 
72	<#if type == 'cloud'> Cloud </#if> 
73	<#if type == 'composite-app'> Composite App </#if> 
74	<#if type == 'dxp'> DXP </#if> 
75	<#if type == 'low-code-configuration'> Low Code Configuration </#if> 
76</@section> 
77 
78<@section title = languageUtil.get(locale, "version")> 
79	${getSpecificationValue("latest-version", "1.0.0")} 
80</@section> 
81 
82<#if liferayVersions?has_content> 
83	<@section title = languageUtil.get(locale, "supported-versions", "Supported Versions")> 
84		<#list liferayVersions as version> 
85			${version.value}<#if version?has_next>, </#if> 
86		</#list> 
87	</@section> 
88</#if> 
89 
90<#if cpuValue?has_content> 
91	<@section title = languageUtil.get(locale, "resource-requirements", "Resource Requirements")> 
92		<p> 
93			<#if cpuValue?has_content> 
94				${cpuValue} 
95				<#assign cpuNumber = cpuValue?number?default(0) /> 
96				<#if cpuValue?eval gt 1> 
97					CPUS 
98				</#if> 
99				<#if cpuValue?eval lt 2> 
100					CPU 
101				</#if> 
102			</#if>, <#if ramValue?has_content>${ramValue} GB RAM</#if> 
103		</p> 
104	</@section> 
105</#if> 
106 
107<@section title = languageUtil.get(locale, "standard-price", "Standard Price")> 
108	<div> 
109		<#assign purchasableSkus = [] /> 
110 
111		<#list product.skus as sku> 
112			<#if sku.purchasable?? && sku.purchasable> 
113				<#assign purchasableSkus = purchasableSkus + [sku] /> 
114			</#if> 
115		</#list> 
116 
117		<#assign standardSku = {} /> 
118 
119		<#list purchasableSkus as sku> 
120			<#assign matched = false /> 
121 
122			<#list sku.skuOptions as opt> 
123				<#if stringUtil.equals(opt.skuOptionValueKey, "standard")> 
124					<#assign 
125						matched = true 
126						standardSku = sku 
127					/> 
128 
129					<#break> 
130				</#if> 
131			</#list> 
132			<#if matched><#break></#if> 
133		</#list> 
134 
135		<#if standardSku.price?? && standardSku.price.price?eval gt 0> 
136			<div class="bg-neutral-8">${standardSku.price.priceFormatted!""}</div> 
137		<#else> 
138			${languageUtil.get(locale, "free", "Free")} 
139		</#if> 
140	</div> 
141</@section> 
142 
143<@section title = languageUtil.get(locale, "help-and-support", "Help and Support")> 
144	<div class="d-flex flex-column mt-4"> 
145		<#if (appDocumentationURL?has_content || appInstallationGuideURL?has_content)> 
146			<div class="d-flex mb-4"> 
147				<span class="support-modal-icon" id="app-documentation"> 
148					<@clay["icon"] symbol="document" /> 
149				</span> 
150 
151				<a class="d-flex support-modal justify-content-between w-100" href="javascript:void(0)" onClick="openInstallationDocsModal();"> 
152					<span class="ml-1 "> 
153						${languageUtil.get(locale, "app-documentation", "App Documentation")} 
154					</span> 
155				</a> 
156			</div> 
157		</#if> 
158 
159		<div class="d-flex mb-4"> 
160			<span class="support-modal-icon" id="publisher-support"> 
161				<@clay["icon"] symbol="envelope-closed" /> 
162			</span> 
163 
164			<a class="d-flex justify-content-between support-modal w-100" href="javascript:void(0)" onClick="openPublisherSupportModal();"> 
165				<span class="ml-1 "> 
166					${languageUtil.get(locale, "publisher-support", "Publisher Support")} 
167				</span> 
168			</a> 
169		</div> 
170 
171		<#if sourceCode?has_content> 
172			<div class="d-flex mb-4"> 
173				<span class="support-link-icon"> 
174					<@clay["icon"] symbol="code" /> 
175				</span> 
176 
177				<a 
178					class="d-flex justify-content-between support-link w-100" 
179					href="${sourceCode}" 
180					target="_blank" 
181
182					<span class="ml-1"> 
183						${languageUtil.get(locale, "source-code", "Source Code")} 
184 
185						<span class="d-none ml-1 support-link-icon-arrow-container"> 
186							<@clay["icon"] className="support-link-icon-arrow" symbol="tap-ahead" /> 
187						</span> 
188					</span> 
189				</a> 
190			</div> 
191		</#if> 
192 
193		<div class="d-flex"> 
194			<span class="support-link-icon"> 
195				<@clay["icon"] symbol="check-square" /> 
196			</span> 
197 
198			<a 
199				class="d-flex justify-content-between support-link w-100" 
200				href="https://marketplace.liferay.com/documents/d/marketplace/end_user_license_agreement-1" 
201				target="_blank"> 
202 
203				<span class="ml-1"> 
204					${languageUtil.get(locale, "eula", "EULA")} 
205 
206					<span class="d-none support-link-icon-arrow-container ml-1"> 
207						<@clay["icon"] className="support-link-icon-arrow" symbol="tap-ahead" /> 
208					</span> 
209				</span> 
210			</a> 
211		</div> 
212	</div> 
213</@section> 
214 
215<@section 
216	showLine = false 
217	title = languageUtil.get(locale, "share-link") 
218
219	<a class="align-items-center d-flex font-weight-bold ml-1 support-link text-primary" href="#copy-share-link" onclick="copyToClipboard(Liferay.ThemeDisplay.getCanonicalURL())"> 
220		<span class="link-icon mr-1"> 
221			<@clay["icon"] symbol="link" /> 
222		</span> 
223		Copy & Share 
224	</a> 
225</@section> 
226 
227<#function getSpecificationValue key default=""> 
228	<#local spec = productSpecifications?filter(productSpecification -> 
229		stringUtil.equals(productSpecification.specificationKey, key)) /> 
230 
231	<#return (spec?first.value)!default /> 
232</#function> 
233 
234<#macro section 
235	title 
236	showLine=true 
237
238	<p> 
239		<strong>${title}</strong> 
240	</p> 
241 
242	<div> 
243		<#nested> 
244	</div> 
245 
246	<#if showLine> 
247		<hr /> 
248	</#if> 
249</#macro> 
250 
251<script ${nonceAttribute}> 
252	function installationDocsModalBody() { 
253		return ` 
254			<#if appDocumentationURL?has_content> 
255				<div class="d-flex flex-row align-items-center mb-3"> 
256					<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:57px;"> 
257						<@clay["icon"] 
258							style="fill:#6B6C7E;" 
259							symbol="document-code" 
260						/> 
261					</span> 
262 
263					<div class="d-flex flex-column" style="min-width: 0;"> 
264						<span class="text-black-50">${languageUtil.get(locale, "app-documentation-url", "App Documentation URL")}</span> 
265 
266						<a class="font-weight-bold" href="${appDocumentationURL}" target="_blank"> 
267						${appDocumentationURL} 
268	</a> 
269					</div> 
270				</div> 
271			</#if> 
272 
273			<#if appInstallationGuideURL?has_content> 
274				<div class="d-flex flex-row align-items-center mb-4"> 
275					<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:57px;"> 
276						<@clay["icon"] 
277							style="fill:#6B6C7E;" 
278							symbol="document" 
279						/> 
280					</span> 
281 
282					<div class="d-flex flex-column" style="min-width: 0;"> 
283						<span class="text-black-50">${languageUtil.get(locale, "app-installation-guide-url", "App Installation Guide URL")}</span> 
284 
285						<a class="font-weight-bold" href="${appInstallationGuideURL}" target="_blank"> 
286${appInstallationGuideURL} 
287	</a> 
288					</div> 
289				</div> 
290			</#if> 
291		`; 
292
293 
294	function publisherSupportModalBody() { 
295		return ` 
296			<div class="align-items-center d-flex flex-row mb-3"> 
297				<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;"> 
298					<#if profileImageURL?? && profileImageURL?length gt 0> 
299						<img src="${profileImageURL}" alt="Publisher Image" style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%;" /> 
300					<#else> 
301						<@clay["icon"] 
302							style="fill:#6B6C7E;" 
303							symbol="picture" 
304						/> 
305					</#if> 
306				</span> 
307 
308				<div class="d-flex flex-column"> 
309					<h3 class="font-weight-bold mb-0"> 
310						${catalogName} 
311					</h3> 
312				</div> 
313			</div> 
314 
315			<#if publisherURL?has_content> 
316				<div class="align-items-center d-flex flex-row mb-3"> 
317				<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;"> 
318						<@clay["icon"] 
319							style="fill:#6B6C7E;" 
320							symbol="globe" 
321						/> 
322					</span> 
323 
324					<div class="d-flex flex-column"> 
325						<span class="text-black-50">${languageUtil.get(locale, "publisher-website", "Publisher Website")}</span> 
326 
327						<a href="${publisherURL}" target="_blank" class="font-weight-bold"> 
328							${publisherURL} 
329						</a> 
330					</div> 
331				</div> 
332			</#if> 
333 
334			<#if supportEmail?has_content> 
335				<div class="align-items-center d-flex flex-row mb-3"> 
336					<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;"> 
337						<@clay["icon"] style="fill:#6B6C7E;"symbol="envelope-closed" /> 
338					</span> 
339 
340					<div class="d-flex flex-column"> 
341						<span class="text-black-50">${languageUtil.get(locale, "support-email", "Support Email")}</span> 
342 
343						<a class="font-weight-bold" href="mailto:${supportEmail}" target="_blank"> 
344							${supportEmail} 
345						</a> 
346					</div> 
347				</div> 
348			</#if> 
349 
350			<#if supportPhone?has_content> 
351				<div class="d-flex flex-row align-items-center mb-3"> 
352					<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;"> 
353						<@clay["icon"] 
354							style="fill:#6B6C7E;" 
355							symbol="phone" 
356						/> 
357					</span> 
358 
359					<div class="d-flex flex-column"> 
360						<span class="text-black-50">${languageUtil.get(locale, "phone")}</span> 
361 
362						<a class="font-weight-bold" href="tel:${supportPhone}" target="_blank"> 
363							${supportPhone} 
364						</a> 
365					</div> 
366				</div> 
367			</#if> 
368		`; 
369
370 
371	function openInstallationDocsModal() { 
372		Liferay.Util.openModal({ 
373			bodyHTML: installationDocsModalBody(), 
374			center: true, 
375			headerHTML: "<h2>Installation Guide</h2>", 
376			size: "md" 
377		}); 
378
379 
380	function openPublisherSupportModal() { 
381		Liferay.Util.openModal({ 
382			bodyHTML: publisherSupportModalBody(), 
383			center: true, 
384			headerHTML: "<h2>Publisher Support Info</h2>", 
385			size: "md" 
386		}); 
387
388</script> 
389 
390<script ${nonceAttribute}> 
391	function copyToClipboard(text) { 
392		if (navigator && navigator.clipboard && navigator.clipboard.writeText) { 
393			navigator.clipboard.writeText(text); 
394 
395			Liferay.Util.openToast({ message: "Copied link to the clipboard" }); 
396
397
398</script> 
399 
400<style ${nonceAttribute}> 
401	.support-link, 
402	.support-modal { 
403		font-size: 16px; 
404
405 
406	.support-link-icon { 
407		color: #0B5FFF;#54555F 
408
409 
410	.support-link-icon-arrow { 
411		height: 12px !important; 
412		width: 12px !important; 
413
414 
415	.support-link:hover, 
416	.support-modal:hover { 
417		transform: translateY(-0.75px); 
418
419 
420	.support-link:hover .support-link-icon-arrow-container { 
421		display: inline-block !important; 
422		transform: rotate(90deg); 
423
424 
425	.support-modal-icon, 
426	.support-modal { 
427		color: #54555F; 
428
429 
430	.support-modal:hover { 
431		color: #272833; 
432
433 
434	.support-svg mask, 
435	.link-arrow mask { 
436		mask-type: alpha; 
437
438	 
439	.tempCSS{ 
440	 min-width: 0; 
441
442</style> 
DEVELOPER
24-11-21 下午6:36
Published date
24-11-21 下午6:36
Published Date
24-11-21 下午6:36
SUPPORTED OFFERINGS
Liferay PaaS
Supported Versions
Resource Requirements
Edition
Enterprise
PRICE
help & support
处理模板时发生错误。
The following has evaluated to null or missing:
==> product.catalogName  [in template "3192443#3192485#null" at line 69, column 23]

----
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: catalogName = product.catalogName  [in template "3192443#3192485#null" at line 69, 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> 
SHARE LINK
Copy & Share

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.