I want to call a simple PHP script with typoscript to print the results of it.
I tried this,
lib.doSomething = USER
lib.doSomething {
userFunc = fileadmin/pcoShowBlog.inc.php
}
page.20.marks.kumulierterInhalt < lib.doSomething
What is wrong in this case?
Update
also tried this:
lib.obj = USER
lib.obj.includeLibs = fileadmin/pcoShowBlog.inc.php
lib.obj.userFunc = Blog->showBlog
page.20.marks.kumulierterInhalt < lib.obj
and this:
page.10 = USER_INT
page.10 {
userFunc = In2code\MyUserFuncs\Blog->showBlog
}
page.20.marks.kumulierterInhalt = page.10.userFunc
You should not have any PHP files in fileadmin (security)!
Use an own extension and give the class and method name to the userFunc.
lib.doSomething.userFunc = Vendor\ExtensionName\UserFunc\ShowBlog->methodName
I work on TYPO3 10.4
I wanted to run function from my controller before frontend login, so I created my plugin and put it above felogin plugin.
For call function from my controller I use typoscipt like this:
lib.doSomething = USER
lib.doSomething {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = extName
vendorName = vendor
pluginName = plugin
}
In template I just put
<f:cObject typoscriptObjectPath="lib.doSomething"/>
Problem can appears with more then one function in controller, because switchableControllerActions is deprecated, I suggest this solution: https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/10.3/Deprecation-89463-SwitchableControllerActions.html
Related
I would like to load a plugin dynamically according to some data. First I tried to do it with Typoscript, but after some research I figured out, that it is not possible to change the settings of the plugin (see old forum entry).
I need to change settings.simplepoll.uid according to the passed data:
This is the Typoscript I tried:
lib.loadSimplepoll = USER
lib.loadSimplepoll {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = Simplepoll
pluginName = Polllisting
vendorName = Pixelink
switchableControllerActions {
SimplePoll {
1 = list
}
}
settings < plugin.tx_simplepoll.settings
settings {
simplepoll {
uid.current = 1
}
}
}
The call in the template looks like that:
<f:cObject typoscriptObjectPath="lib.loadSimplepoll">{newsItem.simplepoll}</f:cObject>
After figuring out, that changing the settings is not possible, I tried a viewhelper:
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class LoadSimplepollViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
/**
* #param int $uid Uid of poll
* #return string
*/
public function render($uid) {
$cObj = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
$configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$simplepollTs = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
'simplepoll',
'Polllisting'
);
$ttContentConfig = array(
'tables' => 'tt_content',
'source' => 1030,
'dontCheckPid' => 1
);
// returning this works perfectly!
// but I need to change the "settings.simplepoll.uid"
$data = $cObj->RECORDS($ttContentConfig);
$cObj->start($data, 'tx_simplepoll_domain_model_simplepoll');
$renderObjName = '<tt_content.list.20.simplepoll_polllisting';
$renderObjConf = $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['simplepoll_polllisting.'];
$renderObjConf['persistence']['storagePid'] = 394; // This does not work!
$renderObjConf['settings'] = $simplepollTs;
$renderObjConf['settings']['simplepoll']['uid'] = $uid;
return $cObj->cObjGetSingle($renderObjName, $renderObjConf);
}
}
The viehelper is called like this:
{vh:LoadSimplepoll(uid: '{newsItem.simplepoll}')}
Now I am able to change the uid of the poll with this line:
$renderObjConf['settings']['simplepoll']['uid'] = $uid;
My problem is now, that it loads the poll, but not the answers. I tracked this down to the fact, that the plugin somehow does not know the Record Storage Page anymore. The line $renderObjConf['persistence']['storagePid'] = 394; does not help.
How can I tell the plugin the Storage Pid?
Or is there another/better way to load a plugin with changing data?
Why shouldn't it be possible to modify settings.simplepoll.uid in typoscript?
because the extension simplepoll does not handle any stdWrap functionality to its typoscript settings.
Have a look into the code:
this special setting is used here:
$simplePoll = $this->simplePollRepository->findByUid($this->settings['simplepoll']['uid']);
no stdWrap, just plain usage.
compare it to ext:news:
before any settings is used it is processed. A dedicated join of typoscript settings with the settings in the plugin. And if necessary there is a stdWrap possible: here
$this->originalSettings = $originalSettings;
// Use stdWrap for given defined settings
if (isset($originalSettings['useStdWrap']) && !empty($originalSettings['useStdWrap'])) {
$typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
$typoScriptArray = $typoScriptService->convertPlainArrayToTypoScriptArray($originalSettings);
$stdWrapProperties = GeneralUtility::trimExplode(',', $originalSettings['useStdWrap'], true);
foreach ($stdWrapProperties as $key) {
if (is_array($typoScriptArray[$key . '.'])) {
$originalSettings[$key] = $this->configurationManager->getContentObject()->stdWrap(
$typoScriptArray[$key],
$typoScriptArray[$key . '.']
);
}
}
}
As you can see:
extbase does not support you with typoscript stdWrap functionality.
You (and every extension author) need to do it by hand. But that was so even before extbase.
In this way: as you can not configure your value you only can trick TYPO3 (and the plugin):
if you have a small number of uids you can have one variant for each uid
lib.loadSimplepoll123 < lib.loadSimplepoll
lib.loadSimplepoll123.settings.simplepoll.uid = 123
lib.loadSimplepoll234 < lib.loadSimplepoll
lib.loadSimplepoll234.settings.simplepoll.uid = 234
lib.loadSimplepoll345 < lib.loadSimplepoll
lib.loadSimplepoll345.settings.simplepoll.uid = 345
lib.loadSimplepoll456 < lib.loadSimplepoll
lib.loadSimplepoll456.settings.simplepoll.uid = 456
and call it like
<f:cObject typoscriptObjectPath="lib.loadSimplepoll{newsItem.simplepoll}" />
or you build a pull request implementing the stdWrap functionality and send it to the extension author.
Why shouldn't it be possible to modify settings.simplepoll.uid in typoscript?
you just need the correct construction to modify it.
For a single value you can use current, but use it properly. It is a stdWrap function which needs to be evaluated.
If there is no stdWrap evaluation by default it might work with a cObject of type TEXT
settings.simplepoll.uid.cObject = TEXT
settings.simplepoll.uid.cObject.current = 1
or to indicate a stdWrap you need to use stdWrap literally:
settings.simplepoll.uid.stdWrap.current = 1
another variant of data transfer are named parameters. Just build an associative array as data parameter and access the values individual:
fluid:
<f:cObject typoscriptObjectPath="lib.arraytest" data="{a:'abc',b:'xyz'}" >
inside text
</f:cObject>
and the typoscript:
lib.arraytest = COA
lib.arraytest {
10 = TEXT
10.field = a
10.wrap = /|/
20 = TEXT
20.field = b
20.wrap = \|\
}
which results in an output of /abc/\xyz\. Be aware: the inner text of the f:cobject tag will be lost as the data parameter has priority about inner children.
In the meantime I got the Viewhelpter to work:
Viewhelper:
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class LoadSimplepollViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
/**
* #return void
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('simplepollUid', 'int', 'Uid of simplepoll', false);
}
/**
* #return string
*/
public function render()
{
$configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');
$simplepollTs = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
'simplepoll',
'Polllisting');
$cObj = GeneralUtility::makeInstance('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
$renderObjName = '<tt_content.list.20.simplepoll_polllisting';
$renderObjConf = $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['simplepoll_polllisting.'];
$renderObjConf['settings'] = $simplepollTs;
$renderObjConf['settings']['simplepoll']['uid'] = (int)$this->arguments['simplepollUid'];
return $cObj->cObjGetSingle($renderObjName, $renderObjConf);
}
}
Call the viewhelper in the template (don't forget to register the namespace):
{vh:LoadSimplepoll(simplepollUid: '{newsItem.ipgSimplepoll}')}
That's it.
I would like to execute some typoscript commands only on page with a specific plugin on it :
page.includeCSS { }
page.includeJS { }
lib.my_bloc = COA
etc...
I move my typoscript code into the file typo3conf/ext/my_company_plugin/Configuration/TypoScript/setup.txt but it seems not to work. How to make it work ?
Furthermore, I'm not able to set a default storagepid for my module. I want all new entities to be stored in the same specific folder (uid 184 by the way) but my TS into setup.txt isn't effective and the pid in database is the page the user were on, not the 184.
#constant
module.tx_company_events.persistence.storagePid = 184
#setup
module.tx_company_events.persistence.storagePid = {$module.tx_company_events.persistence.storagePid}
If You want to add typoscript for specific page plugin then you can use typoscript condition like below.
// if get your plugin parameters then below typoscript works
[globalVar = GP:tx_extension_key|var1 > 0]
// write your typoscript
page.includeCSS { }
page.includeJS { }
lib.my_bloc = COA
[end]
// FOr specific pageId
[globalVar = TSFE:id = 10]
page.includeCSS { }
page.includeJS { }
lib.my_bloc = COA
[end]
Also For StoragePid, make sure you included TypoScript from your ext in Root template.
I want to make a link from a template to a pageType, made for iCal download:
<f:link.action pageType="730" arguments="{event: event}" target="_blank" title="bla">iCal Download</f:link.action>
In typoscript
tx_myext_icalendar = PAGE
tx_myext_icalendar {
typeNum = 730
config {
disableAllHeaderCode = 1
xhtml_cleaning = none
admPanel = 0
metaCharset = utf-8
additionalHeaders = Content-Type:text/calendar;charset=utf-8
disablePrefixComment = 1
}
10 = USER
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
vendorName = Me
extensionName = SiteMe
pluginName = Events
switchableControllerActions {
Icalevent {
1 = iCalendar
}
}
}
}
In my iCalendarAction in the IcalleventController I never receive the arguments. No matter what I type there, not by parameter, neither by $this->request->getArguments()
I guess I need to adjust the typoscript. Any help would be welcome.
Thanks for your comments. Indeed the extensionname, pluginname, action, controller were needed in the link.action.
The thing is that the config extension which holds this, uses a custom extension that defines things like custom content elements. (I did not create this, so I got confused by it). Therefore the generated link was not the same (for extensionname, pluginname, action and controller) as defined in the pagetype. By explicitly defining them in the html template (link action), any argument is now received in the ical template.
I am upgrading tt_news + mbl_newsevent to their successors tx_news + (probably) roq_newsevent.
I am still missing out on how to access roq_newsevent data in a template when integrating (trying to) it via TypoScript.
Another community member has asked the same question on TYPO3 forge https://forge.typo3.org/issues/61060 before, but no answer.
I would expect it's just extbase basics, I haven't seen a plugin that can only be used via flexform, is it?
EDIT (returns no news):
temp.newslist = USER
temp.newslist {
userFunc = tx_extbase_core_bootstrap->run
extensionName = News
pluginName = Pi1
switchableControllerActions {
News {
1 = eventList
}
}
settings < plugin.tx_news.settings
settings.startingpoint = {$pidRecords}
settings.recursive = 1
settings.detailPid = {$pidDetail}
view =< plugin.tx_news.view
}
As dokumented in api.typo3.org the content parameter of Bootstrap->run is not used.
I need a way to process exactly this content within an extbase extension.
The extension is called by:
page = PAGE
page {
stdWrap {
htmlSpecialChars = 0
postUserFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
postUserFunc {
extensionName = MyExtension
pluginName = Pi1
controller = Firstcontroller
vendorName = MyCompany
action = list
}
}
......
How can I access the (postuserfunc-)content?
I tried to use the ContentObject, but couldn't find the content anywhere.
$this->configurationManager->getContentObject()
Is there a workaround?
Cheers
Wirsing
I'm assuming you want to get at the cObject record? You're almost there:
$contentRecord = $this->configurationManager->getContentObject()->data;