- Configuring Documents and Media Previews
- Enabling Antivirus Scanning for Uploaded Files
- Configuring Caching for Documents and Media
- Setting Storage Quotas for Documents and Media
- Enabling Optimization of Animated GIFs
- Enabling FFmpeg for Audio and Video Previews
- Enabling LibreOffice / OpenOffice Integration
- Enabling Document Creation and Editing with Microsoft Office 365
- Google Drive Integration
- SharePoint Integration
Se ha producido un error al procesar la plantilla.
For "." left-hand operand: Expected a hash, but this has evaluated to a string (wrapper: f.t.SimpleScalar): ==> structuredContent [in template "57868206215768#32483061#37053490" at line 56, column 34] ---- FTL stack trace ("~" means nesting-related): - Failed at: taxonomyCategoryBriefs = structuredCo... [in template "57868206215768#32483061#37053490" 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="d-flex justify-content-end mb-3">
99 <div class="submit-feedback">
100 <a
101 class="text-decoration-none"
102 href="https://liferay.dev/c/portal/login?redirect=https://liferay.dev/ask/questions/liferay-learn-feedback/new"
103 >
104 ${languageUtil.get(locale, "submit-feedback", "Submit Feedback")}
105 <@clay["icon"] symbol="message-boards" />
106 </a>
107 </div>
108 </div>
109 </div>
110 </div>
111
112 <div class="learn-article-wrapper">
113 <div class="language-log learn-article-content">
114 <#if (content.getData())??>
115 ${content.getData()}
116 </#if>
117
118 <#if showChildrenCards && childrenJSONArray.length() gt 0>
119 <div class="learn-card-container">
120 <#list 0..childrenJSONArray.length()-1 as i>
121 <#assign childJSONObject = childrenJSONArray.getJSONObject(i) />
122
123 <div class="learn-card">
124 <a href="${childJSONObject.getString("url")}">
125 <h4>${childJSONObject.getString("title")}</h4>
126 </a>
127
128 <#if childJSONObject.getJSONArray("children")?has_content>
129 <#assign grandchildrenJSONArray = childJSONObject.getJSONArray("children") />
130
131 <div class="mt-2 subsection">
132 <#list 0..grandchildrenJSONArray.length()-1 as j>
133 <#assign grandchildJSONObject = grandchildrenJSONArray.getJSONObject(j)! />
134
135 <#if grandchildJSONObject??
136 && grandchildJSONObject["title"]?has_content
137 && grandchildJSONObject["url"]?has_content >
138 <a href="${grandchildJSONObject["url"]!}">
139 ${grandchildJSONObject["title"]!}
140 </a>
141 </#if>
142 </#list>
143 </div>
144 </#if>
145 </div>
146 </#list>
147 </div>
148 </#if>
149 <div class="learn-article-categories-tags">
150 <#list taxonomyVocabularies as vocabulary>
151 <div class="align-items-baseline d-flex mt-2">
152 <div class="learn-article-category-title mr-2">
153 ${vocabulary}:
154 </div>
155 <#list taxonomyCategoriesMap[vocabulary]?sort_by("categoryName") as taxonomyCategory>
156 <div class="learn-article-category-tag mr-2">
157 <a
158 class="label tag-container"
159 href="/search?${vocabulary?lower_case?replace(" ", "-", "r")}=${taxonomyCategory.categoryId}"
160 >
161 <span>${taxonomyCategory.categoryName}</span>
162 </a>
163 </div>
164 </#list>
165 </div>
166 </#list>
167 </div>
168
169 <div class="article-related-how-to">
170 <#setting url_escaping_charset='UTF-8' />
171
172 <#if (structuredContent.keywords?has_content && structuredContent.keywords?size > 0)>
173 <#assign
174 queryParams = {
175 "fields": "dateModified,id,title",
176 "filter": "(knowledgeArticleType eq 'howTo') and (status eq 0) and (sourceTeam eq 'Enablement')",
177 "pageSize": "3",
178 "search": structuredContent.keywords[0],
179 "sort": "dateModified:desc"
180 }
181 queryParts = []
182 />
183
184 <#list queryParams?keys as key>
185 <#assign
186 value = queryParams[key]
187
188 queryParts = queryParts + ["${key?url}=${value?url}"]
189 />
190 </#list>
191
192 <#assign knowledgeArticles = restClient.get("/c/p2s3knowledgearticles/?" + queryParts?join('&')) />
193
194 <#if (knowledgeArticles.totalCount)?has_content && (knowledgeArticles.totalCount > 0)>
195 <div class="how-to-container">
196 <div class="how-to-container-header">
197 ${languageUtil.get(locale, 'how-to-related-to-this-article')}
198 </div>
199
200 <div class="how-to-cards-container" id="how-to-cards-container">
201 <#assign currentURL = portalUtil.getCurrentURL(request) >
202 <#list knowledgeArticles.items as knowledgeArticle>
203 <a class="how-to-card" href="${currentURL}/l/${knowledgeArticle.id}/">
204 <div class="how-to-card-header">
205 ${knowledgeArticle.title!}
206 </div>
207
208 <div class="how-to-card-date-published">
209 <#assign date = knowledgeArticle.dateModified?datetime("yyyy-MM-dd'T'HH:mm:ss'Z'") />
210
211 ${languageUtil.get(locale, 'published-date')}: ${date?string["MMM dd, yy hh:mm a"]}
212 </div>
213 </a>
214 </#list>
215 </div>
216 </div>
217 </#if>
218 </#if>
219 </div>
220 </div>
221
222 <div class="learn-article-page-nav">
223 <ul class="nav nav-stacked toc" id="articleTOC"></ul>
224 </div>
225 </div>
226 </div>
227</article>
228
229<style>
230 .how-to-card {
231 align-items: flex-start;
232 background: var(--color-brand-primary-lighten-6, #FBFCFE);
233 border: 1px solid var(--color-brand-primary-lighten-5, #E7EFFF);
234 border-radius: 0.75rem;
235 box-sizing: border-box;
236 cursor: pointer;
237 display: flex;
238 flex-direction: column;
239 gap: 0.5rem;
240 isolation: isolate;
241 justify-content: space-between;
242 order: 0;
243 padding: 1rem;
244 width: 100%;
245 }
246
247 .how-to-card:hover {
248 background: var(--color-action-primary-hover-10, #EDF3FE);
249 border: 1px solid var(--color-action-primary-hover, #0053F0);
250 border-radius: 0.625rem;
251 }
252
253 .how-to-card-date-published {
254 align-items: center;
255 align-self: stretch;
256 color: var(--color-neutral-8, #54555F);
257 display: flex;
258 flex: none;
259 flex-grow: 0;
260 font-family: 'Source Sans 3';
261 font-size: 0.75rem;
262 font-style: normal;
263 font-weight: 400;
264 line-height: 1rem;
265 }
266
267 .how-to-card-header {
268 align-items: center;
269 align-self: stretch;
270 color: var(--color-brand-primary, #0B5FFF);
271 display: flex;
272 flex: none;
273 flex-grow: 0;
274 font-family: 'Source Sans 3';
275 font-size: 1rem;
276 font-style: normal;
277 font-weight: 600;
278 line-height: 1.5rem;
279 }
280
281 .how-to-cards-container {
282 display: flex;
283 flex-direction: row;
284 gap: 1rem;
285 width: 100%;
286 }
287
288 .how-to-container {
289 align-items: flex-start;
290 align-self: stretch;
291 background: var(--color-neutral-1, #F7F7F8);
292 border-radius: 0.75rem;
293 display: flex;
294 flex: none;
295 flex-direction: column;
296 flex-grow: 0;
297 gap: 1.5rem;
298 isolation: isolate;
299 margin: 1.5rem 0px;
300 order: 0;
301 padding: 1.5rem;
302 width: 100%;
303 }
304
305 .how-to-container-header {
306 align-items: center;
307 color: var(--color-neutral-10, #282934);
308 display: flex;
309 flex: none;
310 flex-grow: 0;
311 font-family: 'Source Sans 3';
312 font-size: 1.5rem;
313 font-style: normal;
314 font-weight: 700;
315 line-height: 1.75rem;
316 }
317
318 @media only screen and (max-width: 1200px) {
319 .how-to-cards-container {
320 flex-direction: column;
321 }
322 }
323</style>
Capabilities
Product
Education
Knowledge Base
Contact Us