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

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

Related

How to define custom default values for TYPO3's site configuration?

By creating a file /Configuration/SiteConfiguration/Overrides/sites.php in a site package, it is possible to modify default values, such as …
<?php
defined('TYPO3') or die();
$GLOBALS['SiteConfiguration']['site_language']['columns']['title']['config']['default'] = 'Deutsch';
$GLOBALS['SiteConfiguration']['site_language']['columns']['typo3Language']['config']['default'] = 'de';
..., or even add new fields to the backend form.
Is it also possible to define some default values that do not appear in the backend form but are still automatically created in a new sites.yaml files?
For example, it is about the following values:
routeEnhancers:
PageTypeSuffix:
type: PageType
map:
sitemap.xml: 1533906435
settings:
redirects:
autoUpdateSlugs: false
autoCreateRedirects: false
redirectTTL: 0
httpStatusCode: 301
This could allow TYPO3 admin users to create new pages with the previously defined settings without having to (or being allowed to) edit the yaml files directly.
Addendum:
I found out that the default values are set via the function createNewBasicSite(). Perhaps this can be extended or overwritten somehow.
It is not possible to set default values, however I suggest a different solution which is possible since TYPO3 version 10.4 (see)
You can import settings from other files, which are e.g. within your site package.
imports:
- { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" }
another:
option: true

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);
}

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.

Getting properties from AEM multifieldpanel dialog stops working when a second entry is added

I have created an AEM Dialog which prompts the user for a set of links and labels.
These links and labels are stored in a jcr node and are used to generate a menu.
To avoid having to create a custom xtype, I am using the acs-commons multifieldpanel solution, which enables me to nest children under the fieldConfig node.
This works great with only 1 Label/Link pair, but when I add a second one - the property cannot be fetched anymore, since instead of a String, it returns the String hashcode.
The property generated by the multifieldpanel in the jcr node is of type String and is filled correctly when inspecting in CRXDE. The problem occurs when I try to fetch the value from within a Sightly HTML file.
Code
Dialog:
Definitions.js:
"use strict";
use(function () {
var CONST = {
PROP_URLS: "definitions",
};
var json = granite.resource.properties[CONST.PROP_URLS];
log.error(json);
return {
urls: json
};
});
Log output
1 element in multifieldpanel
jcr node variable content
definitions: {"listText": "facebook", "listPath": "/content/en"}
log output
{"linkText":"facebook","linkPath":"/content/en"}
Multiple elements in multifieldpanel
jcr node variable content
definitions: {"listText": "facebook", "listPath": "/content/en"},{"listText": "google", "listPath": "/content/en"}
log output
[Ljava.lang.String;#7b086b97
Conclusion
Once the multifieldpanel has multiple components and stores it, when accessing the property the node returns the String hashcode instead of the value of the property.
A colleague has pointed out that I should use the MultiFieldPanelFunctions class to access the properties, but we are using HTML+Sightly+js and are trying to avoid .jsp files at all cost. In JavaScript, this function is not available. Does anyone have any idea how to solve this issue?
That is because, when there is a single item in the multifield, it returns a String, where as it returns a String[] when there is more than a single item configured.
Use the following syntax to read the property as a String array always.
var json = granite.resource.properties[CONST.PROP_URLS] || [];
Additionally, you can also use TypeHints to make sure your dialog saves the value as String[] always, be it single item or multiple items that is configured.
Don't forget that the use() in JS is compiled into Java Byte code and if you are reading Java "primitives", make sure you convert them to JS types. It's part of the Rhino subtleties.
On another note, I tend to not use the granite.* because they are not documented no where, I use the Sightly global objects instead https://docs.adobe.com/content/docs/en/aem/6-0/develop/sightly/global-objects.html
To access properties, I use properties.get("key")
Hope this help.

Typo3 eID, how to access config

I've just created an eID in Typo3. I can't figure out how to access the config data for my plugin from the Typo3 instance.
I've tried the code from the link but it doesn't want to work. I keep getting an exception "No TypoScript template found! " on the call " $TSFE->getConfigArray(); "
http://lists.typo3.org/pipermail/typo3-dev/2006-December/021392.html
Any ideas?
Thanks.
In eID mode, only a small part of the regular TYPO3 frontend is loaded. Unfortunately TypoScript is not loaded. To still access the TypoScript configuration you need manually load the components it needs to do so. Unfortunately this can be a bit of a pain in the butt. So in some cases it might be easier to just load a page containing a single plugin that doesn't contain anything else (without headers etc.).
If you do want to load the TypoScript templates yourself, you can try something like the following:
require_once(PATH_tslib.'class.tslib_fe.php');
require_once(PATH_t3lib.'class.t3lib_userauth.php' );
require_once(PATH_tslib.'class.tslib_feuserauth.php');
require_once(PATH_t3lib.'class.t3lib_cs.php');
require_once(PATH_tslib.'class.tslib_content.php') ;
require_once(PATH_t3lib.'class.t3lib_tstemplate.php');
require_once(PATH_t3lib.'class.t3lib_page.php');
$TSFEclassName = t3lib_div::makeInstanceClassName('tslib_fe');
$id = isset($HTTP_GET_VARS['id'])?$HTTP_GET_VARS['id']:0;
$GLOBALS['TSFE'] = new $TSFEclassName($TYPO3_CONF_VARS, $id, '0', 1, '','','','');
$GLOBALS['TSFE']->connectToMySQL();
$GLOBALS['TSFE']->initFEuser();
$GLOBALS['TSFE']->fetch_the_id();
$GLOBALS['TSFE']->getPageAndRootline();
$GLOBALS['TSFE']->initTemplate();
$GLOBALS['TSFE']->tmpl->getFileName_backPath = PATH_site;
$GLOBALS['TSFE']->forceTemplateParsing = 1;
$GLOBALS['TSFE']->getConfigArray();
$cObj = t3lib_div::makeInstance('tslib_cObj');
This initializes the TSFE and cObj but is also used to load and parse the TypoScript templates. You might need to make some modifications to (probably kick some things out)
The code came from one of the comments on the following blog post: http://sebastiaandejonge.com/blog/articles/2010/september/21/bringing-ajax-to-your-frontend-plugins/
Good luck!