Liferay DXP web content field inside structure - liferay

Hello I've created a simple structure which only has 1 repeatable web content field. In my template I have the following code:
<#if WebContent75zf.getSiblings()?has_content>
<#list WebContent75zf.getSiblings() as cur_WebContent75zf>
<!-- Web Content Start -->
${cur_WebContent75zf.getData()}
<!-- Web Content End -->
</#list>
</#if>
The desired result would be either to show each web content rendered or at least get their data.
What I'm getting is the following and I'm wondering if I'm doing something wrong...
<!-- Web Content Start -->
{"className":"com.liferay.journal.model.JournalArticle","classPK":"40952"}
<!-- Web Content End -->
<!-- Web Content Start -->
{"className":"com.liferay.journal.model.JournalArticle","classPK":"40971"}
<!-- Web Content End -->
<!-- Web Content Start -->
{"className":"com.liferay.journal.model.JournalArticle","classPK":"40990"}
<!-- Web Content End -->

This: {"className":"com.liferay.journal.model.JournalArticle","classPK":"40971"} is what you need to retrieve the selected Web Content through the JournalArticleLocalService, you have just to get the classPK like this:
<#if WebContent75zf.getSiblings()?has_content>
<#list WebContent75zf.getSiblings() as cur_webContent>
<#assign cur_webContent_map = cur_webContent.getData()?eval>
<#assign cur_webContent_classPK = cur_webContent_map.classPK>
<#assign article = JournalArticleLocalService.getLatestArticle(cur_webContent_classPK?number)>
</#list>
</#if>

This works in Liferay 7.0. Make sure restricted variables are disabled in Liferay settings
<#-- Liferay 7.0 -->
<#-- Make sure restricted variables are disabled in Liferay settings -->
<#assign
serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()
themeDisplay = serviceContext.getThemeDisplay()
group_id = themeDisplay.getScopeGroupId()
JournalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
>
<#if WebContent75zf.getSiblings()?has_content>
<#list WebContent75zf.getSiblings() as cur_webContent>
<#assign
cur_webContent_map = cur_webContent.getData()?eval
cur_webContent_classPK = cur_webContent_map.classPK
article = JournalArticleLocalService.getLatestArticle(cur_webContent_classPK?number)
article_id = article.articleId
article_content = JournalArticleLocalService.getArticleContent(group_id, article_id, null, locale, themeDisplay)
>
${article_content}
</#list>
</#if>

Define journalArticleLocalService before use it:
<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />

Related

How To retrive freeMarkerPortletPreferences in Web content templates Liferay 7.4?

I am trying to use portletpreference in my nested webcontent in Liferay 7.4. In the 7.4 version, there are two tables [PortletPreferences] and [PortletPreferenceValue] for Preferences.
I am able to set the Preferences values but, having trouble in retrieving it in the template.
I have tried below code in my template for retriving the prefrences. I am not able to find any method which retrives PortletPreferenceValues.
<#assign portletPreferencesService = serviceLocator.findService("com.liferay.portal.kernel.service.PortletPreferencesLocalService") />
<#assign portletPreferncesValueService = serviceLocator.findService("com.liferay.portal.kernel.service.PortletPreferenceValueLocalService") />
<#assign portletKeys = staticUtil["com.liferay.portal.kernel.util.PortletKeys"]>
<#assign ownerId = groupId />
<#assign ownerType = portletKeys.PREFS_OWNER_TYPE_LAYOUT />
<#assign portletId = "com_liferay_journal_content_web_portlet_JournalContentPortlet" />
<#assign plid = 0/>
<#assign portletPreferences = portletPreferencesService.fetchPortletPreferences(ownerId, ownerType, plid, portletId) />
Can someone throw pointers on how to retrieve the same?
Thanks

Liferay Asset Publisher ADT get Image URL

