TYPO3 MenuProcessor with dynamic uid - typo3

I want to use the MenuProcessor dynamic in my fluidtemplate.
Configured in TypoScript, I want to call it with the cObject ViewHelper and pass the uid of a page to it:
{f:cObject(typoscriptObjectPath: 'lib.menuTest', data:{menuId:'28'})}
This is what I have tried - it should be a special = directory with the the given uid in special.value = XXXXXX.
lib {
menuTest = FLUIDTEMPLATE
menuTest {
templateName = MenuTest
templateRootPaths {
10 = EXT:hatemplate/Resources/Private/Templates/
}
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
special = directory
special.value = XXXXXX
levels = 1
as = menuItems
}
}
}
}
If I set a uid directly it works, but I don't know how to insert the variable. Has anyone a hint or a working solution?
Thank you

I have solved it with the help of a friend who is much more experienced in TypoScript.
I wasn't as wrong as I thought.
This is the Code in TypoScript. I added the tamplate,layout and partial paths for future copy/pasting :) :
lib {
menuDirectory = FLUIDTEMPLATE
menuDirectory {
templateName = MenuDirectory
layoutRootPaths {
10 = EXT:hatemplate/Resources/Private/Layouts/
}
templateRootPaths {
10 = EXT:hatemplate/Resources/Private/Templates/
}
partialRootPaths {
10 = EXT:hatemplate/Resources/Private/Partials/
}
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
special = directory
special.value.field = menuId
levels = 1
as = directory
}
}
}
}
With this configured you can use the f:cObject ViewHelper like this:
<f:cObject typoscriptObjectPath="lib.menuDirectory" data="{menuId:1}" />
Or inline
{f:cObject(typoscriptObjectPath: 'lib.menuDirectory', data:{menuId:1})}
This renders the Items into the fluidtemplate:

Related

TYPO3: Disable cache of custom DataProcessor output

I have an own DataProcessor, fetching and returing a random record.
This works as long as cache is disabled. How can I disable caching of this specific dataprocessor to display another result on every page load?
Like COA_INT would do?
My DataProcessor:
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData): array
{
$heroResult = $this->heroQueryBuilder->fetchRandom($cObj->data['uid']);
$heros = $this->dataMapper->map(Hero::class, $heroResult);
if (count($heros)) {
$hero = $heros[0];
if ($hero instanceof Hero) {
$targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, 'hero');
$processedData[$targetVariableName] = $hero;
}
}
return $processedData;
}
My query builder statement, returning one result sorted random:
public function fetchRandom(int $pageUid, int $limit = 1): array
{
return $this->queryBuilder
->select('*')
->where(
$this->queryBuilder->expr()->eq('pid', $this->queryBuilder->createNamedParameter($pageUid, \PDO::PARAM_INT))
)
->addSelectLiteral('rand() AS random_sort')
->orderBy('random_sort')
->from(self::TABLE_NAME)
->setMaxResults($limit)
->execute()
->fetchAll();
}
Calling the dataProcessor in my page object:
page = PAGE
page {
10 = FLUIDTEMPLATE
10 {
dataProcessing {
20 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
20 {
special = list
special.value = 1
as = rootpage
dataProcessing {
10 = Vendor\Extension\DataProcessing\HeroProcessor
10 {
as = hero
}
}
}
}
}
}
Rendering the result in my page layout
<f:if condition="{rootpage.0.hero}">
<div class="c-page__hero">
<f:render partial="Page/Hero/Hero" arguments="{hero:rootpage.0.hero}" />
</div>
</f:if>
How can I disable caching just for this specific DataProcessor? Do I have to convert the cObj e.g. by calling $cObj->convertToUserIntObject()? Any ideas?
Solved by creating a COA_INT object. Thought, there might be a better way without having to use f:cObject viewhelper.
lib.hero = COA_INT
lib.hero {
10 = FLUIDTEMPLATE
10 {
file = {$pmWebsite.view.partialRootPath}/Page/Hero/Hero.html
dataProcessing {
10 = Vendor\Extension\DataProcessing\HeroProcessor
10 {
pid = 1
as = hero
}
}
}
}

TYPO3 MenuProcessor shows root page when empty?

I have a basic menu element using the Pages field and the MenuProcessor.
In the fluid template I only want to output something only if there are pages in the Page field. But if the field is empty the MenuProcessor adds the root page to the array.
How do I prevent the root page being added to what should be an empty array?
typoscript looks like this:
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
special = list
special.value.field = pages
levels = 1
as = menuItems
expandAll = 1
includeNotInMenu = 1
titleField = nav_title // title
}
}
I suppose it is a very special edge case (which could be handled in the menu processor, you might open a ticket on https://forge.typo3.org ).
As you have identified the reason with empty input parameters you might build a condition on that case.
Either in FLUID or in typoscript.
In typoscript you could add a stdWrap function:
10 {
:
if.isTrue.field = pages
}
Did you try the entryLevel?
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
entryLevel = 0
}
}

InvalidTemplateResourceException after move to new server

