DXP / Portal
Creating a Discount
テンプレート処理中にエラーが発生しました。
For "." left-hand operand: Expected a hash, but this has evaluated to a string (wrapper: f.t.SimpleScalar):
==> structuredContent  [in template "57868206215768#32483061#35456003" at line 56, column 34]

----
FTL stack trace ("~" means nesting-related):
	- Failed at: taxonomyCategoryBriefs = structuredCo...  [in template "57868206215768#32483061#35456003" at line 56, column 9]
----
1<script> 
2	const _addEventListener = (selectors) => { 
3		var elements = document.querySelectorAll(selectors); 
4 
5		elements.forEach((element) => { 
6			element.addEventListener("click", (event) => { 
7				event.preventDefault(); 
8 
9				const anchorElement = document.getElementById(element.getAttribute("id").replace("toc-", "")); 
10 
11				if (anchorElement) { 
12					window.history.pushState( 
13						{}, 
14						"", 
15						"#" + element.getAttribute("id").replace("toc-", "") 
16					); 
17					scrollToElement(anchorElement); 
18
19			}); 
20		}); 
21
22 
23	const scrollToElement = (element) => { 
24		if (!element) return; 
25 
26		window.scrollTo({ 
27			behavior: "smooth", 
28			top: element.getBoundingClientRect().top + window.scrollY - 190, 
29		}); 
30	}; 
31 
32	window.addEventListener('load', function() { 
33		_addEventListener("h1 a, h2 a, h3 a"); 
34		_addEventListener(".toc li a"); 
35 
36		if (window.location.hash) { 
37			const hashLocation = document.getElementById(window.location.hash.substring(1)); 
38 
39			if (hashLocation) { 
40				setTimeout(() => { 
41					scrollToElement(hashLocation); 
42				}, 100); 
43
44
45	}); 
46</script> 
47 
48<#assign 
49	journalArticleId = .vars["reserved-article-id"].data 
50 
51	structuredContent = restClient.get("/headless-delivery/v1.0/sites/${groupId}/structured-contents/by-key/${journalArticleId}?nestedFields=embeddedTaxonomyCategory") 
52 
53	showChildrenCards = showChildrenCards.getData()?boolean 
54	taxonomyCategoriesMap = {} 
55	taxonomyVocabularies = [] 
56	taxonomyCategoryBriefs = structuredContent.taxonomyCategoryBriefs 
57 
58	navigationJSONObject = jsonFactoryUtil.createJSONObject(htmlUtil.unescape(navigation.getData()?trim)) 
59 
60	breadcrumbJSONArray = navigationJSONObject.getJSONArray("breadcrumb") 
61	childrenJSONArray = navigationJSONObject.getJSONArray("children") 
62/> 
63 
64<#list taxonomyCategoryBriefs as taxonomyCategoryBrief> 
65	<#assign taxonomyVocabularyName = taxonomyCategoryBrief.embeddedTaxonomyCategory.parentTaxonomyVocabulary.name /> 
66 
67	<#if !taxonomyVocabularies?seq_contains(taxonomyVocabularyName)> 
68		<#assign taxonomyVocabularies = taxonomyVocabularies + [taxonomyVocabularyName] /> 
69	</#if> 
70 
71	<#if taxonomyCategoriesMap[taxonomyVocabularyName]?has_content> 
72		<#assign taxonomyCategoriesMap = taxonomyCategoriesMap + 
73
74				taxonomyVocabularyName: 
75					taxonomyCategoriesMap[taxonomyVocabularyName] + [{ 
76						"categoryId": taxonomyCategoryBrief.taxonomyCategoryId, 
77						"categoryName": taxonomyCategoryBrief.taxonomyCategoryName 
78					}] 
79
80		/> 
81	<#else> 
82		<#assign taxonomyCategoriesMap = taxonomyCategoriesMap + 
83
84				taxonomyVocabularyName: 
85					[{ 
86						"categoryId": taxonomyCategoryBrief.taxonomyCategoryId, 
87						"categoryName": taxonomyCategoryBrief.taxonomyCategoryName 
88					}] 
89
90		/> 
91	</#if> 
92</#list> 
93 
94<article class="learn-article"> 
95	<div class="d-flex flex-column"> 
96		<div class="learn-article-breadcrumbs"> 
97			<div class="learn-article-breadcrumbs-content"> 
98				<div class="align-items-baseline d-flex justify-content-between mb-3"> 
99					<ul 
100						aria-label="breadcrumb navigation" 
101						class="learn-article-breadcrumb" 
102						role="navigation" 
103
104						<li> 
105							<a href="/"><@clay["icon"] symbol="home-full" /></a> 
106						</li> 
107 
108						<#if breadcrumbJSONArray?has_content> 
109							<#list breadcrumbJSONArray.length()-1..0 as i> 
110								<#assign breadcrumbJSONObject = breadcrumbJSONArray.getJSONObject(i)! /> 
111								<li> 
112								<#if breadcrumbJSONObject??  
113												&& breadcrumbJSONObject["title"]?has_content 
114												&& breadcrumbJSONObject["url"]?has_content > 
115									<a href='${breadcrumbJSONObject.getString("url")}'>${breadcrumbJSONObject.getString("title")}</a> 
116									</#if> 
117								</li> 
118							</#list> 
119						</#if> 
120 
121						<li> 
122							${navigationJSONObject.getJSONObject("self").getString("title")} 
123						</li> 
124					</ul> 
125 
126					<div class="submit-feedback"> 
127						<a 
128							class="text-decoration-none" 
129							href="https://liferay.dev/c/portal/login?redirect=https://liferay.dev/ask/questions/liferay-learn-feedback/new" 
130
131							${languageUtil.get(locale, "submit-feedback", "Submit Feedback")} 
132							<@clay["icon"] symbol="message-boards" /> 
133						</a> 
134					</div> 
135				</div> 
136			</div> 
137		</div> 
138 
139		<div class="learn-article-wrapper"> 
140			<div class="language-log learn-article-content"> 
141				<#if (content.getData())??> 
142					${content.getData()} 
143				</#if> 
144 
145				<#if showChildrenCards && childrenJSONArray.length() gt 0> 
146					<div class="learn-card-container"> 
147						<#list 0..childrenJSONArray.length()-1 as i> 
148							<#assign childJSONObject = childrenJSONArray.getJSONObject(i) /> 
149 
150							<div class="learn-card"> 
151								<a href="${childJSONObject.getString("url")}"> 
152									<h4>${childJSONObject.getString("title")}</h4> 
153								</a> 
154 
155								<#if childJSONObject.getJSONArray("children")?has_content> 
156									<#assign grandchildrenJSONArray = childJSONObject.getJSONArray("children") /> 
157 
158									<div class="mt-2 subsection"> 
159										<#list 0..grandchildrenJSONArray.length()-1 as j> 
160											<#assign grandchildJSONObject = grandchildrenJSONArray.getJSONObject(j)! /> 
161 
162											<#if grandchildJSONObject??  
163												&& grandchildJSONObject["title"]?has_content 
164												&& grandchildJSONObject["url"]?has_content > 
165												<a href="${grandchildJSONObject["url"]!}"> 
166													${grandchildJSONObject["title"]!} 
167												</a> 
168											</#if> 
169										</#list> 
170									</div> 
171								</#if> 
172							</div> 
173						</#list> 
174					</div> 
175				</#if> 
176				<div class="learn-article-categories-tags"> 
177					<#list taxonomyVocabularies as vocabulary> 
178						<div class="align-items-baseline d-flex mt-2"> 
179							<div class="learn-article-category-title mr-2"> 
180								${vocabulary}: 
181							</div> 
182							<#list taxonomyCategoriesMap[vocabulary]?sort_by("categoryName") as taxonomyCategory> 
183								<div class="learn-article-category-tag mr-2"> 
184									<a 
185										class="label tag-container" 
186										href="/search?${vocabulary?lower_case?replace(" ", "-", "r")}=${taxonomyCategory.categoryId}" 
187
188										<span>${taxonomyCategory.categoryName}</span> 
189									</a> 
190								</div> 
191							</#list> 
192						</div> 
193					</#list> 
194				</div> 
195 
196				<div class="article-related-how-to"> 
197					<#setting url_escaping_charset='UTF-8' /> 
198 
199					<#if (structuredContent.keywords?has_content && structuredContent.keywords?size > 0)> 
200						<#assign  
201							queryParams = { 
202								"fields": "dateModified,id,title", 
203								"filter": "(knowledgeArticleType eq 'howTo') and (status eq 0) and (sourceTeam eq 'Enablement')", 
204								"pageSize": "3", 
205								"search": structuredContent.keywords[0], 
206								"sort": "dateModified:desc" 
207
208							queryParts = []  
209						/> 
210 
211						<#list queryParams?keys as key> 
212							<#assign  
213								value = queryParams[key] 
214								 
215								queryParts = queryParts + ["${key?url}=${value?url}"] 
216							/> 
217						</#list> 
218 
219						<#assign knowledgeArticles = restClient.get("/c/p2s3knowledgearticles/?" + queryParts?join('&')) /> 
220 
221						<#if (knowledgeArticles.totalCount)?has_content && (knowledgeArticles.totalCount > 0)> 
222							<div class="how-to-container"> 
223								<div class="how-to-container-header"> 
224									${languageUtil.get(locale, 'how-to-related-to-this-article')} 
225								</div> 
226 
227								<div class="how-to-cards-container" id="how-to-cards-container"> 
228								<#assign currentURL = portalUtil.getCurrentURL(request) > 
229									<#list knowledgeArticles.items as knowledgeArticle> 
230											<a class="how-to-card" href="${currentURL}/l/${knowledgeArticle.id}/"> 
231											<div class="how-to-card-header"> 
232												${knowledgeArticle.title!} 
233											</div> 
234 
235											<div class="how-to-card-date-published"> 
236												<#assign date = knowledgeArticle.dateModified?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'") /> 
237 
238												${languageUtil.get(locale, 'published-date')}: ${date?string["MMM dd, yy hh:mm a"]} 
239											</div> 
240										</a> 
241									</#list> 
242								</div> 
243							</div> 
244						</#if> 
245					</#if> 
246				</div> 
247			</div> 
248 
249			<div class="learn-article-page-nav"> 
250				<ul class="nav nav-stacked toc" id="articleTOC"></ul> 
251			</div> 
252		</div> 
253	</div> 
254</article> 
255 
256<style> 
257	.how-to-card { 
258		align-items: flex-start; 
259		background: var(--color-brand-primary-lighten-6, #FBFCFE); 
260		border: 1px solid var(--color-brand-primary-lighten-5, #E7EFFF); 
261		border-radius: 0.75rem; 
262		box-sizing: border-box; 
263		cursor: pointer; 
264		display: flex; 
265		flex-direction: column; 
266		gap: 0.5rem; 
267		isolation: isolate; 
268		justify-content: space-between; 
269		order: 0; 
270		padding: 1rem; 
271		width: 100%; 
272
273 
274	.how-to-card:hover { 
275		background: var(--color-action-primary-hover-10, #EDF3FE); 
276		border: 1px solid var(--color-action-primary-hover, #0053F0); 
277		border-radius: 0.625rem; 
278
279 
280	.how-to-card-date-published { 
281		align-items: center; 
282		align-self: stretch; 
283		color: var(--color-neutral-8, #54555F); 
284		display: flex; 
285		flex: none; 
286		flex-grow: 0; 
287		font-family: 'Source Sans 3'; 
288		font-size: 0.75rem; 
289		font-style: normal; 
290		font-weight: 400; 
291		line-height: 1rem; 
292
293 
294	.how-to-card-header { 
295		align-items: center; 
296		align-self: stretch; 
297		color: var(--color-brand-primary, #0B5FFF); 
298		display: flex; 
299		flex: none; 
300		flex-grow: 0; 
301		font-family: 'Source Sans 3'; 
302		font-size: 1rem; 
303		font-style: normal; 
304		font-weight: 600; 
305		line-height: 1.5rem; 
306
307 
308	.how-to-cards-container { 
309		display: flex; 
310		flex-direction: row; 
311		gap: 1rem; 
312		width: 100%; 
313
314 
315	.how-to-container { 
316		align-items: flex-start; 
317		align-self: stretch; 
318		background: var(--color-neutral-1, #F7F7F8); 
319		border-radius: 0.75rem; 
320		display: flex; 
321		flex: none; 
322		flex-direction: column; 
323		flex-grow: 0; 
324		gap: 1.5rem; 
325		isolation: isolate; 
326		margin: 1.5rem 0px; 
327		order: 0; 
328		padding: 1.5rem; 
329		width: 100%; 
330
331 
332	.how-to-container-header { 
333		align-items: center; 
334		color: var(--color-neutral-10, #282934); 
335		display: flex; 
336		flex: none; 
337		flex-grow: 0; 
338		font-family: 'Source Sans 3'; 
339		font-size: 1.5rem; 
340		font-style: normal; 
341		font-weight: 700; 
342		line-height: 1.75rem; 
343
344 
345	@media only screen and (max-width: 1200px) { 
346		.how-to-cards-container { 
347			flex-direction: column; 
348
349
350</style>