Franz Holzinger
Franz Holzinger

Reputation: 998

TYPO3 11 call stdWrap from Extbase

How do you call the ContentObjectRenderer method stdWrap from Extbase?

The setup from a pi_base plugin is:

plugin.tx_myextension {
    standard = TEXT
    standard.value = Sorry, no data could be fetched!
}

In TYPO3 extensions without Extbase you have the $conf array with the keys

'standard' =>
     'TEXT' (string)

and the key

 'standard.' => 
      'value' (array) =>
          'Sorry, no data could be fetched!'. 

Then you call the method by:

$out =
    $cObj->stdWrap(
        $conf['standard'],
        $conf['standard.']
    );

This will render the desired text 'Sorry, no data could be fetched!' into $out.

But in Extbase you do not have the $conf array in this way. Exbase delivers the $this->settings to store the settings part of the setup.

plugin.tx_myextension {
    settings {
        standard = TEXT
        standard.value = Sorry, no data could be fetched!
    }
}

The standard setup is internally stored by Extbase as a 2-dimensional array with this data:

'standard' 
   => 'value' (Array) 
       => 'Sorry, no data could be fetched!'

and

'standard' 
   => '_typoScriptNodeValue' (Array) 
       => 'TEXT'

I have tried it this way ($conf = $this->settings):

$out =
    $cObj->stdWrap(
        '',
        $conf['standard']
    );

And I have tried this:

$out =
    $cObj->stdWrap(
        $conf['standard']['_typoScriptNodeValue'],
        $conf['standard']
    );

But the result is an empty string only.

What is the recommended way to accomplish the stdWrap rendering with Extbase?

Upvotes: 2

Views: 420

Answers (2)

Julian Hofmann
Julian Hofmann

Reputation: 2592

Maybe a look into the News extension can help. IMO it's a proper, flexible way without much overhead.

    // Use stdWrap for given defined settings

    if (isset($originalSettings['useStdWrap']) && !empty($originalSettings['useStdWrap'])) {
        $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
        $typoScriptArray = $typoScriptService->convertPlainArrayToTypoScriptArray($originalSettings);
        $stdWrapProperties = GeneralUtility::trimExplode(',', $originalSettings['useStdWrap'], true);
        foreach ($stdWrapProperties as $key) {
            if (is_array($typoScriptArray[$key . '.'])) {
                $originalSettings[$key] = $this->configurationManager->getContentObject()->stdWrap(
                    $typoScriptArray[$key],
                    $typoScriptArray[$key . '.']
                );
            }
        }
    }

    // start override
    if (isset($tsSettings['settings']['overrideFlexformSettingsIfEmpty'])) {
        $typoScriptUtility = GeneralUtility::makeInstance(TypoScript::class);
        $originalSettings = $typoScriptUtility->override($originalSettings, $tsSettings);
    }

    // ...

    $this->settings = $originalSettings;

snippet taken from https://github.com/georgringer/news/blob/main/Classes/Controller/NewsController.php#L658-L688

Upvotes: 1

Oliver Hader
Oliver Hader

Reputation: 4200

Basically $cObj->stdWrap only supports stdWrap instructions - however, you were using a cObject instruction (with TEXT).

Let's assume your settings look like this in TypoScript:

plugin.tx_myextension {
    settings {
        standard {
          # cObject is a stdWrap function
          # (that was the missing piece)
          cObject = TEXT
          cObject.value = Sorry, no data could be fetched!
        }
    }
}

Inside an Extbase controller $this->settings holds all data of the TypoScript path plugin.tx_myextension.settings as shown in the example before - and, the structure has been converted to be a "plain array".

Thus, inside a controller action things would look like this:

public function myAction()
{
    // consider using dependency-injection instead
    $typoScriptService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\TypoScriptService::class);
    // converting "plain array" back to TypoScript array
    $typoScriptArray = $typoScriptService->convertPlainArrayToTypoScriptArray($this->settings['standard']);

    // invoking stdWrap instruction    
    $cObj = $this->configurationManager->getContentObject();
    $out = $cObj->stdWrap('', $typoScriptArray);
    // ...
}

Additional considerations:

  • in Extbase, plugin settings from TypoScript and potential FlexForm settings for a specific plugin are merged
    • → make sure, to keep scopes separated before "executing" it as instruction
    • → otherwise editors might be able to trigger stdWrap functions via FlexForm
    • that would be an "injection" and a security vulnerability
  • e.g. use plugin.tx_myextension.instructions dedicated to be used in e.g. stdWrap, instead of putting everything to plugin.tx_myextension.settings
  • in general consider moving view-related aspects to a corresponding view or Fluid template, e.g using f:cObject view helper there

Upvotes: 1

Related Questions