i have a site package extension for my template in Typo3 9.5. Furthermore I have another extension for a specific purpose. Now this extension searches in the ProviderExtension for template files!?!? On my development machine everything works fine. After I have transferred everything to a remote server, this exception occurs on those pages where the plugin of the extension is included. Other pages work.
The Fluid template files enter code here
"/home/.sites/822/site4946398/web/bttemplate/public/typo3conf/ext/amtstafel/Resources/Private/Partials/Navigation/Top.html",
"/home/.sites/822/site4946398/web/bttemplate/public/typo3conf/ext/amtstafel/Resources/Private/Partials/Navigation/Top"
could not be loaded.
Here is the typoscript fom the Site-Template
page = PAGE
page {
config.index_enable = 1
typeNum = 0
shortcutIcon = EXT:btbuerger2/Resources/Public/Icons/favicon.ico
10 = FLUIDTEMPLATE
10 {
templateName = TEXT
templateName {
cObject = TEXT
cObject {
data = pagelayout
required = 1
case = uppercamelcase
split {
token = pagets__
cObjNum = 1
1.current = 1
}
}
ifEmpty = Default
}
templateRootPaths {
0 = EXT:btbuerger2/Resources/Private/Templates/Page/
1 = {$page.fluidtemplate.templateRootPath}
}
partialRootPaths {
0 = EXT:btbuerger2/Resources/Private/Partials/Page/
1 = {$page.fluidtemplate.partialRootPath}
}
layoutRootPaths {
0 = EXT:btbuerger2/Resources/Private/Layouts/Page/
1 = {$page.fluidtemplate.layoutRootPath}
}
...
The extension amtstafel has a static typoscript which is included in the Main-Template. Here templateRootPaths and layoutRootPaths is defined. As mentioned, the Extension was built with Extension-Builder and works fine so long..
plugin.tx_amtstafel_bulletinentry {
view {
templateRootPaths.0 = EXT:{extension.shortExtensionKey}/Resources/Private/Templates/
templateRootPaths.1 = {$plugin.tx_amtstafel_bulletinentry.view.templateRootPath}
layoutRootPaths.0 = EXT:tx_amtstafel/Resources/Private/Layouts/
layoutRootPaths.1 = {$plugin.tx_amtstafel_bulletinentry.view.layoutRootPath}
}
"bttemplate" is the template extension, "amtstafel" is the additional extension.
In the place of .../amtstafe/... there is not need for partials ...
Thank you for help!
Thomas
I suspect that your constant page.fluidtemplate.partialRootPath is set to EXT:amtstafel/Resources/Private/Partials/
This constant is used in your page.10.templateRootPaths.1

Pass Fluid variable to TypoScript

I want to pass a variable (uid of category) in Fluid to a TypoScript :
<f:cObject typoscriptObjectPath="lib.testFluid" data="{setting.myvar}/>
Then i want to use the var to get all content elements in folder with pid 942 and the category {setting.myvar}
lib.testFluid = COA
lib.testFluid = CONTENT
lib.testFluid {
table = tt_content
select {
pidInList = 942
where = selected_categories = |
}
}
This does not work, it creates an MySql syntax error. I also tried using current = 1 instead of the where clause without success. I looked at post TYPO3: pass variable to typoscript via cObject? and I can recreate it but it does not work with my script. (TYPO3 8)
If i use
...
where = selected_categories = 13
....
the scrip will succesfully display all CE with category 13. How do i make it work with a var?
could you try this:
<f:cObject typoscriptObjectPath="lib.testFluid" data="{myvar: setting.myvar}/>
lib.testFluid = CONTENT
lib.testFluid {
table = tt_content
select {
pidInList = 942
where.data = field:myvar
where.intval = 1
where.wrap = selected_categories=|
}
}
hard to test for me but it might work ...
I had to solve it once with markers. I couldn't find another simpler way. I give you a very general solution which you may adapt to your needs. For example you could set the pid value via a typoscript setting which is more elegant than to put it in the snippet code. Please try:
<f:cObject typoscriptObjectPath="lib.testFluid" data="{category: setting.myvar, catPid: 942}" currrentValueKey="category" />
The related TypoScript snippet:
lib.testFluid = COA
lib.testFluid {
10 = LOAD_REGISTER
10 {
category.cObject = TEXT
category.cObject.value.current = 1
catPid.cObject = TEXT
catPid.cObject.value.dataWrap = { field: catPid }
}
20 = CONTENT
20 {
table = tt_content
select {
pidInList.cObject = TEXT
pidInList.cObject.dataWrap = {REGISTER:catPid}
where = selected_categories=###category###
markers {
category.data = REGISTER:category
}
}
}
30 = RESTORE_REGISTER
}

fallback for FILES in typoscript

I'm using typoscript go get the first file out of a page. This works and is out of the documentation. But the documentation doesn't tell something about a fallback if no files are found.
lib.files = FILES
lib.files {
references {
table = pages
fieldName = media
}
file =
begin = 0
maxItems = 1
renderObj = TEXT
renderObj {
value = URL: {file:current:publicUrl}
insertData = 1
}
}
A naive .if.isNull failed at the first attpent. Is there a possibilty to define a fallback if the FILES-Object is empty?
Mh,
try to make a second object and check there if lib.files is filled with data.
__
UNTESTED
lib.files = FILES
lib.files {
references {
table = pages
fieldName = media
}
file =
begin = 0
maxItems = 1
renderObj = TEXT
renderObj {
value = URL: {file:current:publicUrl}
insertData = 1
}
}
lib.fileFallback = COA
lib.fileFallback {
10 < lib.files
20 = TEXT
20 {
value = Do something
stdWrap.if.isFalse.cObject < lib.fileFallback.10
}
}
I am using this technique often to slide through pages for slideshow objects.
Let me know, if it is working.
You should check the TypoScript Reference stdWrap.ifEmpty.
In your case the code should look like this
lib.files {
# ....
stdWrap.ifEmpty.cObject = IMAGE
stdWrap.ifEmpty.cObject{
file = fileadmin/.../my_image.png
}
# ....
}
You can use every cObject you want.
Check out Content Objects (cObject)