I have created a structure in Liferay 7.2 that has an image selector. When I add the following to the ADT to get the image
<#assign
artImg = saxReaderUtil.createXPath("dynamic-element[#name='Imagean48']")
/>
it doesn't return the URL but instead returns a list.
<img src=" {" classpk":1923313,"groupid":"1912582","name":"spc_desktop_welcome_image3_benefits.jpg","alt":"man="" in="" suit","title":"spc_desktop_welcome_image3_benefits.jpg","type":"document","uuid":"db10a245-881c-d09c-ab64-4aeebc1581f0","fileentryid":"1923313","resourceprimkey":"2474428"}="" "="">
Is it possible to get just the URL of the image?
Evaluate artImg to a hash
<#assign
artImg = saxReaderUtil.createXPath("dynamic-element[#name='Imagean48']")
artImgHash = artImg?eval
/>
Get artImg DLFileEntry and then its URL
<#assign
dlFileEntryLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLFileEntryLocalService")
dlURLHelper = serviceLocator.findService("com.liferay.document.library.util.DLURLHelper")
artImgDLFile = dlFileEntryLocalService.getFileEntryByUuidAndGroupId(artImgHash.uuid, artImgHash.grouId)
artImgURL = dlURLHelper.getImagePreviewURL(artImgDLFile, themeDisplay)
/>
Then you can just use it in your img
<img src="${artImgURL}"/>
Note: I've replicated your artImg = saxReaderUtil.createXPath... line but I don't think it works. The right way would be something like this:
<#assign
journal = entry.getAssetRenderer().getArticle()
rootElement = saxReaderUtil.read(journal.content).getRootElement()
artImg = rootElement.selectSingleNode("dynamic-element[#name='Imagean48']")
/>

Simple pagination in FreeMarker with Spark Framework

I implement a simple blog use Spark Framework with FreeMarker. I need implement pagination in order to show only 5 entries per page, and it is not necessary to show page numbers, with next and previous buttons would be fine. However, I don't even know where to begin in the pagination. This my current code to show all the entries:
<#list entries as art>
<h2>
${art.getTitle()}
</h2>
<p>
Author: ${art.getAuthor().getName()}
</p>
<p><span class="glyphicon glyphicon-time"></span>${art.getDate()}</p>
<hr>
<#assign body=art.getBody()>
<#if body?length < 70>
${body}
<#else>
${body?substring(0,70) + "..."}
</#if>
<br><br>
<a class="btn btn-primary" href="/Entrada/${art_index}">Read More<span class="glyphicon glyphicon-chevron-right"></span></a>
<hr>
</#list>
Also, here is the backend code in Spark Framework:
get("/Home", (request, response) -> {
Map<String, Object> attributes = new HashMap<>();
attributes.put("entries", entrie.getEntries());
return new ModelAndView(attributes, "index.ftl");
}, freeMarkerEngine);
Any help would be appreciated, thanks in advance!
Usually you paginate before putting the list into the model, because then you can avoid loading the entries that you won't show anyway. So simply only pass the list of entries that you will actually show on the current page (as opposed to the whole list), and also pass a pageNumber and totalPages variable (two numbers) that you can use in the template.
BTW, in the template, art.getAuthor().getName() can be written as art.author.name. body?substring(0,70) can be written as body[0 .. 70].

How to add asset publisher configuration options in LifeRay 6.2

