news: Different settings via typoscript for multiple listviews on one page - typo3

Using the extension news I implemented three list views on one page with different colPos. Now I need to make some different settings for each list view. I would prefer doing this via TypoScript.
Is there a solution for this?
Many thanks and best regards!

It really depends which settings you need. One easy solution could be something like thins
plugin.tx_news.settings {
mainCol {
setting = abc
}
leftCol {
setting = def
}
}
and in the fluid templates
<f:if condition="{contentObjectData.colPos} == 3">
<f:then><f:variable name="mySettings">{settings.mainCol}</f:then>
<f:else><f:variable name="mySettings">{settings.leftCol}</f:else>
</f:if>
<f:render section="list" arguments="{_all}" />
<f:section name="list">
... do your stuff here
{mySettings -> f:debug(inline:1)}
</f:section>

Related

Render overridden fluid template

I want to override an extension's fluid template in Typo3 with my own template. My own template contains an if-condition. If not met, I want to include/render the extension's template (i.e. the overridden template) instead.
The actual case: I'm using the Typo3 News Extension which allows custom "template layouts". I want to add my custom template layout but also keep the News Extension's default template:
<!-- my_site_package/Resources/Private/Extensions/News/Templates/News/List.html -->
<f:if condition="{settings.templateLayout} == 2">
<f:then>
My specific list view for news entries
<ul>
<li>
...
</li>
</ul>
</f:then>
<f:else>
<!--
Include the original template here, e.g.
EXT:news/Resources/Private/Templates/Styles/Twb5/Templates/News/List.html
-->
</f:else>
</f:if>
How can I include / render the overridden template itself?
Fluid Is not able to Render the "Original Template" as there might be any number of TemplateRootpaths providing the Template. what you could do:
if the original Template is Part of an extension you controll, best to move the "Repeating" parts to an Partial. and let the Original Template use this partial as well.
if the original template is part of an extension you do not controll. (eg by a third party) you should copy the orignal template as partial in your Extension and then render this Partial. maybe ad a comment that this is an 1:1 copy of the original and shoud not be modified.
You can create another template layouts using page TSConfig, Define this TS in your root Page TSconfig (inside Resources) Tab.
plugin.tx_news {
templateLayouts {
1 = Homepage
2 = Specific list
}
}
then in your template you will get selected template value here in case 1 or 2.
You will find more help here.
https://docs.typo3.org/p/georgringer/news/main/en-us/Reference/TsConfig/General.html#confval-templateLayouts

Controller action - redirect to another template

I am looking for a way to redirect to another template if certain conditions are fulfilled.
Like:
public funtion redirectAction() {
if(certain conditions = TRUE){
REDIRECT TO ANOTHER TEMPLATE WITH DIFFERENT CONTENT
}
}
I've seen some expressions in existing actions:
$this->redirect('list');
In this case, 'list' is the default List.html template, right?
So I thought if I replaced the 'list' with a different template name, that would solve the problem. But i get a opps error.
Or is there any other solution of calling a different template?
Thank you very much!
with a redirect in the controller you always redirect to another function, not a template.
For example with
$this->redirect('list2');
You would then redirect to the function list2Action() and this would expect a Template List2.html
Often however, it is easier to use a switch in fluid.
for example:
<f:if condition="{abc} == 1">
<f:then>
<f:render partial="TempalteAbcTrue" arguments="{_all}" />
</f:then>
<f:else>
<f:render partial="TempalteAbcFalse" arguments="{_all}" />
</f:else>
If you used the normal folder structure of extbase you have a "Layouts", "Templates" and "Partials" folder.
With the example above you can create 2 files in the folder "Partials": "TempalteAbcTrue.html" and "TempalteAbcFalse.html".

Conditional hiding of tt_content div for plugin in Frontend

I am using TYPO3 8 and fluid_styled_content.
In am developing an extension with the following requirements: If specific conditions are met (depending on URL query parameter) nothing should be displayed for the plugin in the Frontend. In this case, the fluid output of the plugin will be empty (depending on a variable that is set in the Controller). But TYPO3 still - by default - renders a wrapping div and the header.
So, essentially, what I get is something like:
<div id="c217" class="...">
<header>
<h2 class="...">Header</h2>
</header>
<p> <!-- plugin output here is empty -- > </p>
</div>
How do I (dynamically) prevent that?
This has been asked before, but the solutions I found will not work with fluid_styled_content:
You should use the FSC way.
All content is rendered with templates which use layouts and partials. Aside from the simple CEs you have a template for plugins which requests a layout which renders the header.
Enhance the (global) layout with a special condition for your plugin to avoid the header (be sure to render the header by yourself) or avoid the header if your plugin will not render any output.
EDIT:
add the override template-pathes to FSC:
lib.contentElement {
templateRootPaths {
200 = EXT:your_extension_key/Resources/Private/FSC/Templates/
}
partialRootPaths {
200 = EXT:your_extension_key/Resources/Private/FSC/Partials/
}
layoutRootPaths {
200 = EXT:your_extension_key/Resources/Private/FSC/Layouts/
}
}
now you can copy the default-layout from the FSC folder to your layout folder and add in that layout a condition which skips the header and global wrapping if your plugin is rendered.
<f:if condition="{data.CType} == 'list' && {data.list_type} == 'myPlugin'">
<f:then>
<f:comment> only plugin output </fcomment>
</f:then>
<f:else>
<f:comment> original output with headers and wrap </fcomment>
</f:else>
</f:if>

