I have the following problem and I'm sure some of you will mark this question as duplicate but I couldn't find a specific answer for my problem.
I have an extension and I want to add images / pdf's etc. using the FAL.
According to tutorials I have to config the TCA. Well, the docs are sh.. about that point and the tutorials are based on the knowledge of TCA.
I also have to use some TypoScript, which I haven't used to this point.
Ok, as far as I got here's my question:
Where do I edit the TCA?
I have a file named ext_tables where I can see $GLOBALS['TCA'].
I also have a directory TCA with some files in it (only filled with $GLOBALES['TCA'].
And after that, how do I access these datas? I need to build a tree in the inside of a modal (pop-up is also possible)
I know these questions sound horribly easy but I couldn't find a tutorial which could explain anything at all.
I appreciate all help :)
Thanks a lot.
Your question is king of vague:
What exactly did you try so far?
Which files did you change?
Do you need the files inside your FLUIDTEMPLATE, inside your extbase controller or somewhere else?
Steps to add FAL fields to your extension
Extend the database (typo3conf/ext/yourExtFolder/ext_tables.sql):
CREATE TABLE your_database_table (
your_fal_field int(11) unsigned DEFAULT '0' NOT NULL
)
Extend the TCA:
If you extend an existing table from another extension you have the extend the TCA inside typo3conf/ext/yourExtFolder/Configuration/TCA/Overrides/your_database_table.php
Example (extend tt_content):
$newColumn = [
'field_name' => [
'image' => [
'label' => 'Image',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('image', [
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference',
],
'minitems' => 0,
'maxitems' => 1,
], $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']),
],
],
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', $newColumn);
If you add the field to your own extension your have to extend typo3conf/ext/yourExtFolder/Configuration/TCA/your_database_table.php.
Example (from TYPO3 core be_users TCA - shortened version):
return [
'ctrl' => [
'label' => 'username',
'descriptionColumn' => 'description',
],
'columns' => [
'username' => [
'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_tca.xlf:be_users.username',
'config' => [
'type' => 'input',
'size' => 20,
'max' => 50,
'eval' => 'nospace,trim,lower,unique,required',
'autocomplete' => false,
]
],
'avatar' => [
'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_tca.xlf:be_users.avatar',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'avatar',
['maxitems' => 1],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
)
],
],
// Removed more `columns`, `types` and `palettes` config
];
The important part is the definition of avatar which uses the getFileFieldTCAConfig function.
Extend your extbase model (typo3conf/ext/yourExtFolder/Classes/Domain/Model/YourClass.php)
Simplified snippet from keinerweiss.de:
class YourClass extends TheModelYouWantToExtend or \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
// ...
/**
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $yourField;
/**
* Returns the image
*
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $image
*/
public function getYourField() {
return $this->yourField;
}
/**
* Sets the image
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $image
* #return void
*/
public function setYourField($image) {
$this->yourField = $yourField;
}
}
Use your images in Fluid (From t3-developer.com):
<f:for each="{mymodel.mypictures}" as="picture">
<f:image src="{mypicture.image.uid}" alt="" treatIdAsReference="TRUE" />
</f:for>
More links (english):
https://gist.github.com/maddy2101/5668835
http://blog.scwebs.in/typo3/typo3-fal-file-abstraction-layer-in-extbasefluid-extension
More links(german):
http://keinerweiss.de/755-typo3-fal-in-einer-eigenen-extbasefluid-extension-einsetzen.html
http://t3-developer.com/ext-programmierung/techniken-in-extensions/fal-in-typo3-extensions-verwenden/
http://t3g.at/extbase-bilder-fal-in-extension-integrieren/
Related
We are using the Mask extension for some of our content Elements. (It basically adds dynamic CTypes and additional columns in the tt_content).
Next we have our custom extension whose entities should have a relation to an instance of a Mask module. Which works. The only problem is, that the labels of the inline element aren't showing up.
If we add the same Mask module as normal page content, the labels are showing up just fine.
Domain Model of our ext:
/**
* Returns the intro
*
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\MASK\Mask\Domain\Model\Content> $intro
*/
public function getIntro()
{
return $this->intro;
}
TCA
'intro' => [
'exclude' => 0,
'label' => 'Intro zentriert',
'config' => [
'type' => 'inline',
'foreign_table' => 'tt_content',
'foreign_field' => 'tx_zeppelinregions_content_elements',
'foreign_label' => 'tx_mask_teasergalleryheadline',
'foreign_table_field' => 'tx_zeppelinregions_content_elements_type',
'maxitems' => 1,
'foreign_match_fields' => [
'ctype' => 'mask_introzentriert',
],
'overrideChildTca' => [
'columns' => [
'CType' => [
'config' => [
'default' => 'mask_introzentriert',
'readOnly' => 1,
],
],
],
],
]
],
Missing labels in inline element:
(Note: the default tt_content field labels are showing)
Labels showing when adding an element of the same type as normal page content:
How can I restrict allowedExtention just for $GLOBALS['TCA']['pages']['columns']['media']? But not using $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] as it will add restriction for all FAL fields.
I found class
class ImageManipulationElement extends AbstractFormElement
{
/**
* Default element configuration
*
* #var array
*/
protected static $defaultConfig = [
'file_field' => 'uid_local',
'allowedExtensions' => null, // default: $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
Looks like should be something like:
$GLOBALS['TCA']['pages']['columns']['media']['config']['overrideChildTca']['allowedExtensions'] = 'jpg, jpeg';
Hard way will drope all usefull things for this field.
$GLOBALS['TCA']['pages']['columns']['media'] = [
'exclude' => true,
'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.media',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'media',
[], 'jpg, jpeg'
)
];
So not is our way. I need just some override like
$GLOBALS['TCA']['pages']['columns']['media']['config']['overrideChildTca']['columns']...['allowedExtention'] = 'jpg, jpeg';
Who know knows how to do this?
After small searching I found this example:
$allowExtensions = 'jpg,jpeg';
$GLOBALS['TCA']['pages']['columns']['media']['config']['filter'][0]['parameters']['allowedFileExtensions'] = '$allowExtensions;
$GLOBALS['TCA']['pages']['columns']['media']['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed']= $allowExtensions;
added to typo3conf/ext/myext/Configuration/TCA/Overrides/pages.php
Related to How to add custom wizards in typo3 7 TCA? how can costum wizards in TYPO3 9 be implemented? I've added my entry to the Routes.php
return [
'tx_csseo_preview' => [
'path' => '/wizard/tx_csseo/preview',
'target' => \Clickstorm\CsSeo\UserFunc\PreviewWizard::class . '::render'
],
'tx_csseo_permalink' => [
'path' => '/wizard/tx_csseo/permalink',
'target' => \Clickstorm\CsSeo\UserFunc\PermalinkWizard::class . '::render'
]
];
How can I add them now to my TCA field?
'tx_csseo_title' => [
'label' => 'LLL:EXT:cs_seo/Resources/Private/Language/locallang_db.xlf:pages.tx_csseo_title',
'exclude' => 1,
'config' => [
'type' => 'input',
'max' => $extConf['maxTitle'],
'eval' => 'trim',
'fieldWizard' => [
'tx_csseo_preview' => [
'disabled' => false,
]
]
]
],
This does not work. What do I miss? Thanks in advance.
Related to your kind of wizard the registration-process is different and extensive explained here. You can leave the entries in Routes.php away (perhaps even the whole file if nothing else is inside).
Registration is done in ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1485351217] = [
'nodeName' => 'importDataControl',
'priority' => 30,
'class' => \T3G\Something\FormEngine\FieldControl\ImportDataControl::class
];
Then reference the new wizard in TCA:
'somefield' => [
'label' => $langFile . ':pages.somefield',
'config' => [
'type' => 'input',
'eval' => 'int, unique',
'fieldControl' => [
'importControl' => [
'renderType' => 'importDataControl'
]
]
]
],
Then finally the class with the "magic"
declare(strict_types=1);
namespace T3G\Something\FormEngine\FieldControl;
use TYPO3\CMS\Backend\Form\AbstractNode;
class ImportDataControl extends AbstractNode
{
public function render()
{
$result = [
'iconIdentifier' => 'import-data',
'title' => $GLOBALS['LANG']->sL('LLL:EXT:something/Resources/Private/Language/locallang_db.xlf:pages.importData'),
'linkAttributes' => [
'class' => 'importData ',
'data-id' => $this->data['databaseRow']['somefield']
],
'requireJsModules' => ['TYPO3/CMS/Something/ImportData'],
];
return $result;
}
}
In the linked example there is still an Ajax Route with corresponding files, including a special defined route, but that's not required to get the basic wizard shown.
Concerning the registration in ext_localconf.php there is above the number 1485351217 as array-key shown. For an own registered node just calculate once the current time as unix-timestamp and enter that instead. So it's unique and can't be mistaken with other definitions of any registered nodes.
In contrast to the linked example I used slightly different descriptions, so I call the process in ext_localconf.php registering, and the inclusion in TCA referencing. Perhaps this small difference makes it a bit more clear.
Icons
Concerning Icons there is still a difference to earlier TYPO3 versions, they have to be registered now too and in TCA they are only referenced too by the registered name. Here in the TCA-file is no icon referenced but the class below makes usage of it. Here is an example how an icon has to be registered in ext_tables.php:
$systemIconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
$systemIconRegistry->registerIcon(
'imagemapwizard_link_edit',
\TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider::class,
[
'source' => 'EXT:imagemap_wizard/Resources/Public/Icons/link_edit.png'
]
);
The new icon registry is implemented starting with TYPO3 version 7.5
Don't forget the configuration in YourExtension/Configuration/Backend/AjaxRoutes.php. See the documentation
I've been searching for quite a while but couldn't find what I was looking for.
I've created two custom content-elements: parallax_content and bg_image.
In the backend for the time being I have the fields of a standard textmedia-element the code for which is as follows (from tt_content):
array('showitem' => '
--palette--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.general;
general,
--palette--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.header;
header,
rowDescription,
bodytext;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:bodytext_formlabel,
--div--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.media,
assets,
--palette--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.imagelinks;
imagelinks,
--div--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
layout;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:layout_formlabel,
--palette--;
LLL:EXT:fluid_styled_content/Resources/Private/Language/Database.xlf:tt_content.palette.mediaAdjustments;mediaAdjustments,
--palette--;
LLL:EXT:fluid_styled_content/Resources/Private/Language/Database.xlf:tt_content.palette.gallerySettings;
gallerySettings,
--palette--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.appearanceLinks;appearanceLinks,
--div--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access,
hidden;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:field.default.hidden,
--palette--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:palette.access;
access,
--div--;
LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.extended,
--div--;
LLL:EXT:lang/locallang_tca.xlf:sys_category.tabs.category,
categories',
'columnsOverrides' => array(
'bodytext' => array(
'defaultExtras' => 'richtext:rte_transform[mode=ts_css]'
)
)
)
For my element parallax_content I would need the following fields:
Header
a checkbox "insert Logo"
a bodytext
an image selecting field
For image_bg I would need:
an image selecting field
a dropdown list with 2 items
But I'm struggling with understanding the code and how I would neet to adapt it so it would work. I've looked at the documentation but it doesn't really answer my question as it only shows one example of code with some lines but no explanation. I couldn't find the other documentation again where I gained just as "much" information as in the one linked above. I do understand some parts, for example the palette.header creates the whole header palette with header, header-link, alignment, date etc.
So my questions are:
Can someone explain to me how the code above works exaclty? Where does one element start and where does it end? what do "--palette--" and "--div--" do? how are the tabs created (e.g. general, media etc)? Is it possible to create my fields as listed above with these palettes? Can I create my own palette? If yes how? Or is there maybe a typoscript I can use/make to create my custom fields? Or would I need to create an extension for each of these elements? If possible I'd like to avoid this.
Yes, it's quite a lot of questions, I'm a novice in TYPO3 and not only trying to work with TYPO3 but also understand it as far as possible (at least for the things I need). My utmost priority is to understand the code above, but any pointers, explanations, help or even links to documentations (which I might not have seen so far) which could lead to a solution for my request I would greatly appreciate. Thanks in advance!
in my current project I added a parallax effect to the textmedia element in the tt_content.
First I override the tt_content TCA:
'background_media' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:extension/Resources/Private/Language/locallang.xml:background_media',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'background_media',
array(
'minitems' => 0,
'maxitems' => 1,
'appearance' => array(
'createNewRelationLinkTitle' => 'LLL:EXT:extension/Resources/Private/Language/locallang.xml:add_media',
'showAllLocalizationLink' => 1,
),
'foreign_match_fields' => array(
'fieldname' => 'background_media',
'tablenames' => 'tt_content',
'table_local' => 'sys_file',
),
// custom configuration for displaying fields in the overlay/reference table
// to use the newsPalette and imageoverlayPalette instead of the basicoverlayPalette
'foreign_types' => array(
\TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => array(
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette,
--palette--;;imageoverlayPalette,
--palette--;;filePalette'
),
)
),
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
)
),
'effects' => [
'exclude' => true,
'label' => 'LLL:EXT:extension/Resources/Private/Language/locallang.xml:effects',
'config' => [
'type' => 'select',
'itemsProcFunc' => 'VENDOR\Extension\UserFunction\ProviderField->createEffectItems',
'renderType' => 'selectCheckBox',
'multiple' => true,
'minitems' => 0,
'maxitems' => 999,
'items' => []
]
],...
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', $additionalColumns);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'background_media,effects', 'textmedia', 'after:layout');
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'image_classes,text_classes', 'textmedia', 'after:layout');
Now I have 2 additional fields:
- Background Image (FAL)
- Selct Box (UserFunc) for own styles
My UserFunc (VENDOR\Extension\UserFunction\ProviderField->createEffectItems)
/**
* #param ConfigurationService $configurationService
* #return void
*/
public function injectConfigurationService(ConfigurationService $configurationService) {
$this->configurationService = $configurationService;
}
public function createEffectItems($config) {
$settings = $this->configurationService->getSettingsForExtensionName('extension');
$classNames = json_decode($settings['container']['effects'],true);
if (!is_array($classNames)) return $config;
$optionList = array();
foreach ($classNames as $key => $val) {
$optionList[] = [$val, $key];
}
$config['items'] = array_merge($config['items'], $optionList);
return $config;
}
Now I can define my own CSS classes in Typoscript setting...
Last but not least the FluidStyleContent Part:
I overrride the Fluid_tyled_content template Textmedia.html and Layout Detaulf.html.
<v:content.resources.fal uid="{data.uid}" table="tt_content" field="background_media" as="ceBackground">
<f:if condition="{ceBackground}">
{v:uri.image(treatIdAsReference: 1, src: ceBackground.0.id, maxW: 1920) -> v:variable.set(name: 'parallaxBg')}
</f:if>
</v:content.resources.fal>
<div id="c{data.uid}" {f:if(condition: '{parallaxBg}', then: 'style="background-image: url(\'{parallaxBg}\');" ')}">
</div>
For a multiple classes use: {data.effects -> v:format.replace(substring: ',', replacement: ' ')}
Best regards
My goal is being able to:
Create Expertise Entries in the backend (already accomplished)
Create SubExpertise Entries in the backend
(same props as Expertise but
they belong to one or many Expertise)
Create AdditionalInfoTitles Entries in the backend
(they can belong to one or many Expertise OR SubExpertise)
I want to be able to choose Objects from all Expertise AND SubExpertise when creating a new entry
Right now I can only choose between all Expertise-Entries:
That's why I thought about inheritance since then SubExpertise would be of the same type as Expertise and therefore automatically displayed in the Expertise list in a AdditionalInfoTitles entry. But that's just my theory and I'm kinda stuck in reality with typo3 TCA and other knowledge that I'm lacking...
In my extension builder I made following (don't mind the subExpertises property)
Then I added expertise to the Overrides folder, because I'm trying to extend it with subexpertise:
<?php
if (!defined('TYPO3_MODE')) {
die ('Access denied.');
}
$temporaryColumns = array (
'expertise' => array(
'exclude' => 1,
'label' => 'LLL:EXT:appoints/Resources/Private/Language/locallang_db.xlf:tx_appoints_domain_model_subexpertise.expertise',
'config' => array(
'type' => 'select',
'foreign_table' => 'tx_appoints_domain_model_subexpertise',
'MM' => 'tx_appoints_subexpertise_expertise_mm',
'size' => 10,
'autoSizeMax' => 30,
'maxitems' => 9999,
'multiple' => 0,
'wizards' => array(
'_PADDING' => 1,
'_VERTICAL' => 1,
'edit' => array(
'module' => array(
'name' => 'wizard_edit',
),
'type' => 'popup',
'title' => 'Edit',
'icon' => 'edit2.gif',
'popup_onlyOpenIfSelected' => 1,
'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
),
'add' => Array(
'module' => array(
'name' => 'wizard_add',
),
'type' => 'script',
'title' => 'Create new',
'icon' => 'add.gif',
'params' => array(
'table' => 'tx_appoints_domain_model_expertise',
'pid' => '###CURRENT_PID###',
'setValue' => 'prepend'
),
),
),
),
),
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
'tx_appoints_domain_model_expertise',
$temporaryColumns
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'tx_appoints_domain_model_expertise',
'expertise'
);
But I don't think I'm going into the right direction with this -
Because I think this way I'm not gonna be able to add a SubExpertise in the backend separately from an Expertise - I already have the same problem with my Objects that extend fe_user because when creating them I usually have to go through a new User and then set the extension type - but this way I don't have separate listings of the different entities that extend fe_user.
I would get rid of the separation between Expertise and SubExpertise for the most part. According to your description a SubExpertise cannot have another SubExpertise as its parent, so you can adapt the select field that it only lists Expertises which have an empty parent field.
By removing the difference the problem of selecting (Sub)Expertise's in AdditionalInfoTitles is removed; it's just one and the same type of objects.
If you need to differentiate in the presentation in the BE forms there are plenty of options to adjust the labels of the listed items, use a function of your own to build the list or even a custom form element.
In Extbase you can simply write a few functions in your repository to fetch Expertise's, SubExpertise's or both.
If the entity SubExpertise does not have a meaning in your domain model, Jigal's answer is perfect for your scenario. If it does have a meaning, you can achieve that using single table inheritance in Extbase.
class Expertise extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
// all common properties
}
class SubExpertise extends Expertise
{
/**
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\[YourVendorName]\Appoints\Domain\Model\Expertise>
*/
protected $expertises;
public function __construct()
{
$this->expertises = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
public function getExpertises() {}
public function setExpertises($expertises) {}
}
Via TypoScript then you have to define mapping rules, since both Expertise and SubExpertise would be stored in the same table tx_appoints_domain_model_subexpertise.
You'll find more details on single table inheritance in the Extbase book.