/o//commerce-media/accounts/-1/images/18564202?download=true
Web Content Importer
DXP App
This application allows a liferay user administrator to import journal
articles and ddm structures using a generic defined Xml.
The import processment will show a report with details about imported data.
-> Why using it?
It can be beneficial when an insert of many journal articles or structures is required or for migration purpose getting web content data from whatever source.
In this last scenario tools might be created to generate the given Xml.
It can be in general used as an alternative to the "add new web content/ddm structure" offered by liferay (Web Content section).
-> How to use it?
Once installed a portlet will be accessible from "configuration" item of control panel with name "Web Content Importer", therefore allowed to be viewed/used by an Administrator role.
When it is opened the app will let you import whenever the Xml to upload and the liferay site (site in which the web content is saved) are selected.
-> Creating the Xml
In order to create the Xml please refer to the xsd file residing in the service module: webcontent-importer-service under "resources" folder at the path "\it\keybiz\liferay\globalimp\service\webcontent\xml\impl" with name webcontent.xsd
When uploading the file xml is parsed and validated against the xsd,in case displaying an error message describing which element is defined incorrectly.
ps: beware of the order of the element and the number minimum occurrences (almost all attributes element are optional) as they are main source of validation issues.
-> Defining DDM Structure, xml element example
```
<ddmstructure>
<name>Example</name>
<structurekey>ExampleKey</structurekey>
<dateformfield>
<label>date</label>
<tip></tip>
<showlabel>true</showlabel>
</dateformfield>
</ddmstructure>
```
-> Defining Journal Article, xml element example
```
<journalarticle>
<title>Example</title>
<description>Example</description>
<defaultlocale>it_IT</defaultlocale>
<ddmstructurekey>ExampleKey</ddmstructurekey>
<dateformfield>
<data>2016-03-02</data>
</dateformfield>
</journalarticle>
```
The xml above will create a ddmstructure and than a journal article associated to it (see ddmstructurekey equals to the structurekey of the ddmstructure element).
Mandatory form field elements like dateformfield or checkboxformfield in the journalarticle element let you insert content data.
p.s: To check required or not elements please refer to the webcontent.xsd file.
-> What About DDM Template of a structure ?
The template associated with the structure can't be defined at this stage of development.
At the moment a default one is created with a default freemarker script which will display data of structure form fields,in display mode.
-> What if I don't define a structure Key for the journal article ?
the journal article will be created with the Liferay default DDM Structure/template (BASIC WEB CONTENT)
-> Which format in the input xml for formfields element of a journalarticles ?
the <data> element should be filled respecting the following format,
respectively for each field:
1. radioformfield should be one of the possible value defined in the related formfield of the ddmstructure
-> for options: value1,value2,value3 for instance could be value1
-> for the default ddmstructure (value 1,2,3 are the default)
2. separatorformfield: it is just a graphic separator filling data element is useless
3. selectformfield should be one of the possible value defined in the related formfield of the ddmstructure
-> for options: value1,value2,value3 for instance could be value1
-> for the default ddmstructure (value 1,2,3 are the default)
4. journalarticleformfield
must be a json object like -> {"className":"com.liferay.journal.model.JournalArticle","classPK":"116602"}
5. imageformfield and documentlibraryformfield
must be a url referencing a resource image or document -> /documents/20147/0/Chrysanthemum.jpg/9fff10be-dc64-d8fa-bbcd-25be3555bb94?t=1475668603495
6. dataformfield -> 2016-10-30 = YYYY-mm-dd
7. htmlformfield -> must be wrapped in a CDDATA -> <![CDATA[<h1>test444</h1><div>ciaooone</div><script>alert("ciao");</script>]]>
8. textformfield whatever string representing a text
9. textareaformfield -> see 8
All of the above are validated during import, in case data is in the incorrect format(date in the wrong format) content won't be created for that formfield.
Later feature will contemplate a failed import and error messages to be displayed in the report table.
-> Report Result table
After processement a table with import result will be presented:
* it will contain details of each web content (can be type ddm structure or journal article) import operation.
* in case an insert operation goes wrong error a message will be displayed in the error message column.
* the title column can be clicked to access the detail page of the imported journal article (at the moment this is not enabled for a ddm structure)
* the id and structure key gives you an insight of the entites created in the database
The import processment will show a report with details about imported data.
-> Why using it?
It can be beneficial when an insert of many journal articles or structures is required or for migration purpose getting web content data from whatever source.
In this last scenario tools might be created to generate the given Xml.
It can be in general used as an alternative to the "add new web content/ddm structure" offered by liferay (Web Content section).
-> How to use it?
Once installed a portlet will be accessible from "configuration" item of control panel with name "Web Content Importer", therefore allowed to be viewed/used by an Administrator role.
When it is opened the app will let you import whenever the Xml to upload and the liferay site (site in which the web content is saved) are selected.
-> Creating the Xml
In order to create the Xml please refer to the xsd file residing in the service module: webcontent-importer-service under "resources" folder at the path "\it\keybiz\liferay\globalimp\service\webcontent\xml\impl" with name webcontent.xsd
When uploading the file xml is parsed and validated against the xsd,in case displaying an error message describing which element is defined incorrectly.
ps: beware of the order of the element and the number minimum occurrences (almost all attributes element are optional) as they are main source of validation issues.
-> Defining DDM Structure, xml element example
```
<ddmstructure>
<name>Example</name>
<structurekey>ExampleKey</structurekey>
<dateformfield>
<label>date</label>
<tip></tip>
<showlabel>true</showlabel>
</dateformfield>
</ddmstructure>
```
-> Defining Journal Article, xml element example
```
<journalarticle>
<title>Example</title>
<description>Example</description>
<defaultlocale>it_IT</defaultlocale>
<ddmstructurekey>ExampleKey</ddmstructurekey>
<dateformfield>
<data>2016-03-02</data>
</dateformfield>
</journalarticle>
```
The xml above will create a ddmstructure and than a journal article associated to it (see ddmstructurekey equals to the structurekey of the ddmstructure element).
Mandatory form field elements like dateformfield or checkboxformfield in the journalarticle element let you insert content data.
p.s: To check required or not elements please refer to the webcontent.xsd file.
-> What About DDM Template of a structure ?
The template associated with the structure can't be defined at this stage of development.
At the moment a default one is created with a default freemarker script which will display data of structure form fields,in display mode.
-> What if I don't define a structure Key for the journal article ?
the journal article will be created with the Liferay default DDM Structure/template (BASIC WEB CONTENT)
-> Which format in the input xml for formfields element of a journalarticles ?
the <data> element should be filled respecting the following format,
respectively for each field:
1. radioformfield should be one of the possible value defined in the related formfield of the ddmstructure
-> for options: value1,value2,value3 for instance could be value1
-> for the default ddmstructure (value 1,2,3 are the default)
2. separatorformfield: it is just a graphic separator filling data element is useless
3. selectformfield should be one of the possible value defined in the related formfield of the ddmstructure
-> for options: value1,value2,value3 for instance could be value1
-> for the default ddmstructure (value 1,2,3 are the default)
4. journalarticleformfield
must be a json object like -> {"className":"com.liferay.journal.model.JournalArticle","classPK":"116602"}
5. imageformfield and documentlibraryformfield
must be a url referencing a resource image or document -> /documents/20147/0/Chrysanthemum.jpg/9fff10be-dc64-d8fa-bbcd-25be3555bb94?t=1475668603495
6. dataformfield -> 2016-10-30 = YYYY-mm-dd
7. htmlformfield -> must be wrapped in a CDDATA -> <![CDATA[<h1>test444</h1><div>ciaooone</div><script>alert("ciao");</script>]]>
8. textformfield whatever string representing a text
9. textareaformfield -> see 8
All of the above are validated during import, in case data is in the incorrect format(date in the wrong format) content won't be created for that formfield.
Later feature will contemplate a failed import and error messages to be displayed in the report table.
-> Report Result table
After processement a table with import result will be presented:
* it will contain details of each web content (can be type ddm structure or journal article) import operation.
* in case an insert operation goes wrong error a message will be displayed in the error message column.
* the title column can be clicked to access the detail page of the imported journal article (at the moment this is not enabled for a ddm structure)
* the id and structure key gives you an insight of the entites created in the database
DEVELOPER
Hiba jelentkezett a sablon feldolgozása során.
The string doesn't match the expected date/time/date-time format. The string to parse was: "2024.11.21. 18:19". The expected format was: "MM/dd/yy h:mm a". The nested reason given follows: Unparseable date: "2024.11.21. 18:19" ---- FTL stack trace ("~" means nesting-related): - Failed at: ${CPDefinition_displayDate.getData()?... [in template "3192443#3192485#null" at line 46, column 20] ~ Reached through: #nested [in template "3192443#3192485#null" in macro "section" at line 197, column 17] ~ Reached through: @section title=languageUtil.get(local... [in template "3192443#3192485#null" at line 42, 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
20<#if publisherDetailsResponse.items?has_content>
21 <#assign
22 publisherDetails = publisherDetailsResponse.items[0]
23 profileImageURL = publisherDetails.publisherProfileImage?replace("https://", "http://")
24 />
25</#if>
26
27<#assign
28 cpuValue = getSpecificationValue("cpu")
29 developerName = getSpecificationValue("developer-name", catalogName)
30 publisherURL = (getSpecificationValue("publisherwebsiteurl")?trim?replace(" ", ""))!""
31 ramValue = getSpecificationValue("ram")
32 supportEmail = getSpecificationValue("supportemailaddress")
33 supportPhone = getSpecificationValue("supportphone")
34 type = getSpecificationValue("type")?lower_case
35>
36<@section title = languageUtil.get(locale, "developer")>
37 <a class = "bg-neutral-8" href = "/?developer-name=${developerName}">
38 ${developerName}
39 </a>
40</@section>
41
42<@section title = languageUtil.get(locale, "publisher-date", "Publisher Date")>
43 <#setting date_format = "MMMM d, yyyy">
44
45 <#if CPDefinition_displayDate.getData()?has_content>
46 <p>${CPDefinition_displayDate.getData()?date("MM/dd/yy h:mm a")?string("MMMM d, yyyy")}</p>
47 </#if>
48</@section>
49
50<@section title = languageUtil.get(locale, "deployment-method", "Deployment Method")>
51 <#list platformOffering as offering>
52 <p>${offering.name}</p>
53 </#list>
54</@section>
55
56<@section title = languageUtil.get(locale, "app-type", "App Type")>
57 <#if type == 'client-extension'> Client Extension </#if>
58 <#if type == 'cloud'> Cloud </#if>
59 <#if type == 'composite-app'> Composite App </#if>
60 <#if type == 'dxp'> DXP </#if>
61 <#if type == 'low-code-configuration'> Low Code Configuration </#if>
62</@section>
63
64<@section title = languageUtil.get(locale, "version")>
65 ${getSpecificationValue("latest-version", "1.0.0")}
66</@section>
67
68<#if liferayVersions?has_content>
69 <@section title = languageUtil.get(locale, "supported-versions", "Supported Versions")>
70 <#list liferayVersions as version>
71 ${version.value}<#if version?has_next>, </#if>
72 </#list>
73 </@section>
74</#if>
75
76<#if cpuValue?has_content>
77 <@section title = languageUtil.get(locale, "resource-requirements", "Resource Requirements")>
78 <p>
79 <#if cpuValue?has_content>
80 ${cpuValue}
81 <#assign cpuNumber = cpuValue?number?default(0) />
82 <#if cpuValue?eval gt 1>
83 CPUS
84 </#if>
85 <#if cpuValue?eval lt 2>
86 CPU
87 </#if>
88 </#if>, <#if ramValue?has_content>${ramValue} GB RAM</#if>
89 </p>
90 </@section>
91</#if>
92
93<@section title = languageUtil.get(locale, "standard-price", "Standard Price")>
94 <div>
95 <#assign purchasableSkus = [] />
96
97 <#list product.skus as sku>
98 <#if sku.purchasable?? && sku.purchasable>
99 <#assign purchasableSkus = purchasableSkus + [sku] />
100 </#if>
101 </#list>
102
103 <#assign standardSku = {} />
104
105 <#list purchasableSkus as sku>
106 <#assign matched = false />
107
108 <#list sku.skuOptions as opt>
109 <#if stringUtil.equals(opt.skuOptionValueKey, "standard")>
110 <#assign
111 matched = true
112 standardSku = sku
113 />
114
115 <#break>
116 </#if>
117 </#list>
118 <#if matched><#break></#if>
119 </#list>
120
121 <#if standardSku.price?? && standardSku.price.price?eval gt 0>
122 <div class="bg-neutral-8">${standardSku.price.priceFormatted!""}</div>
123 <#else>
124 ${languageUtil.get(locale, "free", "Free")}
125 </#if>
126 </div>
127</@section>
128
129<@section title = languageUtil.get(locale, "help-and-support", "Help and Support")>
130 <div class="d-flex flex-column mt-4">
131 <div class="d-flex">
132 <span class="help-and-support-link-icon">
133 <@clay["icon"] symbol="document" />
134 </span>
135
136 <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">
137 <span class="copy-text ml-1 help-and-support-link">
138 ${languageUtil.get(locale, "terms-and-conditions", "Terms & Conditions")}
139 </span>
140
141 <@clay["icon"]
142 className="help-and-support-link-arrow link-arrow ml-auto"
143 height="12"
144 symbol="angle-right"
145 />
146 </a>
147 </div>
148
149 <div class="d-flex">
150 <span class="help-and-support-link-icon">
151 <@clay["icon"] symbol="document" />
152 </span>
153
154 <a class="d-flex w-100 justify-content-between help-and-support-link" href="javascript:void(0)" onClick="openModal()">
155 <span class="copy-text ml-1 help-and-support-link">
156 ${languageUtil.get(locale, "publisher-contact-info", "Publisher Contact Info")}
157 </span>
158
159 <@clay["icon"]
160 className="help-and-support-link-arrow link-arrow ml-auto"
161 height="12"
162 symbol="angle-right"
163 />
164 </a>
165 </div>
166 </div>
167</@section>
168
169<@section
170 showLine = false
171 title = languageUtil.get(locale, "share-link")
172>
173 <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())">
174 <span class="help-and-support-link-icon mr-1">
175 <@clay["icon"] symbol="link" />
176 </span>
177 Copy & Share
178 </a>
179</@section>
180
181<#function getSpecificationValue key default="">
182 <#local spec = productSpecifications?filter(productSpecification ->
183 stringUtil.equals(productSpecification.specificationKey, key)) />
184
185 <#return (spec?first.value)!default />
186</#function>
187
188<#macro section
189 title
190 showLine=true
191>
192 <p>
193 <strong>${title}</strong>
194 </p>
195
196 <div>
197 <#nested>
198 </div>
199
200 <#if showLine>
201 <hr />
202 </#if>
203</#macro>
204
205<script ${nonceAttribute}>
206 function modalBody() {
207 return `
208 <div class="align-items-center d-flex flex-row mb-3">
209 <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;">
210 <#if profileImageURL?? && profileImageURL?length gt 0>
211 <img src="${profileImageURL}" alt="Publisher Image" style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%;" />
212 <#else>
213 <@clay["icon"]
214 style="fill:#6B6C7E;"
215 symbol="picture"
216 />
217 </#if>
218 </span>
219
220 <div class="d-flex flex-column">
221 <h3 class="font-weight-bold mb-0">
222 ${catalogName}
223 </h3>
224 </div>
225 </div>
226
227 <#if publisherURL?has_content>
228 <div class="align-items-center d-flex flex-row mb-3">
229 <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;">
230 <@clay["icon"]
231 style="fill:#6B6C7E;"
232 symbol="globe"
233 />
234 </span>
235
236 <div class="d-flex flex-column">
237 <span class="text-black-50">${languageUtil.get(locale, "publisher-website", "Publisher Website")}</span>
238
239 <a href="${publisherURL}" target="_blank" class="font-weight-bold">
240 ${publisherURL}
241 </a>
242 </div>
243 </div>
244 </#if>
245
246 <#if supportEmail?has_content>
247 <div class="align-items-center d-flex flex-row mb-3">
248 <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;">
249 <@clay["icon"] style="fill:#6B6C7E;"symbol="envelope-closed" />
250 </span>
251
252 <div class="d-flex flex-column">
253 <span class="text-black-50">${languageUtil.get(locale, "support-email", "Support Email")}</span>
254
255 <a class="font-weight-bold" href="mailto:${supportEmail}" target="_blank">
256 ${supportEmail}
257 </a>
258 </div>
259 </div>
260 </#if>
261
262 <#if supportPhone?has_content>
263 <div class="d-flex flex-row align-items-center mb-3">
264 <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;">
265 <@clay["icon"]
266 style="fill:#6B6C7E;"
267 symbol="phone"
268 />
269 </span>
270
271 <div class="d-flex flex-column">
272 <span class="text-black-50">${languageUtil.get(locale, "phone")}</span>
273
274 <a class="font-weight-bold" href="tel:${supportPhone}" target="_blank">
275 ${supportPhone}
276 </a>
277 </div>
278 </div>
279 </#if>
280 `;
281 }
282
283 function openModal() {
284 Liferay.Util.openModal({
285 bodyHTML: modalBody(),
286 center: true,
287 headerHTML: "<h2>Publisher Support Contact Info</h2>",
288 size: "md"
289 });
290 }
291</script>
292
293<script ${nonceAttribute}>
294 function copyToClipboard(text) {
295 if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
296 navigator.clipboard.writeText(text);
297
298 Liferay.Util.openToast({ message: "Copied link to the clipboard" });
299 }
300 }
301</script>
302
303<style ${nonceAttribute}>
304 .copy-text {
305 color: #282934;
306 font-size: 16px;
307 }
308
309 .help-and-support-link {
310 color: inherit;
311 text-decoration: none;
312 }
313
314 .help-and-support-link-arrow {
315 fill: rgb(133, 140, 148);
316 }
317
318 .help-and-support-link:hover {
319 color: inherit;
320 text-decoration: none;
321 }
322
323 .help-and-support-link-icon {
324 color: rgb(133, 140, 148);
325 }
326
327 .help-and-support-svg mask,
328 .link-arrow mask {
329 mask-type: alpha;
330 }
331</style>
DEVELOPER
2024.11.21. 18:19
Published date
2024.11.21. 18:19
Published Date
2024.11.21. 18:19
SUPPORTED OFFERINGS
Liferay PaaS
Supported Versions
7.0
Resource Requirements
Edition
CE
PRICE
Free
help & support
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.