How to pass argument to controller action with FluidTypo3? - typo3

How do I have to pass an argument to a flux-enabled controller so it is recognized by the controller action?
I created an extension using builder and added the following method to the ContentController.
/**
* #param string $var
*/
public function exampleAction($var = null) {
var_dump($var);
die;
}
But no matter how I add the parameter to the URL, I only get "null" as a result.
Extensions directory is "test" and so is $_EXTKEY. The builder put "Mac.Test" into ext_tables.php for calls to registerProviderExtensionKey(). So in the URL I tried these parameters:
http://host/index.php?id=1&tx_test_content[var]=abc
http://host/index.php?id=1&tx_test[var]=abc
http://host/index.php?id=1&tx_mactest_content[var]=abc
http://host/index.php?id=1&tx_mactest[var]=abc
http://host/index.php?id=1&var=abc
and some others. But to no avail.
I tried with the f:link.action ViewHelper, resulting in
http://localhost/test2/index.php?id=1&no_cache=1&tx_test_content[member]=foo&tx_test_content[action]=example&tx_test_content[controller]=Content
Also $this->request->getArguments() only returns an empty array, so there must be something seriously wrong.
Used versions:
PHP 5.6.11
TYPO3 6.2.21
vhs 2.4.0
flux 7.2.3
fluidpages 3.3.1
fluidcontent 4.3.3
fluidcontent_core 1.3.0
builder 1.0.0
Nothing else installed (fresh system just for testing this behaviour).

Using fluid link, you can pass para like
<f:link.action action="example" controller="controllerName" arguments="{var:'abc'}">Go</f:link.action>
It'll create link like:
http://host/index.php?id=1&tx_[extension_key]_[fe_plugin_key][var]=abc
Now, how to get para from url in extBase
$arguments = $this->request->getArguments(); // OR
$var = $this->request->getArgument('var');
Useful links:
Fluid
extBase Accessing GET/POST vars

Related

TYPO3 extbase: Simple readable GET parameters

GET and POST parameters in custom extbase controllers need to be prefixed with the plugin signature to be injected automatically:
<?php
namespace Vendor\Example\Controller;
class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
public function resultsAction($q = null)
{
//...
}
}
Search term $q is only filled automatically if it is passed as ?tx_example_search[q]=foo.
Is there a way declare that the readable version ?q=foo is also fine, and that this should be injected by extbase as well?
(I know that this breaks when multiple plugins on the same page use that parameter, but that's no problem here.)
(The parameter mapping seems already done when ActionController::processRequest() is called, so it must be done earlier.)
You could use the Extbase Plugin enhancer within the routing configuration.
See here: TYPO3 Advanced routing configuration Docs
TYPO3 would then transform the EXTbase URLs into an readable version.
Example:
without the routeEnhancer: yourdomain.com/?tx_example_search[q]=foo
with the routeEnhancer: yourdomain.com/foo
Tipp: You have to define all GET Params otherwise TYPO3 will show the cHash Param.
You can use the method \TYPO3\CMS\Core\Utility\GeneralUtility::_GP($var) in order to retrieve parameters from global variables GET/POST.
Or also \TYPO3\CMS\Core\Utility\GeneralUtility::_GET($var) or \TYPO3\CMS\Core\Utility\GeneralUtility::_POST($var).
Take care of security, those parameters are not sanitized !
If you really want to add the parameter to the action, you have to create an initializeAction() and set the parameter, something like this I guess :
public function initializeResultsAction() {
$myVar = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('q');
$this->request->setArgument('q', $myVar);
}

TYPO3 9.5.4 (with slug) ignores get parameter 'type'

I want to switch the type of my typo3 website e.g. for xml or json output, but the system ignores the get parameter type. I don't know what I'm doing wrong or if there is a bug.
typoscript example
testtype = PAGE
testtype.typeNum = 13
testtype.10 = TEXT
testtype.10.value = test
testtype.config.disableAllHeaderCode = 1
my site config
https://pastebin.com/UsdZGq7N
You make use of the PageType routeEnhancer, when that is active you have to map all the page-types you use. Otherwise it gets stripped from the url.
Also, the PageType routeEnhancer should be the last enhancer you configure, as it modifies existing route variants:
https://github.com/TYPO3/TYPO3.CMS/blob/master/typo3/sysext/core/Classes/Routing/Enhancer/PageTypeDecorator.php#L25

Fluid standalone view in BE context

Given you are in a BE or CLI context (e.g. sending emails via extbase command controller task), the following worked up to 7 LTS for rendering a fluid standalone view:
$view = $this->objectManager->get(StandaloneView::class);
$view->setTemplatePathAndFilename('/Absolute/Path/To/Template.html');
$view->setFormat('html');
$view->getRequest()->setControllerExtensionName('Myextensionname');
return trim($view->render());
However, in 8 LTS, this throws the following exception:
Tried resolving a template file for controller action "Standard->index" in format ".html", but none of the paths contained the expected template fileā€¦ No paths configured.
As suggested in the wiki page at https://wiki.typo3.org/How_to_use_the_Fluid_Standalone_view_to_render_template_based_emails#Usage_in_TYPO3_8.7, I tried setting layout and partial root paths for the view:
$view->setLayoutRootPaths(['EXT:Myextensionname/Resources/Private/Layouts/']);
$view->setPartialRootPaths(['EXT:Myextensionname/Resources/Private/Partials/']);
However, this won't do the trick.
Digging a bit deeper, I could imagine that one would have to set the controller and action name, e.g. by setting the controller context, but that does not seem to be a solid solution as multiple other class instances are tied to it.
What is the correct way to render fluid standalone views in 8 LTS?
Here an example from our current webproject where we want to show a simple note in backend context based on a FLUID HTML in TYPO3 8.7
protected function renderMarkup(): string
{
$standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
$standaloneView->getRequest()->setControllerExtensionName('in2template');
$templatePathAndFile = 'EXT:in2template/Resources/Private/Templates/Tca/ToolbarNoteEmptyFields.html';
$standaloneView->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFile));
$standaloneView->assign('toolbar', 'toolbarstuff');
return $standaloneView->render();
}
StandaloneView likes to receive all template paths (partial, template and layout root paths) so if you don't already provide all of them, you should do so. The reason being that the naming "Standalone" refers to the view being tied neither to a specific MVC action nor a specific extension context.
That said, if you use 8.7.5 there's a chance you are hit by a regression that is going to be solved by https://review.typo3.org/#/c/53917/ so it might be worth checking that out before you do a major refactoring. Technically the StandaloneView can be operated like a TemplateView with extension context, it's just not officially supported behavior and TYPO3 may not consistently apply all of the context you expect.
In my 8.7 extension I use the following code to get the StandaloneView:
$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
/** #var StandaloneView $emailView */
$emailView = $this->objectManager->get(StandaloneView::class);
$emailView->getRequest()->setControllerExtensionName($controllerExtensionName);
$emailView->getRequest()->setPluginName($pluginName);
$emailView->getRequest()->setControllerName($controllerName);
$emailView->setTemplateRootPaths($extbaseFrameworkConfiguration['view']['templateRootPaths']);
$emailView->setLayoutRootPaths($extbaseFrameworkConfiguration['view']['layoutRootPaths']);
$emailView->setPartialRootPaths($extbaseFrameworkConfiguration['view']['partialRootPaths']);
$emailView->setTemplate('Email/' . ucfirst($templateName));
$emailView->assignMultiple($variables);
$emailBody = $emailView->render();
In my function I gave the $controllerExtensionName, $pluginName and $controllerName as parameter with default values, so that other controllers/plugins can use this function, too.

