/o//commerce-media/accounts/-1/images/30455628?download=false
OpenID is a single sign-on standard implemented by multiple vendors.
Users can register for an ID with the vendor they trust. The
credential issued by that vendor can be used by all the web sites that
support OpenID. Some high profile OpenID vendors are Google, Paypal,
Amazon, and Microsoft. Please see the [OpenID site](http://www.openid.net/) for a more complete
list.
Note: OpenID was deprecated in Liferay 7.1 and may be
removed in future versions. Users should migrate to OpenID Connect.
OpenID is a single sign-on standard implemented by multiple vendors.
Users can register for an ID with the vendor they trust. The
credential issued by that vendor can be used by all the web sites that
support OpenID. Some high profile OpenID vendors are Google, Paypal,
Amazon, and Microsoft. Please see the [OpenID site](http://www.openid.net/) for a more complete
list.
Note: OpenID was deprecated in Liferay 7.1 and may be
removed in future versions. Users should migrate to OpenID Connect.
The following has evaluated to null or missing:
==> sku.skuOptions [in template "3192443#3192485#null" at line 116, 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 116, column 25]
~ Reached through: #nested [in template "3192443#3192485#null" in macro "section" at line 208, column 17]
~ Reached through: @section title=languageUtil.get(local... [in template "3192443#3192485#null" at line 101, 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 publisherDetailsResponse = restClient.get("/c/publisherdetailses?filter=publisherName eq '${catalogName}'") />
20<#assign redirectPath="https://marketplace.liferay.com/e/publisher-details/29282497"/>
21
22<#if publisherDetailsResponse.items?has_content>
23 <#assign
24 publisherDetails = publisherDetailsResponse.items[0]
25 profileImageURL = publisherDetails.publisherProfileImage?replace("https://", "http://")
26 />
27</#if>
28
29<#assign
30 appUsageTerms = getSpecificationValue("appusagetermsurl")
31 cpuValue = getSpecificationValue("cpu")
32 developerName = getSpecificationValue("developer-name", catalogName)
33 publisherURL = (getSpecificationValue("publisherwebsiteurl")?trim?replace(" ", ""))!""
34 ramValue = getSpecificationValue("ram")
35 supportEmail = getSpecificationValue("supportemailaddress")
36 supportPhone = getSpecificationValue("supportphone")
37 type = getSpecificationValue("type")?lower_case
38>
39<@section title = languageUtil.get(locale, "developer")>
40 <#if publisherDetails?has_content>
41 <a class="bg-neutral-8" href="${redirectPath}/${publisherDetails.id}">
42 ${developerName}
43 </a>
44 <#else>
45 <a class="bg-neutral-8" href="/?q=${developerName}">
46 ${developerName}
47 </a>
48 </#if>
49</@section>
50
51<@section title=languageUtil.get(locale, "publisher-date", "Publisher Date")>
52 <#if createDate?has_content>
53 <#assign parsedDate = createDate?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'")>
54 <p>${parsedDate?string("MMMM d, yyyy")}</p>
55 </#if>
56</@section>
57
58<@section title = languageUtil.get(locale, "deployment-method", "Deployment Method")>
59 <#list platformOffering as offering>
60 <p>${offering.name}</p>
61 </#list>
62</@section>
63
64<@section title = languageUtil.get(locale, "app-type", "App Type")>
65 <#if type == 'client-extension'> Client Extension </#if>
66 <#if type == 'cloud'> Cloud </#if>
67 <#if type == 'composite-app'> Composite App </#if>
68 <#if type == 'dxp'> DXP </#if>
69 <#if type == 'low-code-configuration'> Low Code Configuration </#if>
70</@section>
71
72<@section title = languageUtil.get(locale, "version")>
73 ${getSpecificationValue("latest-version", "1.0.0")}
74</@section>
75
76<#if liferayVersions?has_content>
77 <@section title = languageUtil.get(locale, "supported-versions", "Supported Versions")>
78 <#list liferayVersions as version>
79 ${version.value}<#if version?has_next>, </#if>
80 </#list>
81 </@section>
82</#if>
83
84<#if cpuValue?has_content>
85 <@section title = languageUtil.get(locale, "resource-requirements", "Resource Requirements")>
86 <p>
87 <#if cpuValue?has_content>
88 ${cpuValue}
89 <#assign cpuNumber = cpuValue?number?default(0) />
90 <#if cpuValue?eval gt 1>
91 CPUS
92 </#if>
93 <#if cpuValue?eval lt 2>
94 CPU
95 </#if>
96 </#if>, <#if ramValue?has_content>${ramValue} GB RAM</#if>
97 </p>
98 </@section>
99</#if>
100
101<@section title = languageUtil.get(locale, "standard-price", "Standard Price")>
102 <div>
103 <#assign purchasableSkus = [] />
104
105 <#list product.skus as sku>
106 <#if sku.purchasable?? && sku.purchasable>
107 <#assign purchasableSkus = purchasableSkus + [sku] />
108 </#if>
109 </#list>
110
111 <#assign standardSku = {} />
112
113 <#list purchasableSkus as sku>
114 <#assign matched = false />
115
116 <#list sku.skuOptions as opt>
117 <#if stringUtil.equals(opt.skuOptionValueKey, "standard")>
118 <#assign
119 matched = true
120 standardSku = sku
121 />
122
123 <#break>
124 </#if>
125 </#list>
126 <#if matched><#break></#if>
127 </#list>
128
129 <#if standardSku.price?? && standardSku.price.price?eval gt 0>
130 <div class="bg-neutral-8">${standardSku.price.priceFormatted!""}</div>
131 <#else>
132 ${languageUtil.get(locale, "free", "Free")}
133 </#if>
134 </div>
135</@section>
136
137<@section title = languageUtil.get(locale, "help-and-support", "Help and Support")>
138 <div class="d-flex flex-column mt-4">
139 <div class="d-flex">
140 <span class="help-and-support-link-icon">
141 <@clay["icon"] symbol="document" />
142 </span>
143
144 <a
145 class="d-flex w-100 justify-content-between help-and-support-link"
146 href="${(appUsageTerms?has_content)?then(appUsageTerms, 'https://www.liferay.com/en/legal/marketplace-terms-of-service')}"
147 target="_blank">
148 <span class="copy-text ml-1 help-and-support-link">
149 ${languageUtil.get(locale, "terms-and-conditions", "Terms & Conditions")}
150 </span>
151
152 <@clay["icon"]
153 className="help-and-support-link-arrow link-arrow ml-auto"
154 height="12"
155 symbol="angle-right"
156 />
157 </a>
158 </div>
159
160 <div class="d-flex">
161 <span class="help-and-support-link-icon">
162 <@clay["icon"] symbol="document" />
163 </span>
164
165 <a class="d-flex w-100 justify-content-between help-and-support-link" href="javascript:void(0)" onClick="openModal()">
166 <span class="copy-text ml-1 help-and-support-link">
167 ${languageUtil.get(locale, "publisher-contact-info", "Publisher Contact Info")}
168 </span>
169
170 <@clay["icon"]
171 className="help-and-support-link-arrow link-arrow ml-auto"
172 height="12"
173 symbol="angle-right"
174 />
175 </a>
176 </div>
177 </div>
178</@section>
179
180<@section
181 showLine = false
182 title = languageUtil.get(locale, "share-link")
183>
184 <a class="align-items-center copy-text d-flex font-weight-bold ml-1 text-decoration-none text-primary" href="#copy-share-link" onclick="copyToClipboard(Liferay.ThemeDisplay.getCanonicalURL())">
185 <span class="help-and-support-link-icon mr-1">
186 <@clay["icon"] symbol="link" />
187 </span>
188 Copy & Share
189 </a>
190</@section>
191
192<#function getSpecificationValue key default="">
193 <#local spec = productSpecifications?filter(productSpecification ->
194 stringUtil.equals(productSpecification.specificationKey, key)) />
195
196 <#return (spec?first.value)!default />
197</#function>
198
199<#macro section
200 title
201 showLine=true
202>
203 <p>
204 <strong>${title}</strong>
205 </p>
206
207 <div>
208 <#nested>
209 </div>
210
211 <#if showLine>
212 <hr />
213 </#if>
214</#macro>
215
216<script ${nonceAttribute}>
217 function modalBody() {
218 return `
219 <div class="align-items-center d-flex flex-row mb-3">
220 <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;">
221 <#if profileImageURL?? && profileImageURL?length gt 0>
222 <img src="${profileImageURL}" alt="Publisher Image" style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%;" />
223 <#else>
224 <@clay["icon"]
225 style="fill:#6B6C7E;"
226 symbol="picture"
227 />
228 </#if>
229 </span>
230
231 <div class="d-flex flex-column">
232 <h3 class="font-weight-bold mb-0">
233 ${catalogName}
234 </h3>
235 </div>
236 </div>
237
238 <#if publisherURL?has_content>
239 <div class="align-items-center d-flex flex-row mb-3">
240 <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;">
241 <@clay["icon"]
242 style="fill:#6B6C7E;"
243 symbol="globe"
244 />
245 </span>
246
247 <div class="d-flex flex-column">
248 <span class="text-black-50">${languageUtil.get(locale, "publisher-website", "Publisher Website")}</span>
249
250 <a href="${publisherURL}" target="_blank" class="font-weight-bold">
251 ${publisherURL}
252 </a>
253 </div>
254 </div>
255 </#if>
256
257 <#if supportEmail?has_content>
258 <div class="align-items-center d-flex flex-row mb-3">
259 <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;">
260 <@clay["icon"] style="fill:#6B6C7E;"symbol="envelope-closed" />
261 </span>
262
263 <div class="d-flex flex-column">
264 <span class="text-black-50">${languageUtil.get(locale, "support-email", "Support Email")}</span>
265
266 <a class="font-weight-bold" href="mailto:${supportEmail}" target="_blank">
267 ${supportEmail}
268 </a>
269 </div>
270 </div>
271 </#if>
272
273 <#if supportPhone?has_content>
274 <div class="d-flex flex-row align-items-center mb-3">
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="phone"
279 />
280 </span>
281
282 <div class="d-flex flex-column">
283 <span class="text-black-50">${languageUtil.get(locale, "phone")}</span>
284
285 <a class="font-weight-bold" href="tel:${supportPhone}" target="_blank">
286 ${supportPhone}
287 </a>
288 </div>
289 </div>
290 </#if>
291 `;
292 }
293
294 function openModal() {
295 Liferay.Util.openModal({
296 bodyHTML: modalBody(),
297 center: true,
298 headerHTML: "<h2>Publisher Support Contact Info</h2>",
299 size: "md"
300 });
301 }
302</script>
303
304<script ${nonceAttribute}>
305 function copyToClipboard(text) {
306 if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
307 navigator.clipboard.writeText(text);
308
309 Liferay.Util.openToast({ message: "Copied link to the clipboard" });
310 }
311 }
312</script>
313
314<style ${nonceAttribute}>
315 .copy-text {
316 color: #282934;
317 font-size: 16px;
318 }
319
320 .help-and-support-link {
321 color: inherit;
322 text-decoration: none;
323 }
324
325 .help-and-support-link-arrow {
326 fill: rgb(133, 140, 148);
327 }
328
329 .help-and-support-link:hover {
330 color: inherit;
331 text-decoration: none;
332 }
333
334 .help-and-support-link-icon {
335 color: rgb(133, 140, 148);
336 }
337
338 .help-and-support-svg mask,
339 .link-arrow mask {
340 mask-type: alpha;
341 }
342</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.