/o//commerce-media/accounts/-1/images/30454912?download=false
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.
The following has evaluated to null or missing:
==> sku.skuOptions [in template "3192443#3192485#null" at line 122, column 32]
----
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: #list sku.skuOptions as opt [in template "3192443#3192485#null" at line 122, column 25]
~ 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 107, 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="${(appUsageTerms?has_content)?then(appUsageTerms, '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:40px;">
257 <@clay["icon"]
258 style="fill:#6B6C7E;"
259 symbol="document-code"
260 />
261 </span>
262
263 <div class="d-flex flex-column">
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:40px;">
276 <@clay["icon"]
277 style="fill:#6B6C7E;"
278 symbol="document"
279 />
280 </span>
281
282 <div class="d-flex flex-column">
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</style>
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.