TYPO3 - how to properly define constant, store it into variable and use inside of fluid template

In the Fluid template of plugin I am working on, some things are hardcoded. For instance:
<f:else>
<li>
<v:page.link pageUid="114" />
</li>
</f:else>
Since pageUid values are not same on test and production server I would like to make this more dynamic.
I would like to store this somehow in variable and then use the variable in the fluid template.
I just dont know hot to make this and where in TYPO3.
Thanks in advance!
Because it is an setting do it like this:
Constants:
plugin.myext.settings.detailPid = 123
Setup:
plugin.myext.settings.detailPid = {$plugin.myext.settings.detailPid}
Variables are for variable content. If you have the same PID using variables with TEXT or similiar is overdressed and settings are the correct way.
Also variables are only accessable for FLUID_TEMPLATE content element, not for plugins!
Also in your extbase controller you can access these settings by simple access $this->settings['detailPid']without to render the cObjects first.
In your fluid you can access settings by {settings.detailPid}.
In typoscript template for your content object FLUIDTEMPLATE:
Typoscript setup/configuration:
10 = FLUIDTEMPLATE
10 {
variables {
pageUid = TEXT
pageUid.value = 114
}
}
or using constants
Typoscript constants:
pageUid = 114
Typoscript setup/configuration:
10 = FLUIDTEMPLATE
10 {
variables {
pageUid = TEXT
pageUid.value = {$pageUid}
}
}
Then you can fetch pageUid in your Fluid HTML
<f:else>
<li>
<v:page.link pageUid="{pageUid}" />
</li>
</f:else>
To use variables in a Fluid partial, make sure to pass these along, e.g. by providing _all:
<f:render partial="fluid_part_header" arguments="{_all}" />
If you use EXT:vhs anyways, you can do the following to:
TS-Constants:
pageUid=114
TS-Setup:
settings.pageUid = {$pageUid}
Template (Fluid)
<f:else>
<li>
<v:page.link pageUid="{v:variable.typoscript(path: 'settings.pageUid')}" />
</li>
</f:else>
This will make it available for all FLUID Templates.
Please consider using jokumer's solution.
randomresult's solution would work, but I wouldn't suggest it. You don't need vhs to pass variables.
Not talking about Paul Beck`s solution, because it wouldn't work at all. Not anymore at least. (See TYPO3\CMS\Fluid\ViewHelpers\CObjectViewHelper, https://docs.typo3.org/typo3cms/ExtbaseGuide/Fluid/ViewHelper/CObject.html). It accepts only content objects.
Set your Pid in constants like PID_SOME_PAGE = 123 and set a variable in your plugins settings. Like this:
plugin.tx_yourplugin {
...
settings{
somePage = {$PID_SOME_PAGE}
}
...
}
You can bypass that constants version if you want and set your page id in settings directly. It's just a cleaner way in my opinion, especially for larger websites.
Then you can use that variable in your template, like this <f:link.page pageUid="{settings.somePage}">Go to Page</f:link.page>. More options for f:link.page here: https://docs.typo3.org/typo3cms/ExtbaseGuide/Fluid/ViewHelper/Link/Page.html

Dynamicly change TYPO3 fluid Layout by typeNum

I am using the extension fluidpages and want to switch the layout by the typeNum.
is it possible to change the f:layout by by an condition?
This wont work:
<f:layout name="{f:if(condition: '{typeNum} == 666', then: 'PageAjax', else: 'Page')}"/>
Suggested approach:
<f:layout name="Page/{typeNum}"/>
Required files:
Resources/Private/Layouts/Page/0.html
Resources/Private/Layouts/Page/666.html
Please note: this only works if the {typeNum} variable is guaranteed to exist - if it does not, you will face a "template file not found" error with an empty filename. To avoid this, you can use the VHS extension's v:var.convert ViewHelper to ensure a proper value:
<f:layout name="Page/{typeNum -> v:var.convert(type: 'integer')}"/>
I got the same problem recently, and found the solution after a few researchings.
The problem is, you can not use nested fluid like <f:if>, <f:cObject> or others in <f:layout>. Otherwise, you will get a fatal error in the cache file, saying call to a member function getViewHelper() on a non-object. And when you look at the cache file, you will find it's because $self is not defined.
Therefore, my solution is, searching public function getLayoutName( in \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler, and adding \$self = \$this; before \$currentVariableContainer = \$renderingContext->getTemplateVariableContainer();, just like generateCodeForSection()
I have now added the Condition in the Layout template. I get the typeNum from typoscript.
<f:if condition="{f:cObject(typoscriptObjectPath:'plugin.nc_template.settings.pageLayout')} == 'Default'">
<p>Default Template</p>
</f:if>
<f:if condition="{f:cObject(typoscriptObjectPath:'plugin.nc_template.settings.pageLayout')} == 'Ajax'">
<p>Ajax Template</p>
</f:if>
I found an example on the fedext Page, but could not get this to run:
https://fedext.net/blog/archive.html?tx_news_pi1[news]=55&tx_news_pi1[%40widget_0][currentPage]=8&cHash=f9c3165598a28d2aa98fd30ef115bb75
CanĀ“t you use an if-statement instead?
IMHO this is easier to read - and if you need to add more arguments which depends on typeNum, it would stay readable.
<f:if condition="{typeNum} == 666">
<f:then>
<f:layout name="PageAjax">
</f:then>
<f:else>
<f:layout name="Page">
</f:else>
</f:if>