Liferay 7: ADT custom for blog, how to get the post url - liferay-7

I've created a custom ADT for rendering blog posts. For each post I need the link "Read More".
I watch the BlogEntry class but I didn't find any url for the specified post.
I'm working with Freemarker.
Thanks in advance
Luis

<#if entries?has_content>
<#list entries as curBlogEntry>
<#assign
viewURL = renderResponse.createRenderURL()
/>
${viewURL.setParameter("mvcRenderCommandName", "/blogs/view_entry")}
${viewURL.setParameter("redirect", currentURL)}
${viewURL.setParameter("urlTitle", curBlogEntry.getUrlTitle())}
${viewURL.setParameter("p_p_state", "maximized")}
/* code */
Read More
</#list>
</#if>

Related

Display full name of logged in TYPO3 frontend user in Fluid

The task is pretty simple: I want to display the full name (first- and lastname) of the current TYPO3 frontend user in Fluid. But somehow, TYPO3 (version 9.5) or Fluid seems to cache data, so a logged in frontend user sometimes sees the name of other another logged user.
Current implementation:
TypoScript:
lib.username = USER_INT
lib.username.userFunc = Vendor\Extension\UserFunc\Username->getUsername
This is a USER_INT, so the output should always be uncached.
Fluid Layout - Default.html:
<f:render partial="Header" section="Top" />
Fluid Partial - Header.html:
<f:section name="Top">
<img src="logo.png">
<f:render partial="Navigation" />
</f:section>
Fluid Partial - Navigation.html
<f:security.ifAuthenticated>
<f:then>
<p>Logged in as: <f:cObject typoscriptObjectPath="lib.username" /></p>
</f:then>
<f:else>
<p>Not logged in</p>
<f:else>
</f:security.ifAuthenticated>
Why does the result of the cObject get cached? Should'nt this always be calculated per request, because lib.username is a USER_INT? I also tried to add a f:cache.disable ViewHelper to the template with no success.
In order to resolve the problem I refactored it to fetch the full name of the fe_user using a JavaScript XHR request to a simple PSR-15 middleware. Is this really the only suitable solution or am I missing something?
Update 17.12.2020
This all works fine. I just spotted a typo in my userFunc, which resulted in the unexpected behavior.
This happens because TYPO3 cache works with frontend user groups, not frontend users. So you will see results cached for the list of user's groups rather than the current user.
Use <v:render.uncache> ... </v:render.uncache> from EXT:vhs to render that part of code uncached. Alternatively you can modify TYPO3 caching to use the current user but this may decrease cache performance and seriously increase amount of cached items.
Beware, that there is a caching problem even with USER_INT and COA_Int see https://forge.typo3.org/issues/37988
You could use only TypoScript for that like:
lib.username = COA_INT
lib.username {
10 = TEXT
10.data = TSFE:fe_user|user|first_name
10.wrap = |
20 = TEXT
20.data = TSFE:fe_user|user|lastname_name
}
Why use TypoScript? It is very limited on what it can bring back. I just finished a tutorial where you can use a ViewHelper to add an ExtBase variable which assigns the whole user object in the FrontEnd and you can use it wherever you want with all it's relations, even the image, which is difficult to get via TypoScript.
TYPO3 tutorial
Best regards
share edit delete flag

Dynamic UID to edit the current news item

I use "Frontend_Editing" extension on TYPO3, to edit News items from Frontend.
How can i edit this code to change uid with the value of the current News item :
<core:contentEditable table="tx_news_domain_model_news" uid="9">
<f:render section="content" />
</core:contentEditable>
Did you have a look at the documentation of EXT:frontend_editing?
A full example for inline editing of a certain field looks like this:
<core:contentEditable table="{item.table}" field="{item.field}" uid="{item.uid}">
{item.bodytext}
</core:contentEditable>
I found the solution uid="{item.uid}" need to be uid="{newsItem.uid}"
So the code is :
<core:contentEditable table="tx_news_domain_model_news" uid="{newsItem.uid}">
<f:render section="content" />
</core:contentEditable>

Access flux fields from another Fluidtypo3 FCE element (flux, fluidcontent, vhs)

I'm trying to access the settings of a Fluidtypo3 FCE element. My FCE is a news article that I want to include in another FCE, which is a slider. The slider only has one field and the configuration is the following:
<flux:field.relation
name="articles"
label="News-Beitrag"
multiple="true"
size="6"
table="tt_content"
condition="AND tt_content.pid = {record.pid} AND CType = 'fluidcontent_content' AND colPos = 1 AND sys_language_uid = {record.sys_language_uid}"
minItems="1"
maxItems="10"
renderMode="default"
/>
This configuration works, I can select all my news FCE's as a relation. The field articles saves the uid's of all referenced FCE's. Now I am trying to use these uid's to receive the content. Right now my code is the following:
<f:section name="Main">
<f:if condition="{articles}">
{v:iterator.explode(content: '{articles}', glue: ",", as: 'articles')}
{v:content.get(contentUids: "{articles}", render: 0) -> v:variable.set(name: 'slides')}
<f:for each="{slides}" as="element">
</f:for>
</f:if>
</f:section>
The <v:content.get> ViewHelper gets the tt_content record as it is recorded in the database. The flux settings are stored in XML-Format in the field pi_flexform. I am trying to access those specific flux settings one by one and not just the whole pi_flexform field in xml format.
I've looked for ViewHelpers that can convert XML to an Array and tried many other things, but nothing worked for me. I am grateful for any ideas how to solve this problem.
<flux:form.data> is the Viewhelper you seek. You can use it like this:
<f:for each="{slides}" as="element">
<flux:form.data table="tt_content" field="pi_flexform" record="{element}" as="flexformData">
<!-- Do stuff with flexformData -->
</flux:form.data>
</f:for>

