2
votes

I have the own extension that has controller with two actions: listAction and showAction.
Question: Can I display two actions at the same page.

At specific page I've created an insert plugin record with my own plugin where in flexform of backend configuration of the plugin I've choosen "list action" via switchableControllerActions field. The list action contains list of products with link to the show action of product.

So what do I want?

F.e. I have page Products. The URL is example.com/products (here is my list action)
And for show action I want the URL like example.com/products/name-of-product

I've found a extension with this functionality. It's gb_events. And I noticed that in switchableControllerActions field of flexform of plugin there is something like this:

<switchableControllerActions>
        <TCEforms>
          <label>LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions</label>
          <config>
            <type>select</type>
            <items type="array">
              <numIndex index="0" type="array">
                <numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.upcoming</numIndex>
                <numIndex index="1">Event->upcoming;Event->list;Event->calendar;Event->show;Event->export</numIndex>
              </numIndex>
              <numIndex index="1" type="array">
                <numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.list</numIndex>
                <numIndex index="1">Event->list;Event->upcoming;Event->calendar;Event->show;Event->export</numIndex>
              </numIndex>
              <numIndex index="2" type="array">
                <numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.calendar</numIndex>
                <numIndex index="1">Event->calendar;Event->upcoming;Event->list;Event->show;Event->export</numIndex>
              </numIndex>
              <numIndex index="3" type="array">
                <numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.details</numIndex>
                <numIndex index="1">Event->show;Event->list;Event->upcoming;Event->calendar;Event->export</numIndex>
              </numIndex>
            </items>
            <maxitems>1</maxitems>
            <size>1</size>
          </config>
          <onChange>reload</onChange>
        </TCEforms>
      </switchableControllerActions>

I've updated my flexform configuration. But it still doesn't work. I've the same list view after when I click on link with show action.

Thanks in advance. I will appreciate any help.

2

2 Answers

3
votes

Make sure you have both, the list and detail Action in your switchableControllerActions like so:

<numIndex index="0" type="array">
            <numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.upcoming</numIndex>
            <numIndex index="1">Event->list;Event->calendar;Event->show</numIndex>
          </numIndex>

Then in your TypoScript Template use a condition to set the Controller / Action based on a detail uid:

[globalVar = GP:tx_myext_plugin|showUid > 0]
config.defaultGetVars {
    tx_myext_plugin.action = show
}
[global]

To get the other controller parameter off the URL in RealUrl use something like this:

array(
  'GETvar' => 'tx_extkey_plugin[action]',
  'noMatch' => 'bypass'
),

You can find more about this trick in this german article here

1
votes

The structurally more sensical approach is to keep that sort of logic inside the controller.

Make your showAction the defaut one and check the arguments in its initializaion. If no product was given, or the specified one cannot be loaded, forward to the list action.

/**
 * initialize action show
 * @return void
 */
public function initializeShowAction() {
    if($this->request->hasArgument('product')){
        if( $product=$this->stadtRepository->findByUid( 
            intval($this->request->getArgument('product'))
         ) ){
            $this->request->setArgument('product',$product);
            return;
        }
    }
    $this->forward('list');
}