Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
Fetch and display web content inside web content in Liferay ce-7.2-ga1
Hi, there!
Some time ago I migrated my project from Liferay 7.1-ce-ga4 to Liferay ce-7.2-ga1 and now I'm experiencing the following problem: I have a custom structure that contains a web content field (of type ddm-journal-article). My purpose is to fetch and display this web content inside the main article that is an instance of this structure. In the old version of my liferay installation, I had no problems to do this using the following code:
<#assign webContent = webContent.getData()?eval />
<@liferay_ui["asset-display"]
className = webContent.className
classPK = webContent.getLong(externalContent.classPK, 0)
/>
However, in the new version I get an error message saying that 'FreeMarker template error: The following has evaluated to null or missing: ==> liferay_ui["asset-display"]'. So obviously this code is not usable anymore. I tried to use the automatically generated code for this field inside the structure template which looks like that:
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<a href="${webContent.getFriendlyUrl()}">
${webContentData.title}
</a>
Of course, this code did not fit my needs but I checked the output of ${webContentData} jSON and noticed that I had className and classPK data there. Then I decided to fetch and display this journal content using the standard methods of JournalArticleLocalService . So I proceeded with this code:
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<#assign webJournalArticle = journalArticleLocalService.getArticle( groupId, webContentData.className, getterUtil.getLong(webContentData.classPK) ) />
<#assign webJournalArticleContent = journalArticleLocalService.getArticleContent( groupId, webJournalArticle.getArticleId(), "", locale, themeDisplay ) />${webJournalArticleContent}
This option seemed logic and correct for me, but for my surprise it generated an exception saying that: No approved JournalArticle exists with the key {groupId=XXXXX, className=com.liferay.journal.model.JournalArticle, classPK=XXXXXX} although such an article exists and is approved.
I really don't know how to proceed and solve this issue with ddm-journal-article content, so please any help or advice will be much appreciated.
Regards,
Eli
Some time ago I migrated my project from Liferay 7.1-ce-ga4 to Liferay ce-7.2-ga1 and now I'm experiencing the following problem: I have a custom structure that contains a web content field (of type ddm-journal-article). My purpose is to fetch and display this web content inside the main article that is an instance of this structure. In the old version of my liferay installation, I had no problems to do this using the following code:
<#assign webContent = webContent.getData()?eval />
<@liferay_ui["asset-display"]
className = webContent.className
classPK = webContent.getLong(externalContent.classPK, 0)
/>
However, in the new version I get an error message saying that 'FreeMarker template error: The following has evaluated to null or missing: ==> liferay_ui["asset-display"]'. So obviously this code is not usable anymore. I tried to use the automatically generated code for this field inside the structure template which looks like that:
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<a href="${webContent.getFriendlyUrl()}">
${webContentData.title}
</a>
Of course, this code did not fit my needs but I checked the output of ${webContentData} jSON and noticed that I had className and classPK data there. Then I decided to fetch and display this journal content using the standard methods of JournalArticleLocalService . So I proceeded with this code:
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<#assign webJournalArticle = journalArticleLocalService.getArticle( groupId, webContentData.className, getterUtil.getLong(webContentData.classPK) ) />
<#assign webJournalArticleContent = journalArticleLocalService.getArticleContent( groupId, webJournalArticle.getArticleId(), "", locale, themeDisplay ) />${webJournalArticleContent}
This option seemed logic and correct for me, but for my surprise it generated an exception saying that: No approved JournalArticle exists with the key {groupId=XXXXX, className=com.liferay.journal.model.JournalArticle, classPK=XXXXXX} although such an article exists and is approved.
I really don't know how to proceed and solve this issue with ddm-journal-article content, so please any help or advice will be much appreciated.
Regards,
Eli
Ok, this is the workaround that I used to solve my issue:
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
<#assign assetEntryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") />
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<#assign asset = assetEntryLocalService.getEntry( webContentData.className, getterUtil.getLong( webContentData.classPK ) ) />
<#assign webArticle = asset.getAssetRenderer().getArticle() />
<#assign webArticleContent = journalArticleLocalService.getArticleContent( groupId, webArticle.getArticleId(), "", locale, themeDisplay ) />
${webArticleContent}
By the way, I tested the following method which is also working, but I personally prefer the first one:
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<#assign webArticle = journalArticleLocalService.getJournalArticleByUuidAndGroupId(webContentData.uuid, groupId) />
<#assign webArticleContent = journalArticleLocalService.getArticleContent( groupId, webArticle.getArticleId(), "", locale, themeDisplay ) />
${webArticleContent}
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
<#assign assetEntryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") />
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<#assign asset = assetEntryLocalService.getEntry( webContentData.className, getterUtil.getLong( webContentData.classPK ) ) />
<#assign webArticle = asset.getAssetRenderer().getArticle() />
<#assign webArticleContent = journalArticleLocalService.getArticleContent( groupId, webArticle.getArticleId(), "", locale, themeDisplay ) />
${webArticleContent}
By the way, I tested the following method which is also working, but I personally prefer the first one:
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
<#assign webContentData = jsonFactoryUtil.createJSONObject(webContent.getData()) />
<#assign webArticle = journalArticleLocalService.getJournalArticleByUuidAndGroupId(webContentData.uuid, groupId) />
<#assign webArticleContent = journalArticleLocalService.getArticleContent( groupId, webArticle.getArticleId(), "", locale, themeDisplay ) />
${webArticleContent}
I know I'm late, but others might find it useful.In 7.2 the taglibs are split into smaller ones and it is not well documented, but list could be found here: https://help.liferay.com/hc/en-us/articles/360029145851-FreeMarker-Taglib-Macros. In this case you are looking for `liferay-asset`, in FreeMarker you would use it like this:<#assign webContent = webContent.getData()?eval />
<@liferay_asset["asset-display"]
className = webContent.className
classPK = webContent.getLong(externalContent.classPK, 0)
/>
<@liferay_asset["asset-display"]
className = webContent.className
classPK = webContent.getLong(externalContent.classPK, 0)
/>
Copyright © 2025 Liferay, Inc
• Privacy Policy
Powered by Liferay™