I am using TYPO3 9, News Plugin (News system).
I am looking for a way to group news articles by year, like this:
2019
--------
article 1
article 2
article 3
--------
2018
--------
article 1
article 2
...
I can't find an easy solution for this and find it hard to believe that the only way to implement this is to edit TYPO3's source code...
Can anyone help?
-------------------------- Edit
Fixed and working code suggested by Bernd Wilke:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:n="http://typo3.org/ns/GeorgRinger/News/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:layout name="General" />
<!--
=====================
Templates/News/List.html
-->
<f:section name="content">
<!--TYPO3SEARCH_end-->
<f:if condition="{news}">
<f:then>
<f:variable name="oldYear">2010</f:variable>
<f:for each="{news}" as="newsItem" iteration="iterator">
<f:variable name="currentYear"><f:format.date format="%Y">{newsItem.datetime}</f:format.date></f:variable>
<f:if condition="{oldYear} < {currentYear}">
<hr />
<h3>{currentYear}</h3>
<hr />
</f:if>
<f:render partial="List/Item" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:for>
</f:then>
<f:else>
<div class="alert ">
<f:translate key="list_nonewsfound" />
</div>
</f:else>
</f:if>
<!--TYPO3SEARCH_begin-->
</f:section>
</html>
However, I award this question to Georg Ringer as his solution was working right away.
Of course this is possible by fluid by using the ViewHelper f:groupedFor, see official documentation.
There is also an example in the docs of the news extension. So the example should work like that
<f:groupedFor each="{news}" as="groupedNews" groupBy="yearOfDatetime" groupKey="year">
<div style="border:1px solid blue;padding:10px;margin:10px;">
<h1>{year}</h1>
<f:for each="{groupedNews}" as="newsItem">
<div style="border:1px solid pink;padding:5px;margin:5px;">
{newsItem.title}
</div>
</f:for>
</div>
</f:groupedFor>
however I also want to warn about the following
Keep an eye on performance!
To be able to group the records, fluid
will load every record itself and groups those afterwards. If you plan
to group many records just for getting something like a count, maybe
it is better to fire the query directly and don’t use fluid for that.
However if the result is on a cacheable page, the issue is only relevant on the first hit.
There is no typoscript option for grouping like this.
But you can do it in FLUID:
Copy the template files for news listing to your (site) extension and modify it according to your needs: build in a group processing.
<f:variable.set name="oldYear">0000</f:variabel.set>
<f:for each="{news}" as="newsItem" iteration="iterator">
<f:variable.set name="currentYear">{newsItem.datetime->f:format.date("Y")}</f:varaible.set>
<f:if condition="{oldYear} == {currentYear}">
<hr />
<h3>{currentYear}</h3>
<hr />
<f:variable.set name="oldYear">{currentYear}</f:variable.set>
</f:if>
<f:render partial="List/Item" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:for>
You might use one of the viewhelpers mentioned in this answer or this answer.
Related
I'm trying to show a list of related news articles in detail view (working) but I want to render "only non-archived entries"
Is this possible with Fluid and how? Maybe with filters?
My code is pretty standard. Nothing special:
...
<f:for each="{newsItem.allRelatedSorted}" as="related">
<li>
<span class="news-related-news-date"><f:format.date format="{f:translate(key:'dateFormat')}">{related.datetime}</f:format.date></span>
<n:link newsItem="{related}" settings="{settings}" title="{related.title}">
{related.title}
</n:link>
<f:render partial="Detail/FalMediaContainer" arguments="{media: related.falMedia, settings:settings}" />
<f:render partial="Detail/MediaContainer" arguments="{media: related.media, settings:settings}" />
</li>
</f:for>
...
Thank you!
I have a fluid template language navigation in which i use bootstrap which looks like follows:
<f:for each="{config.lang.uid}" as="lang" iteration="iterator">
<f:if condition="{languageNavigation.{iterator.index}.available}">
<f:then>
<a
href="{languageNavigation.{iterator.index}.link}"
class="dropdown-item{f:if(condition: '{languageNavigation.{iterator.index}.active}', then: ' active')}"
hreflang="{config.lang.hreflang.{lang}}"
title="{config.lang.title.{lang}}"
>
<span>
<f:if condition="{settings.navbar.langFlags}">
<core:icon identifier="{config.lang.flag.{lang}}" size="small" />
</f:if>
{config.lang.title.{lang}}
</span>
</a>
</f:then>
<f:else>
<span class="dropdown-item text-muted">
<f:if condition="{settings.navbar.langFlags}">
<core:icon identifier="{config.lang.flag.{lang}}" size="small" />
</f:if>
{config.lang.title.{lang}}
</span>
</f:else>
</f:if>
</f:for>
when I'm in the detail view of a news article and I switch the language, the parameters of the query are not translated, so it basically sends me to an empty detail page
I've been trying for hours to fix this problem but I don't seem to find a solution……
I use route enhancer to translate the detail view URLs query into the news title
the nearest i've found is to add following to the link:
addQueryString="TRUE" addQueryStringMethod="GET"
but this only seems to work in < f:link.page > and I can't use
href="{languageNavigation.{iterator.index}.link}"
in <f:link.page>
i've tried with < link.typolink > as well but in both methods i lose the language-switching-goal, even if i use
lang={config.lang.hreflang.{lang}} which would translate to en-US or de-DE in the site configuration……… it just renders the link to the detail page in the current language for all links in menu
any help? I think i've reached my capabilities to solve this
I'd be grateful for any solution
-----------------Example------------------
lets say i have the following URL which is a page with the news plugin detail view of an article:
https://my.domain/news/detail/news-title
When I go to my language navigation of this page the domains rendered are:
EN: https://my.domain/news/detail/
DE: https://my.domain/de/news/detailansicht/
so, the /news-title at the end basically gets lost
If I'm navigating only in german site and I'm standing in the news list page:
https://my.domain/de/news/
from there, all links are rendered correctly, so if i go to the list item of article in question it would send me to:
DE: https://my.domain/de/news/detailansicht/news-title
So, that's what I mean with the question, the problem only appears when I'm already in the detail view page, and I want to switch the language with the navbarmenu.
instead of rendering
https://my.domain/LANG/news/detail/news-title it renders
https://my.domain/LANG/news/detail/
Did you tried the LanguageMenuDataProcessor? With it, the links are
all correct. See:
https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/ContentObjects/Fluidtemplate/Index.html?highlight=languagemenuprocessor#dataprocessing
In older TYPO3 versions DataProcessing of menu was
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
special = languages
as = languageNavigation
}
Now it uses
10 = TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor
10 {
languages = auto
as = languageNavigation
}
This solved my Problem, thanx for the hint #Thomas Löffler
I've also updated my template to make the code more simple by getting rid of the iterator and its index:
<f:section name="Language">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="language" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<f:for each="{languageNavigation}" as="item">
<f:if condition="{item.active}">
<f:if condition="{settings.navbar.langFlags}">
<core:icon identifier="{config.lang.flag.{item.languageId}}" size="small" />
</f:if>
<span class="nav-label">{item.title}</span>
</f:if>
</f:for>
</a>
<div class="dropdown-menu dropdown-menu-right mt-0 language-menu">
<f:for each="{languageNavigation}" as="item">
<f:if condition="{item.available}">
<f:then>
<a
href="{item.link}" hreflang="{item.hreflang}" title="{item.title}"
class="dropdown-item{f:if(condition: '{item.active}', then: ' active')}"
>
<f:if condition="{settings.navbar.langFlags}">
<core:icon identifier="{config.lang.flag.{item.languageId}}" size="small" />
</f:if>
{item.title}
</a>
</f:then>
<f:else>
<span class="dropdown-item text-muted">
<f:if condition="{settings.navbar.langFlags}">
<core:icon identifier="{config.lang.flag.{item.languageId}}" size="small" />
</f:if>
{item.title}
</span>
</f:else>
</f:if>
</f:for>
</div>
</li>
</f:section>
Did you tried the LanguageMenuDataProcessor? With it, the links are all correct. See: https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/ContentObjects/Fluidtemplate/Index.html?highlight=languagemenuprocessor#dataprocessing
currently I'm trying to split up the topnews from regular news within a tx_news template. I need to insert a subheadline between topnews and the regular news.
So is there a chance to split the regular template?
<f:section name="content">
<!--TYPO3SEARCH_end-->
<f:for each="{newsItem.categories}" as="category" iteration="iteratorCategories">
<div class="{category.title}"></div>
</f:for>
<f:if condition="{news}">
<f:then>
<div class="news-list-view">
<f:if condition="{settings.hidePagination}">
<f:then>
<f:for each="{news}" as="newsItem" iteration="iterator">
<f:render partial="List/Item" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:for>
</f:then>
<f:else>
<n:widget.paginate objects="{news}" as="paginatedNews" configuration="{settings.list.paginate}" initial="{offset:settings.offset,limit:settings.limit}">
<f:for each="{paginatedNews}" as="newsItem" iteration="iterator">
<f:render partial="List/Item" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:for>
</n:widget.paginate>
</f:else>
</f:if>
</div>
</f:then>
<f:else>
<div class="no-news-found">
<f:translate key="list_nonewsfound" />
</div>
</f:else>
</f:if>
<!--TYPO3SEARCH_begin-->
<div class="showmorenews">
<span><f:translate key="loadmore" /></span>
</div>
</f:section>
thanks a lot
The easiest thing would be to split that into 2 plugins, one to render only top news and one which only renders non-top news.
In the template, you can e.g check the {demand} property to know which plugin renders what or by using a custom layout.
I am using TYPO3 7.6.11 and indexed_search 7.6.0.
I use the extbase plugin for indexed_search and in the output it escapes the HTML-Tags to mark the searchword. For example, when I search for "search" I get this output:
Test text with<strong class="tx-indexedsearch-redMarkup">search</strong> pattern.
I found this bugfix to this problem: https://forge.typo3.org/issues/77901
But the file PageBrowsingResultsViewHelper.php doesn't look exactly the same, and even when I add the variable protected $escapeOutput = false; it doesn't change anything.
Any idea where this is come from and where I can disable the escaping?
It was another extension who overwrote a Partial of tx_indexedsearch that caused the problem.. -> Always check if the template you are working on is the one that gets outputted ;)
This happen because of format object rendering.your result will render in {row.description} object and initially there is no format set. you have to format your result({row.description}) to the HTML. For that:
Go to the search result file.
yourindexsearch/templatingpath/IndexedSearch/Partials/Searchresult.html
Here is the complete file:
<div class="fourffCom col-sm-6">
<f:format.html><h2>{row.title}</h2></f:format.html>
<f:if condition="{row.headerOnly} == 0">
<!-- Format html -->
<f:format.html>{row.description}</f:format.html>
<ul>
<li>
<p><f:translate key="result.size" /> </p>
<b>{row.size}</b>
</li>
<li>
<p class="tx-indexedsearch-text-item-crdate"><f:translate key="result.created" /> </p>
<b class="tx-indexedsearch-text-item-crdate"><f:format.date>#{row.created}</f:format.date></b>
</li>
<li>
<p class="tx-indexedsearch-text-item-mtime"><f:translate key="result.modified" /> </p>
<b class="tx-indexedsearch-text-item-mtime"><f:format.date>#{row.modified}</f:format.date></b>
</li>
<li>
</li>
<li>
<p><f:translate key="result.path" /> </p>
<b><f:format.html>{row.path}</f:format.html></b>
</li>
</ul>
</f:if>
<f:if condition="{row.headerOnly} == 1">
<!-- Format html -->
<f:format.html>{row.description}</f:format.html>
</f:if>
<f:if condition="{row.subresults}">
<p class="tx-indexedsearch-list">
<f:for each="{row.subresults.items}" as="subrow">
<f:render partial="Searchresult" arguments="{row: subrow}" />
</f:for>
</p>
</f:if>
</div>
Is there any possibilities tu use something like the alternating template parts in tx_news extension? In standard tt_news template I used to use <!-- ###NEWS_1###--> <!-- ###NEWS_2###--> <!-- ###NEWS_3###--> etc. In tx_news everything is in Fluid and I don't see anything similar to alternating template parts in manual.
Ok, again as answer:
You can just do this in fluid, there is no need for a specific feature. The news are rendered in a for-loop, which provides a variable with the current index, see the documentation.
Use the loop index modulo your number of different templates to render news differently in an alternating way. The iteration-variable provides some more subproperties that you can use for controlling the output. To see them all, use <f:debug>{iterator}</f:debug>.
For example, in the list-view of EXT:news you can do this to get three alternating templates, each one represented by a partial. Only the relevant inner loop is shown:
<f:for each="{news}" as="newsItem" iteration="iterator">
<f:if condition="{iterator.index} % 3 == 0">
<f:render partial="List/Item_Layout1" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:if>
<f:if condition="{iterator.index} % 3 == 1">
<f:render partial="List/Item_Layout2" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:if>
<f:if condition="{iterator.index} % 3 == 2">
<f:render partial="List/Item_Layout3" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</f:if>
</f:for>
If you have EXT:vhs installed with namespace shortcut v (very good extension!), this can be done a bit more elegant:
<f:for each="{news}" as="newsItem" iteration="iterator">
<v:switch value="{iterator.index} % 3">
<v:case value="0" break="true">
<f:render partial="List/Item_Layout1" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</v:case>
<v:case value="1" break="true">
<f:render partial="List/Item_Layout2" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</v:case>
<v:case value="2" break="true">
<f:render partial="List/Item_Layout3" arguments="{newsItem: newsItem,settings:settings,iterator:iterator}" />
</v:case>
</v:switch>