Problem with setting a Plugin as a new CType - plugins

In order to have the full power of the TCA's showitem for configuring the back-end form for a plugin, I define it as a new CType, instead of a new list_type of the list CType.
I do this by registering it with addPlugin instead of the default method outlined in the official extension guide, using registerPlugin. In ext_tables.php:
TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
[
// Label.
'LLL:EXT:my_ext/Resources/Private/Language/locallang.xlf:pi1.name',
// Plugin key.
'myext_pi1',
// Icon.
'pi1'],
'CType',
'my_ext'
);
Then I can just use, in Configuration/TCA/Overrides/tt_content.php:
$GLOBALS['TCA']['tt_content']['types']['myext_pi1'] = [
'showitem' => " ... "]
to configure it's back-end form display as I want.
But now, after successfully adding the plugin on a page from the back-end, when I try to view it from the front-end, I get the error:
ERROR: Content Element with uid "284" and type "myext_pi1" has no rendering definition!
It's not doing the usual: loading the controller action assigned to the plugin in ext_localconf.php with ExtensionUtility::configurePlugin (in ext_localconf.php).
Does anybody know what could I do to make it work?

The point in this case is, that the element does not just "act as if it were a custom content element", but it actually IS a custom content element.
So you will have to provide at least a basic configuration via
tt_content.myext_pi1
If you registered a plugin properly it might be enough to just copy the plugin configuration to the tt_content entry
tt_content.myext_pi1 < plugin.myext_pi1

Related

Change tt_content's TCA for a subtype?

