/o//commerce-media/accounts/-1/images/18595869?download=true

Bulk Tag Assignment to Assets
DXP App
Data Modeling, Process & Business Logic
18595819
If Liferay Administrator want to add tags or categories to any Asset, then admin has to do it by editing that individual Asset. For example if Admin want to assign "liferay-dxp" tag to the web content having text "liferay" in it. In such case admin has to first search web contents having text "liferay" and then assign "liferay-dxp" tag to each web content by editing each one manually. With the help of this component admin can assign tags (categories) to multiple web contents without opening individual web content.

This component will add given feature to Web Content, Document, Bookmark, Wiki Pages, Message Boards and Blogs.
DEVELOPER
حصل خطأ عند معالجة القالب.
For "?datetime" left-hand operand: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to an extended_hash (wrapper: com.liferay.portal.template.freemarker.internal.LiferayTemplateModel):
==> createDate  [in template "3192443#3192485#null" at line 51, column 31]

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