stmllr.net

Conditions and dynamic values in TCA fields of TYPO3

by on stmllr.net

TYPO3 backend and TCA simetimes appear a bit old school. Fields and values are less flexible like you are used to in recent AJAX applications. How to make them more flexible without heavy JS frameworks like ExtJS?

The first thing that I found was the dynaflex extension. It allows to add new fields dynamically based on conditions. Anyway I found a quick&dirty solution, which looked more confident for the tiny task I had to solve:

The problem was to have dynamic values in the frames (section_frame) field of content elements, depending on the value of the column (colPos) field. If normal column was choosen, frames should offer value 80 and 81. If right column was choosen, frames should offer 82 and 83.

The first thing I did was to add colPos to the list of fields, which trigger saving and reloading the content element on change. I kickstarted a new extension and added these lines to extTables.php:

$updateFields = t3lib_div::trimExplode(',', $TCA['tt_content']['ctrl']['requestUpdate']);
if (in_array('colPos', $updateFields)) {
$TCA['tt_content']['ctrl']['requestUpdate'] .= ',colPos';
}

Then I changed the TCA of section_frame to use itemsProcFunc to customize its items:

$TCA['tt_content']['columns']['section_frame']['config']['items'] = array();
$TCA['tt_content']['columns']['section_frame']['config']['itemsProcFunc'] = 'tx_myext_setsectionframeitems->main';
if (TYPO3_MODE == 'BE') {
  include_once(t3lib_extMgm::extPath($_EXTKEY).'class.tx_myext_setsectionframeitems.php');
}

Next step was to implement the class, which controls the items. The class itself was stored in a seperate file called class.tx_myext_setsectionframeitems.php:

class tx_myext_setsectionframeitems {
  function main(&$params, &$pObj) {
    global $LANG;
    $selectOptions = array();

   // Allowed fields for normal column
    $normalFields = array(
      $LANG->sL("LLL:EXT:myext/locallang_tca.xml:tt_content.section_frame.I.80") => 80,
      $LANG->sL("LLL:EXT:myext/locallang_tca.xml:tt_content.section_frame.I.81") => 81
     );
    // Allowed fields for right column
    $rightFields = array(
      $LANG->sL("LLL:EXT:myext/locallang_tca.xml:tt_content.section_frame.I.82") => 82,
      $LANG->sL("LLL:EXT:myext/locallang_tca.xml:tt_content.section_frame.I.83") => 83
    );
    // Get value of tt_content.colPos
    $key = key($pObj->cachedTSconfig);
    $colPos = $pObj->cachedTSconfig[$key]['_THIS_ROW']['colPos'];
    // Add items
    if ($colPos == 2) {
      $selectOptions = $rightFields;
    } else {
      $selectOptions = $normalFields;
    }
    foreach ($selectOptions as $key => $value) {
      $params['items'][] = array(
        $key,
        $value
      );
    }
  }
}

if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/myext/class.tx_myext_setsectionframeitems.php'])  {
  include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/myext/class.tx_myext_setsectionframeitems.php']);
}

The custom labels were stored in a usual locallang file.

Finally, I did some TSconfig tuning in extTables.php to prevent invalid field values:

t3lib_extMgm::addPageTSConfig('
  TCEFORM.tt_content.section_frame.disableNoMatchingValueElement = 1
');

That's it. The whole stuff looks a bit ugly to me. So if you know a smarter solution, I'd be glad if you leave a comment.

Tags