Where should I create a template for a json view in CakePHP 3?

I am using CakePHP 3.1 and trying to render the json index response for User model. I followed the CakePHP manual page and created index.ctp under the directory src/Template/Users/json/, but the file does not get hooked by the controller. I also tried src/View/Users, which also did not work. Should I specify a file to render or something else? In src/Controller/UsersController.php, I have index() method with
$users = $this->paginate('Users');
$this->set(compact('users'));
Check your AppController.php. Since version 3.1.0 this sets the _serialize to true by default. Therefore the template files are all ignored.
public function beforeRender(Event $event)
{
if (!array_key_exists('_serialize', $this->viewVars) &&
in_array($this->response->type(), ['application/json', 'application/xml'])
) {
$this->set('_serialize', true);
}
}
You need to remove that code from beforeRender.

Zend Framework unknown module is interpreted as default module

i wanted to support multilingual structure for my work i used the following lines
$controller=Zend_Controller_Front::getInstance();
$router=$controller->getRouter();
$languageRouter=new Zend_Controller_Router_Route(":lang/:module/:controller/:action", array("lang"=>"en","module"=>"default","controller"=>"index","action"=>"index"),
array("lang"=>"[a-zA-Z]{2}"));
$router->addRoute("default",$languageRouter);
it works fine http://localhost/zend/public/en set the lang param to en and call default module
but the problem is that when i use url like this http://localhost/zend/public/en/anything
where anything isn't module it still show the default module how to prevent that???
after the answer of takeshin i added this function to the bootstarp file and now it works as i want it
protected function _initRoutes()
{
$routeLang=new Zend_Controller_Router_Route(':lang',array('lang'=>'en'),array('lang'=>'[a-z]{2}'));
$front = Zend_Controller_Front::getInstance() /*$this->getResource('frontcontroller')*/;
$router = $front->getRouter();
$routeDefault=new Zend_Controller_Router_Route_Module(array(),$front->getDispatcher(),$front->getRequest());
$routeLangDefault=$routeLang->chain($routeDefault);
$router->addRoute('default',$routeLangDefault);
$router->addRoute('lang',$routeLang);
}
It looks like you have overwritten default module defined in Zend Application by your custom one.
You should chain the routes instead.
The settings you are using means module will 'default' to default , if you didn't it would throw a route not found error - which should throw to appropriate error controller
I'm not sure if I unterstood this correctly, but it looks like it works fine, as it should. If you try to call non existing module, Zend Framework automatically "redirects" to the default module.