typolink userFunc in TYPO3 V8 - typo3

I want to use the core linkhandler and change my link in a userFunc.
I use the linkhandler as it is described here, and it works with a single detail page:
https://usetypo3.com/linkhandler.html
The problem is:
If i change my typoscript to:
config.recordLinks {
tx_news {
typolink {
userFunc = Vendor\Name\UserFunc\TypolinkUserFunc->parseLinkHandlerTypolink
userFunc {
newsUid = TEXT
newsUid.data = field:uid
newsClass = TEXT
newsClass.data = parameters:class
defaultDetailPid = 53
}
}
}
}
it doesn't work.
I cannot address the userFunc. I'm in an extension. i use
'autoload' =>
array(
'psr-4' => array('Vendor\\Name\\' => 'Classes')
),
);
in order to load my userFunc Class.
I do not get any error message.

You must have figured it out by now, but you have to run a userFunc as USER.
10 = USER
10 {
userFunc = TYPO3\Extension\Sample->user_exampleUserFunc
}
So as a sample, your code should look something like this:
config.recordLinks {
tx_news {
typolink {
10 = USER
10 {
userFunc = Vendor\Name\UserFunc\TypolinkUserFunc->parseLinkHandlerTypolink
userFunc {
newsUid = TEXT
newsUid.data = field:uid
newsClass = TEXT
newsClass.data = parameters:class
defaultDetailPid = 53
}
}
}
}
}
As the above is just an example, it should get you started.

Related

In typo3 news typoscript, how do I set startingpoint to current page ID?

In old versions of typo3 this code worked but in latest version v11 it doesn't.The problem is that "this" value defined as "startingpoint" doesn't return current page id anymore.
lib.pageNews = USER
lib.pageNews {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
startingpoint = this
recursive = 99
templateLayout = 100
hidePagination = 0
#limit = 10
detailPid = 1075
list.paginate.itemsPerPage = 20
}
}
What is the "new" way to achieve this?
I tried to call that id in multiple ways like: TSFE:id, lib.currentPageId, TSFE:page|id, TSFE:page|uid, {TSFE:uid}, {TSFE:id}, getTSFE().id, .....
That is possible by using useStdWrap.
lib.pageNews {
settings {
useStdWrap = startingpoint
startingpoint {
data = TSFE:id
}
}
}
Source: https://github.com/georgringer/news/issues/542

TYPO3: clear cache by tag for custom content element when record in backend is changed

I have a sysfolder with records which get displayed in the frontend via a custom content element.
Now I have the problem that the frontend is not updated when a new record is added or an existing record is changed.
To clear the cache I'm using a hook in ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']['foobar'] =
\Vendor\Name\Hooks\DataHandler::class . '->clearCachePostProc';
The hook looks like this:
<?php
namespace Vendor\Name\Hooks;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class DataHandler implements SingletonInterface
{
public function clearCachePostProc(array $params): void
{
if (isset($params['table']) && $params['table'] === 'tx_foo_domain_model_bar') {
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
$cacheManager->flushCachesByTag('1642782027');
}
}
}
And the content element is implemented with FLUIDTEMPLATE and a dataprocessor:
tt_content {
foo_bar =< lib.contentElement
foo_bar {
templateName = myTemplate
stdWrap.cache {
key = tx_foo_domain_model_bar
tags = 1642782027
lifetime = default
}
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
table = tx_foo_domain_model_bar
pidInList = {$foo.storage_pid}
as = foobar
}
}
}
}
Everything seems to work but when I hit Cmd+R/Ctrl+R and reload the page or visit it again via the navigation, the page is not updated with the latest content.
I implemented the following solution.
Within the Typoscript Setup add a addPageCacheTag to your custom content element:
tt_content {
foo_bar =< lib.contentElement
foo_bar {
templateName = FooBar
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
table = tx_foo_domain_model_bar
pidInList = {$foo.storage_pid}
as = foobar
}
}
stdWrap.addPageCacheTags = foo_bar
}
}
Add the clearCacheCmd to the Page TSConfig from the storage page like:
TCEMAIN.clearCacheCmd = cacheTag:foo_bar
For testing, add this to your Fluid-Template and be sure to test with a separate browser (without BE login):
<div style="color: red;"><f:format.date format="d.m.Y - H:i:s">now</f:format.date></div>
Kudos to https://daniel-siepmann.de/posts/2019/typo3-content-caching.html
You could use the EXT:Fluid Page Cache
https://extensions.typo3.org/extension/fluid_page_cache
This EXT does all the things you need automatically.

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 with dynamic uid

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:

How set categorySelection a value of return of user funcion in Typoscript

I have a user function that return a list of categories (f.e. 20, 19) and I want to set in tt_news categorySelection as indicate the code
plugin.tt_news {
categorySelection = user_ttNewsCategoriesByUID
categoryMode = 2
}
Before of this I have the user function and works correctly
page.105 = USER
page.105 {
includeLibs = EXT:tt_news/Categorias.php
userFunc = user_ttNewsInCat
}
I am looking but I have not found something. How can I set the return of function in categorySelection
Since categorySelection is stdWrap enabled (see reference), you should be able to make use of it like this:
plugin.tt_news {
categorySelection >
categorySelection.cObject = USER
categorySelection.cObject.userFunc = user_ttNewsCategoriesByUID
categoryMode = 2
}
I found the answer and works correctly in this way
includeLibs.userCategories = EXT:tt_news/Categorias.php
temp.catuid = USER
temp.catuid.preUserFunc = user_ttNewsInCat
plugin.tt_news {
categorySelection < temp.catuid
categoryMode = 2
}