Render overridden fluid template - typo3

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

Related

Typo3 Fluid Template and Grid Elements: not rendering

I am doing first steps with Fluid templates and grid elements in Typo3 8.7.12. So far so good I have a functioning fluid template that works just fine.
Now I wanted to integrate grid elements (first time using it).
I installed the "gridelements" extension and loaded the static template to the page template. I created some grid elements with the wizard. They are showing in the BE and I can fill them with content. All good so far.
Then I added the following to my SETUP (as found here):
tt_content.gridelements_pi1.10 =< lib.stdheader
tt_content.gridelements_pi1.20.10.setup {
  4 < lib.gridelements.defaultGridSetup
 4 {
     cObject = FLUIDTEMPLATE
     cObject {
         file = fileadmin/fluid/templates/grid_2-1-2.html
     }
   }
}
Then I added the columns (column numbers are defined correctly) in my HTML template:
<div class="col-md-6 col-xs-12">
{data.tx_gridelements_view_column_10->f:format.raw()}
</div>
<div class="col-md-6 col-xs-12">
{data.tx_gridelements_view_column_11->f:format.raw()}
</div>
Is there anything more to it? Template is rendered but not the content of the Grid Element CE's.
Did you include the Gridelements static file containing the TypoScript setup for lib.gridelements.defaultGridSetup already?
if so, when checking your setup with the TypoScript Object Browser, what is the value of the userFunc within
tt_content.gridelements_pi1.20.10.userFunc
BTW: You might want to follow the instructions in that article to get a fully Fluid based output for your Gridelements: https://coders.care/blog/tutorial/gridelements-and-cms-8/
I got confused with the template files. I accidentally re-rendered the entire template within the template instead of the grid element template. Thanks to Joey‘s input I finally figured it out.

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

Insert after navbar

I'm using Typo3 6.2.15 with bootstrap_package.
I have inserted language bar after shopping basket. How to insert after navbar instead?
lib.navigation.basket.20 < lib.language
Screenshot from DOM: link
Have a look at template EXT:bootstrap_package/Resources/Private/Layouts/Page/Default.html. There you should see the lines
<f:render partial="Navigation/Main" arguments="{_all}"/>
<f:cObject typoscriptObjectPath="lib.navigation.breadcrumb"/>
You can overwrite this template in TypoScript constants:
page.fluidtemplate.layoutRootPath = EXT:yourExt/Resources/Private/Layouts/Page/
In the new template you now can make any modifications you want.
The best will be, you create a new TypoScript object for the basket:
lib.basket = TEXT
lib.basket.value = whatever
Then, you can arrange the contents in the layout template as you wish:
<f:cObject typoscriptObjectPath="lib.basket"/>
<f:render partial="Navigation/Main" arguments="{_all}"/>
<f:cObject typoscriptObjectPath="lib.language"/>
Don't assign the TypoScript objects to other TypoScript objects (like you do with "lib.navigation.basket.20 < lib.language"), modify the templates (but do not modify the original templates EXT:bootstrap_package, create your own template storage)!

Is it possible to set by fluid a argument that the typo3 backend uses as input

In the typo3 template I'm using the following line to get the last 5 added items from the backend and this works.
<f:cObject typoscriptObjectPath="lib.lastaddeditmes" />
Only the number of item I want to have it flexible and set in the fluid template. So for example like below where the qty is set to three, is this possible?
<f:cObject typoscriptObjectPath="lib.lastaddeditmes(3)" />
You can't do that in the view, instead you can make a copy of lib.lastaddeditmes in TypoScript and then use it in other place like:
lib.lastaddeditmesOnlyThree < lib.lastaddeditmes
lib.lastaddeditmesOnlyThree.someSetting.items = 3
and in view:
<f:cObject typoscriptObjectPath="lib.lastaddeditmesOnlyThree" />
Remember that TypoScript is just a configuration syntax (not programming language) so it shouldn't give you any huge performance drop.