Is it possible, for a specific plugin (e.g. newspage_pi1), to configure its TCA, i.e. its back-end form display? Just for that specific plugin, because when changing tt_content's TCA for the list type (i.e. plugins) like this:
$GLOBALS['TCA']['tt_content']['types']["list"] = [
'showitem' => "
(tabs..palettes..columns..etc...)"];
It changes it for all plugins, and I only want to change it for the newspage_pi1 list_type.
Yes, I know that I can use 'subtype_value_field' => 'list_type' and then subtypes_excludelist and subtypes_addlist to add or remove fields for specific plugins. But this is not nearly as powerful as setting showitem directly, since it allows to define new tabs, palettes, position the fields how you want to, etc.
I also know about FlexForms, but these only control the Plugin Options field, not all the other ones.
Is there a way to change the showitem for a specific plugin?
Thanks a lot in advance!
Frankly said, what you actually want is not a subtype but another type, since it needs to change fields other than the usual plugin / pi_flexform configurations.
So instead of adding that subtype as a plugin you should add it as another CType to get the full power of showitem.
Basically, this is how we add any kind of plugin too, since it makes more sense to have real database fields at hand instead of faking them with XML data structures.
As mentioned in the description here https://api.typo3.org/master/class_t_y_p_o3_1_1_c_m_s_1_1_core_1_1_utility_1_1_extension_management_utility.html#ab4f6c66990aca246eac5390a76f0c83c
... - or more generally use this function to add an entry to any
selectorbox/radio-button set in the FormEngine

TYPO3 automatic page creation based on TCA record

I've special requirement on my project and I need help. I am using TYPO3 8.7.8. I've a custom extension to render tag labels in frontend. We can add the tags as TCA record in backend storage folder. In the TCA record, you can tag name. My requirement is, when I save the TCA record I want to create a TYPO3 page automatically with the same name as tag in a specific position. Everytime when I add a TCA record, I need to create corresponding page automatically. Is this possible? I can use hook while saving TCA. But is there any function to create pages automatically?
After automatic page creation, I want to insert a plugin content element in that page with a specific flexform value automatically. I know this is a strange requirement, but I would like to know if it is possible or not.
Exactly, you'd trigger a hook on saving and then as next step you can use the data handler to generate the new page (and possible content).
To create the page and content, use something like the following data structure
$data = [
'pages' => [
'NEW_1' => [
'pid' => 456,
'title' => 'Title for page 1',
],
],
'tt_content' => [
'NEW_123' => [
'pid' => 'NEW_1',
'header' => 'My content element',
],
],
];
Then call the datahandler with that structure:
$tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
$tce->stripslashes_values = 0;
$tce->start($data, []);
$tce->process_datamap();
Find out more in the docs at
https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Typo3CoreEngine/Database/Index.html#data-array
and
https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Typo3CoreEngine/UsingDataHandler/Index.html
Are you sure you need additional pages?
In general your problem sounds like you need one page where the plugin is inserted and where the plugin in dependency of an url-parameter (which can be converted with realurl into a path segment) shows only information depending of the selected record (tag).
If no tag is selected you can output a list with all available tags as a menu to navigate to all possible tags.
With a little effort (less than writing a hook like intended) you can add all tags to your menu.

How to enable header_position in TYPO3 7.6

In versions prior to TYPO3 7.6 you could select a position for your header within your content element (left, middle, right as far as I remember).
The field which has been used for storing that information in tt_content header_position is still available.
However, it will not appear in the backend.
I'm also using fluid_styled_content for rendering my content, and the Header partial doesn't contain any reference to the position, but only to the layout field.
My question is: How can I reenable that field and use it to position my headers?
You have to build a quick extension of yours which can reenable the field. You need to create folders and a file like following:
your_ext/Configuration/TCA/Overrides/tt_content.php
the contents of that file are:
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
ExtensionManagementUtility::addTCAcolumns('tt_content',[
'header_position' => [
'exclude' => 1,
'label' => 'LLL:EXT:your_ext/Resources/Private/Language/locallang_db.xlf:tt_content.header_position',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['LLL:EXT:your_ext/Resources/Private/Language/locallang_db.xlf:tt_content.header_position.left', 'left'],
['LLL:EXT:your_ext/Resources/Private/Language/locallang_db.xlf:tt_content.header_position.right', 'right'],
['LLL:EXT:your_ext/Resources/Private/Language/locallang_db.xlf:tt_content.header_position.center', 'center']
]
]
]
]);
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'header', '--linebreak--,header_position', 'after:header_layout');
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'headers', '--linebreak--,header_position', 'after:header_layout');
Now the field should be back in the backend, because you've added it to the TCA via addTCAColumns to the tt_content configuration and added it via addFieldsToPalette to the header and headers palettes of tt_content, which are used by the types textmedia and header.
You can find out more about this by using the Configuration module in the TYPO3 backend. You can see it, when you are logged in as admin. Also a good place to look and learn about the TCA is the TCA reference: https://docs.typo3.org/typo3cms/TCAReference/
Now you need to alter the fluid_styled_content templates. You need to create template overrides for the header partial of fluid_styled_content.
First create a folder: your_ext/Configuration/TypoScript and add a setup.txt and a constants.txt file.
In setup.txt add the following lines:
lib.fluidContent{
templateRootPaths{
10 = {$plugin.your_ext.view.fluid_styled_content.templateRootPath}
}
partialRootPaths{
10 = {$plugin.your_ext.view.fluid_styled_content.partialRootPath}
}
layoutRootPaths{
10 = {$plugin.your_ext.view.fluid_styled_content.layoutRootPath}
}
}
In constants.txt do:
plugin.your_ext{
view{
fluid_styled_content{
templateRootPath = EXT:your_ext/Resources/Private/FluidStyledContent/Templates/
partialRootPath = EXT:your_ext/Resources/Private/FluidStyledContent/Partials/
layoutRootPath = EXT:your_ext/Resources/Private/FluidStyledContent/Layouts/
}
}
}
To enable your TypoScript, you need to add a ext_tables.php in your your_ext folder and give it the following one-liner:
TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY,'Configuration/TypoScript', 'Your Ext Template');
You need to include your static TypoScript to your page via the Template module to enable the change to fluid_styled_content
Now you can copy the templates you need from
typo3/sysext/fluid_styled_content/Resources/Private/Templates
typo3/sysext/fluid_styled_content/Resources/Private/Partials
typo3/sysext/fluid_styled_content/Resources/Private/Layouts
into your extensions folders you need to create:
your_ext/Resources/Private/FluidStyledContent/Templates
your_ext/Resources/Private/FluidStyledContent/Partials
your_ext/Resources/Private/FluidStyledContent/Layouts
Now you can alter the templates. For your header_position field, you probably just need to copy
typo3/sysext/fluid_styled_content/Resources/Private/Partials/Heaeder.html
to
your_ext/Resources/Private/FluidStyledContent/Partials/Header.html
and add your selected value as {data.header_position} to a div class and style that.
Keep in mind you do not need to copy all of the templates, because with the TypoScript you just defined another location for fluid to search for templates and take them, if they are available. If not, fluid will walk back the chain and take the templates that are defined at position 9 and lower. You can look into the TypoScript Object Browser by the Template module and look into the TypoScript variable lib.FluidContent to see, if your TypoScript include has worked.
Hope this helped a bit ;)
The database field header_position is only included in the TYPO3 core extension css_styled_content. If you don't have that extension installed the field in the database is probably there because it was installed sometime before.
It is not advised to install css_styled_content and fluid_styled_content installed in parallel as some options can conflict.
If you want to use fluid_styled_content and have the header_position field available the best way to go would be to create a very small TYPO3 extension yourself that includes the necessary SQL definition for the column header_position, the appropriate TCA configuration for that column and a few bits of TypoScript to extend/override the „Partial” paths of fluid_styled_content.