When using an asset publisher, you can change Display Settings in the asset publisher configuration panel. If you select the Abstracts display template, a new option will be available for you (Abstract Length). How can I add an option like that to my Application Display Templates (ADT) ?
Example for the Abstracts template :
Example for my custom template (Abstract Length not available):
You can use substring in velocity code written inside ADT built for news asset publisher, check below code to display 100 character only of about us page
#if (!$entries.isEmpty())
<div class="news">
#foreach ($entry in $entries)
#set($renderer = $entry.getAssetRenderer() )
#set($className = $renderer.getClassName() )
#if( $className == "com.liferay.portlet.journal.model.JournalArticle" )
#set( $journalArticle = $renderer.getArticle() )
#set( $document = $saxReaderUtil.read($journalArticle.getContent()) )
#set( $rootElement = $document.getRootElement() )
#set( $xPathSelector = $saxReaderUtil.createXPath("dynamic-element[#name='country-portal-image']") )
#set( $countryPortalImage = $xPathSelector.selectSingleNode($rootElement).getStringValue() )
#set( $xPathSelector = $saxReaderUtil.createXPath("dynamic-element[#name='country-portal-title']") )
#set( $countryPortalTitle = $xPathSelector.selectSingleNode($rootElement).getStringValue() )
#set( $xPathSelector = $saxReaderUtil.createXPath("dynamic-element[#name='country-flag-icon']") )
#set( $countryFlagIcon = $xPathSelector.selectSingleNode($rootElement).getStringValue() )
#set( $xPathSelector = $saxReaderUtil.createXPath("dynamic-element[#name='country-portal-about-us']") )
#set( $countryPortalAboutUs = $xPathSelector.selectSingleNode($rootElement).getStringValue().substring(0,100) )
#set( $link = $renderer.getURLViewInContext($renderRequest, $renderResponse, '') )
#set( $viewURL = $assetPublisherHelper.getAssetViewURL($renderRequest, $renderResponse, $entry))
#set($news-summary =$entry.getSummary($locale))
#set($date = $dateTool.format("dd/MM/yyyy hh:mm:ss", $dateTool.toDate( "EEE, dd MMM yyyy hh:mm:ss Z" , $entry.getPublishDate())))
<div class="new">
<h1 class="title">$entry.getTitle($locale)</h1>
$date
<img src="$countryFlagIcon"/>
<img src="$countryPortalImage"/>
<h3 class="sub-title">$countryPortalAboutUs</h3>
<p class="read-more">
Read More
</p>
</div>
#end
#end
</div>
#end
You can create JSP hook to customize Asset Publisher configuration.
The original configuration is rendered by /html/portlet/asset_publisher/configuration.portal.jsp.
In your hook, you can include the original jsp and then add your own preferences.
Example:
<%-- Include the original Asset Publisher configuration JSP. --%>
<%#include file="/html/portlet/asset_publisher/configuration.portal.jsp"%>
<%-- Read current value from portlet preferences. --%>
<% String abstractLength = portletPreferences.getValue("abstractLength", "100"); %>
<%-- Hidden div with custom input fields. --%>
<div id="customPreferences" style="display: none;">
<aui:fieldset label="fieldset.abstractLength">
<aui:input name="abstractLength" label="abstractLength" value="<%= abstractLength %>">
<aui:validator name="number"/>
<aui:validator name="min">1</aui:validator>
</aui:input>
</aui:fieldset>
</div>
<%-- JS code to place custom preferences at the end of Display Settings tab. --%>
<%-- It uses jQuery, but it's not a requirement. --%>
<script>
$(document).ready(function () {
// find div with custom preferences
var $customPreferences = $("#customPreferences");
// find the last fieldset on Display Settings tab
var displaySettingsLastFieldset = $(".nav-tabs:eq(1)").siblings("div:eq(1)").children().filter("fieldset").last();
// insert custom preferences after the last fieldset on Display Settings tab
$customPreferences.insertAfter(displaySettingsLastFieldset);
// show custom preferences
$customPreferences.show();
});
</script>
It is a good approach to extend the original JSPs - ie. include the original and then make the customization. This way, there's a good chance of a painless update to next Liferay versions.
For general guidelines on how to implement JSP hooks, see Liferay Developer's Guide.
You can get a list of all the available portletPreference values available to the asset publisher ADT using:
<#list portletPreferences?keys as prop >
<li>
${prop}
</li>
</#list>
So, for your example, you could get the abstract length value set by the user using:
abstractLength: ${portletPreferences.abstractLength[0]}
best way if you creating your own ADT then manage content length in ADT instead of unnecessarily hooking of AP jsp.

c# fill something on html page

how can I fill "MyUserName" on
<td width="18%" class="more"><div align="right">¿¿¿¿¿¿ </div></td>
<td width="82%">
<font color="#FFFFFF" face="MS Sans Serif, Tahoma, sans-serif">
<input type=text name="QTitle" size=51 maxlength=100 class=violet>
</font>
</td>
i try in c# but it not work please help
private void webBrowser2_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
}
private void LoadProfileInformation()
{
DataSet dsNew = new DataSet();
//Some code to fetch information if you store it in a DB
//else you can put in static info if you may want.
//so you will nto need the dataset.
QTitle.Text = "MyUserName";
}
You can store it in the class then access it with code behinds like <%= myVar %> in your front end.
if you want to modify the values of divs on the front end then you need to use asp tags like
<asp:label runat="server" name="Qtitle"> </asp:label>
First of all you really need to think about moving to newer versions of XHTML/HTML! (I suggest you that because of your markup code).
In the other hand, in order to get your "QTitle" text set from server, you'll need to set "runat" attribute to "server" in your input, but, if you're using standard (X)HTML elements, you won't have such property "Text".
I suggest you to use a server control like TextBox which has the whole "Text" property:
<asp:TextBox ID="QTitle" runat="server" CssClass="Violet" />
Some server code-behind:
QTitle.Text = "Hello world";
Another suggestion is you won't be setting any property after PreRender ASP.NET Page life-cycle event.
Is the mark-up at the top of your question the resulting html or the source code for the form you are working with? If this is in-fact your asp.net form, try replacing the input tag with the following...
<asp:TextBox id="QTitle" runat="server" />
If the form is properly linked to the C# codebehind file you are using, QTitle.Text should now be accessible.

Resources