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.
Related
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
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.
How can I check that a news article has a certain category? And when a news article is allocated to a certain category I want to add some additional information to the article (Detail). I tried this in Template/News/Detail.html e.g.:
//<f:for each="{categories}" as="category">
<f:if condition="{category.title} == 'Category01'">
<f:then>
<h4>It worked!</h4>
</f:then>
<f:else>
<h4>Didn't work!</h4>
</f:else>
</f:if>
//</f:for>
What works is e.g. this:
<!-- check category -->
<f:if condition="{newsItem.categories}">
<f:for each="{newsItem.categories}" as="category">
<f:if condition="{category.title} == 'Category01'">
<f:then>
<h4>It worked!</h4>
</f:then>
</f:if>
</f:for>
</f:if>
Using the extension DCE elements, I created a fluid template generating a li item for every item created. Now I would like to have every first to second item a wrapper. So that:
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
Becomes:
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
<ul>
<li>item 3</li>
<li>item 4</li>
</ul>
<ul>
<li>item 5</li>
</ul>
Is this possible in a fluid template? Perhaps in combination with Typoscript?
Solution
This is what I ended up with using {cycle} to iterate trough every 2 items, and then closing and opening the tag. As well as making sure the last item does not end with an opening tag:
<ul>
<f:for each="{field.item}" as="item" iteration="iterator">
<f:if condition="{iterator.cycle} % 2">
<f:then>
<li>item {iterator.cycle}</li>
</f:then>
<f:else>
<li>item {iterator.cycle}</li>
<f:if condition="{iterator.isLast} != 1">
<f:then>
</ul><ul>
</f:then>
</f:if>
</f:else>
</f:if>
</f:for>
</ul>
Note
I understand that with the power of VHS v:iterator.chunk would probably solve this with a little less code, but I could not get it to work how I wanted to. If anyone would be willing to provide a working example to compare the 2 options I would be grateful.
With VHS
Update: 21.12.2017
So revisited the chunk option, and the same code is achieved with the following snippet using VHS iterator.chunk:
<f:for each="{field.item -> v:iterator.chunk(count: 2)}" as="col" iteration="cycle">
<ul>
<f:for each="{col}" as="item">
<li>
test
</li>
</f:for>
</ul>
</f:for>
Perhaps this helps someone out there!
If you are using the VHS view helpers collection extension, then you can also use the Iterator\Chunked view helper:
<v:iterator.chunk count="4" subject="{menu}" as="entries">
<f:for each="{entries}" as="row">
<f:for each="{row}" as="page">
[...]
</f:for>
</f:for>
</v:iterator>
This is possible with regular Fluid, using the iterator of the for view helper.
<f:for each="{items}" as="item" iteration="itemIterator">
<f:if condition="{itemIterator.isOdd}">
<ul>
</f:if>
<li>{item.name}</li>
<f:if condition="{itemIterator.isOdd}">
<f:then>
<f:if condition="{itemIterator.isLast}">
</ul>
</f:if>
</f:then>
<f:else>
</ul>
</f:else>
</f:if>
</f:for>
The tricky part is the closing </ul> which is covered with the Fluid above.
Sure, you need the for viewhelper in addition to its counters/iterators. The you can use the if viewhelper to check for your condition.
The API has some examples: http://api.typo3.org/typo3cms/current/html/class_t_y_p_o3_1_1_c_m_s_1_1_fluid_1_1_view_helpers_1_1_for_view_helper.html#details
https://docs.typo3.org/typo3cms/ExtbaseGuide/Fluid/ViewHelper/For.html
I have one more solution, As for me - more native
<f:for each="{items}" as="item" iteration="itemIterator">
<f:cycle values="{0:'left', 1:'right', 3:'center'}" as="order">
<f:switch expression="{order}">
<f:case value="left">
<div class="left">Conetnt</div>
</f:case>
<f:case value="right">
<div class="right">Conetnt</div>
</f:case>
<f:case value="center">
<div class="center">Conetnt</div>
</f:case>
</f:switch>
</f:cycle>
</f:for>
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>