Grails one-to-many databinding with dynamic forms

I'm using Grails 2.3.5 and try to persist multiple domains coming from a dynamic form.
To achieve this, I used the approach with lazy lists like described in: http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/
The forms are genereated well and all the neccessary parameters are in the params-map,
but the binding to the list does not work.
I read a lot about this topic the last two days and found good answers on stackoverflow,
but I think these methods only work for older grails versions.
To illustrate my problem, some code:
House.groovy
class House {
....attributes removed to minimize example
List<Adress> adresses = [].withLazyDefault { new Adress() }
// List adresses = ListUtils.lazyList(new ArrayList<Adress>,FactoryUtils.instantiateFactory(Adress.class));
static hasMany = [adresses:Adress]
//def getAdresses(){
//return LazyList.decorate(adresses, FactoryUtils.instantiateFactory(Adress.class))
//}
static mapping = {
adresses cascade:"all-delete-orphan"
}
Template for dynamic forms --> Are created correctly
<div id="adress${i}" class="adresses-div" style="<g:if test="${hidden}">display:none;</g:if>margin-bottom:10px; ">
<g:hiddenField name='adresses[${i}].id' value='${adresses?.id}'/>
<g:hiddenField name='adresses[${i}].deleted' value='false'/>
<g:hiddenField name='adresses[${i}].neu' value="${adresses?.id == null?'true':'false'}"/>
<g:textField name='adresses[${i}].street' value='${adresses?.street}' />
<g:textField name='adresses[${i}].land' value='${adresses?.land}' />
<span class="del-adresses">
<img src="${resource(dir:'images/skin', file:'database_delete.png')}"
style="vertical-align:middle;"/>
</span>
HouseController - edit action
houseInstance.properties = params
So, the form templates are created correctly and the the input values are existent in the parameter map.
My problem is now the databinding for multiple adresses created from one form.
According to the example project provided by the link above, the parameter binding should automatically create new Adress-Objects and save them as childs for a house.
When debugging my application I can see that there are the right parameters but it seems that the list cannot create a new Adress-Object.
The 'adresses' list, contains a null value after binding--> [null]
Like mentioned above, I tried a few solutions for this problem, but couldn't resolve it.
Probably the lazylist approach is not supported in grails 2.3.5 and only works for older version.
I hope someone had the same same problem and can give me a hint
Thanks in advance
I have experience with the same problem.
Refer to this: grails 2.3 one-to-many databinding with dynamic forms
Try to remove id: in params if it's a new phone. Tested with grails 2.3.11 and using it in my project.
Here is what I changed in _phone.gsp
<div id="phone${i}" class="phone-div" <g:if test="${hidden}">style="display:none;"</g:if>>
<g:if test="${phone?.id != null}">
<g:hiddenField name='phones[${i}].id' value='${phone?.id}'/>
</g:if>
...
</div>
Thanks to #hakuna1811
After carefully reading the docs for grails 2.3.x, I saw how the parameter map should look like with multiple child-domains.
Example:
def bindingMap = [name: 'Skyscraper',
'addresses[0]': [street: 'FirstStreet'],
'addresses[1]': [street: 'SecondStreet']]
But my map looked like this:
def bindingMap = [name: 'Skyscraper',
'addresses[0]': [street: 'FirstStreet', 'SecondStreet']]
I have never noticed this before...
The problem was the jQuery code to clone all the necessary input fields and update
the corresponding ids. By removing this code and testing my application with two static address fields I got it to work.
<g:textField name="adresses[0].street" value=""/>
<g:textField name="adresses[0].zip" value=""/>
<g:textField name="adresses[1].street" value=""/>
<g:textField name="adresses[1].zip" value=""/>
As a short-term solution I decided to create predefined hidden forms. When clicking on the add-Button some simple jQuery will show one form...
The next couple of days I will review my code to get really dynamic behaviour. If I have results, I will add them to the topic here.

Fluid generate URI of another extension in TYPO3

I have a Typo3 Extbase plugin called "PluginOne".
And I have to call another Controller Action of the "PluginTwo" in "PluginOne".
How is it possible...
I tried this in PluginOne
<f:uri.action action='show' controller='Gallery' extensionName='PluginTwo' pluginName='PluginTwo' />
But it gnerate the wrong url, the generated url contains ID of the Current Plugin ie 'PluginOne'.
you can use
<f:uri.action action="list" controller="Inquirer" extensionName='PluginTwo' pluginName='PluginTwo' arguments="{uid: 1}" pageUid="62" />
this one,
it works for me