Set extbase Controller Action in plugin

I have set up an extbase extension in a TYPO3 4.5 site with the extension builder, containing just the default listAction in the controller.
Now I would like to add a new Action, and it doesn't work.
I don't need (aka. can't get to work) a flexform to choose the controller action.
As there's a field "Plugin mode", I thought I could just manually enter the action here:
And extend the plugin configuration as such in ext_localconf.php:
Tx_Extbase_Utility_Extension::configurePlugin(
$_EXTKEY,
'Pluginname',
array(
'Controllername' => 'list,listfeatured',
),
);
Also, in the controller, I have added a new action.
/**
* action listfeatured
*
* #return void
*/
public function listfeaturedAction() {
// do something
}
But, alas, the action is not called at all.
Did I interpret the field "plugin mode" wrong?
Did I miss something?
Alternatively: Can I set the action for a "backend" plugin via TS as well?
You need to use FlexForm correctly to set list of switchable actions.
Other option is creating another plugin for which default action is listfeatured.
If you will decide to use single plugin only just you need to show/describe us what did you try in FlexForm (probably new question)
Edit: As you showed us yourself in your question it's you deciding which Controller and action are default for given plugin, so to add new plugin which will use existing controller, just add this to your ext_localconf.php
Tx_Extbase_Utility_Extension::configurePlugin(
$_EXTKEY,
'MyFeaturedPlugin',
array(
'Controllername' => 'listfeatured',
),
);
you may also need to registerPlugin in your ext_tables.php if you want to be able to use it in BE (can be ommited if ie. plugin should be placed only with TS). You will do this with: Tx_Extbase_Utility_Plugin::registerPlugin
Besides FlexForm there is a further way of reading the field Plugin Mode in the plugin with PHP.
Right now, I'm working on a plugin and wish to distinguish between modi. Some modus B should be set from the very beginning of the request, even better it should not be sent over HTTP but read from the data model.
So I set the text 'myModusB` in the field "Plugin Mode", and in the plugin I inspect:
exit (print_r($this, true));
Then I find
[cObj] => TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer Object
...
[data] => Array
(
...
[select_key] => myModusB
...
So in the plugin by writing
$modus = $this->cObj->data["select_key"];
I'll get the text and can process it.
This is tested for version 6.1.3.

In CQ How to disable any field in child page properties dialog?

I have added a new selection type field "Theme" in page properties>Basic.
Now if I add a new page using the same template in WCM, there also I
am getting the option "Theme", which is quite obvious.
Is there any way by which I can hide the field in child page?
P.S this is happening because I am using the same template for the child page.
You can't use the same template and have the page property dialogs be different.
What you can do is overload the dialog
create a new template and corresponding resourceType component that
inherit from your current.
copy the dialog, or tab that you want to be different from the lowest parent of the component. Make sure the dialog is the only node under the component.
Make the changes you want to the dialog.
You would then have to include code in the page jsp to get the parent page property something like:
// if the parent page is always a certain level below the root you can use
// currentPage.getAbsoluteParent(3); to get the third page down from the top
// of the current path tree.
Page parentPage = currentPage.getParent();
ValueMap parentPageProperties;
if (parentPage != null) {
parentPageProperties = parentPage.getProperties();
}
// This tries to get the property 'theme' from the current page. If that fails
// then it tries to get the property from the parent page. If that fails it
// defaults to blank.
theme = properties.get("theme", parentPageProperties.get("theme", ""));
A quick solution would also be to create a second set of template / page component. Let's assume you've got template A, that uses page component B as resource type:
Create template X and play with allowedParents allowedChildren and allowedPaths properties so that the two are exclusive (actual solution depends on your content architecture)
Give X same title as A
Create page component Y that extends B, and defines it's own dialog
Make Y's dialog re-use any tabs from B using xtype=cqinclude (see foundation page's dialog for reference)