Search code examples
typo3fluidflux

Fluidtypo3: Use custom field as title of FCE


I don't want to use the default header in my FCE's, but only custom flux fields. In the backend list views my FCE's are shown as "[no title]" because the default header is not filled. This leads to much confusion for editors.

How can I define one of my custom flux fields to be used as title for the FCE in TYPO3 Backend list views etc.?


Solution

  • You can't just use a field from the flexform, because all fields from the FCE are stored in the same field in the database (pi_flexform).

    What you can do is to render the content element title with a user function. It is registered with a line like this in the TCA config:

    $GLOBALS['TCA']['tt_content']['ctrl']['label_userFunc'] = 'Vendor\\Extkey\\Utility\\ContentElementLabelRenderer->getContentElementTitle';
    

    The user function itself could look like this:

    <?php
    namespace Vendor\Extkey\Utility;
    
    /**
     * This class renders a human readable title for FCEs,
     * so one is able to find a content element by its headline.
     */
    class ContentElementLabelRenderer implements \TYPO3\CMS\Core\SingletonInterface {
    
        /**
         * @var \TYPO3\CMS\Extbase\Service\FlexFormService
         * @inject
         */
        protected $flexFormService = null;
    
        /**
         * Returns the content element title for a given content element
         */
        public function getContentElementTitle(&$params) {
    
            if (null === $this->flexFormService) {
                $this->flexFormService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Service\\FlexFormService');
            }
    
            if (ctype_digit($params['row']['uid']) && 'fluidcontent_content' === $params['row']['CType']) {
    
                // If this is a FCE, parse the flexform and template name and generate the 
                // title in a template specific way.
                $row = $params['row'];
                $additionalRowData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('pi_flexform, tx_fed_fcefile', 'tt_content', 'uid = ' . $row['uid']);
                $flexFormContent = $this->flexFormService->convertFlexFormContentToArray($additionalRowData['pi_flexform']);
    
                $lastColonPosition = strrpos($additionalRowData['tx_fed_fcefile'], ':');
                $contentElementType = (FALSE === $lastColonPosition) ? 'invalidtype' : substr($additionalRowData['tx_fed_fcefile'], $lastColonPosition + 1);
                switch ($contentElementType) {
    
                    case 'Image.html':
                        $params['title'] = 'Image: "' . ($flexFormContent['title'] ?: $flexFormContent['subtitle']) . '"';
                        break;
                    default:
                        $params['title'] = 'Unknown content element type';
                        break;
                 }
            }
            else {
                // If this is not a FCEm, print out "normal"    
                // title. Not the real thing, but comes pretty close, hopefully.
                $params['title'] = $params['row']['header'] ?: ($params['row']['subheader'] ?: $params['row']['bodytext']);
            }
        }
    }
    

    This produces a maintainance problem though: Every time you add or change a content element, you have to update this file.