Search code examples
typo3tx-newstypo3-9.x

group news by year in frontend (TYPO3, news system)


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.


Solution

  • 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.