TYPO3.CMS 7.6 Schnipsel: Unterschied zwischen den Versionen
F (Diskussion | Beiträge) (→extends TYPO3\CMS\Backend\Controller\EditDocumentController) |
F (Diskussion | Beiträge) |
||
(35 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | [[ | + | [[TYPO3 LTS 9]] | [[TYPO3 LTS 8]] | [[TYPO3.CMS 7.6 Schnipsel]] | [[Typo3]] | [[Typo3 Entwicklereinstellungen]] | [[Typo3 Endbenutzer Hilfe]] |
= Allgemeine Theorien = | = Allgemeine Theorien = | ||
Zeile 20: | Zeile 20: | ||
* https://jweiland.net/typo3/versionen-und-updates/version-60.html#c1426 | * https://jweiland.net/typo3/versionen-und-updates/version-60.html#c1426 | ||
+ | == Browser Internetexplorer == | ||
+ | <source lang=typoscript> | ||
+ | |||
+ | [global] | ||
+ | [browser = msie] | ||
+ | page.includeCSS.file900 = fileadmin/Resources/Public/Stylesheets/ie-fixes.css | ||
+ | [global] | ||
+ | |||
+ | </source> | ||
+ | |||
+ | == if condition == | ||
+ | |||
+ | === if conditions im Zusammenhang mit Datenbanktabellen === | ||
+ | |||
+ | ==== Wert aus Datenbanktabelle in Variable schreiben und auch wenn Reihe nicht existiert Alternative nutzen ==== | ||
+ | |||
+ | <source lang=typoscript> | ||
+ | # Get Email address from fe_users by given POST-parameter | ||
+ | lib.powermailreceiverIni = CONTENT | ||
+ | lib.powermailreceiverIni { | ||
+ | table = tx_<<extname>>_domain_model_<<domainname>> | ||
+ | select { | ||
+ | # Page with records | ||
+ | pidInList = 123 | ||
+ | |||
+ | where { | ||
+ | # UID is given in field with marker {hiddenid} | ||
+ | data = GP:tx_powermail_pi1|field|hiddenid | ||
+ | |||
+ | wrap = uid=| | ||
+ | intval = 1 | ||
+ | } | ||
+ | } | ||
+ | renderObj = TEXT | ||
+ | renderObj { | ||
+ | field = nc_contactperson_email | ||
+ | } | ||
+ | } | ||
+ | |||
+ | plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email < lib.powermailreceiverIni | ||
+ | plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email.stdWrap.ifEmpty.cObject = TEXT | ||
+ | plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email.stdWrap.ifEmpty.cObject.value = alternative@mail.tld | ||
+ | |||
+ | </source> | ||
+ | |||
+ | |||
+ | ==== Wert aus Datenbanktabelle in Variable schreiben und wenn Variable in existierender Reihe nicht vorhanden ist Alternative nutzen ==== | ||
+ | |||
+ | * '''Achtung''': Vergleiche hierzu auch [[#Wert aus Datenbanktabelle in Variable schreiben und auch wenn Reihe nicht existiert Alternative nutzen]] | ||
+ | ** bei folgenden Beispiel funktioniert die Alternative wirklich nur, wenn die Tabellenreihe existiert, ansonsten führt es Alternative (override) nicht aus | ||
+ | |||
+ | |||
+ | <source lang=typoscript> | ||
+ | lib.powermailreceiver = CONTENT | ||
+ | lib.powermailreceiver { | ||
+ | table = tx_<<extname>>_domain_model_<<modelname>> | ||
+ | select { | ||
+ | # Page with records | ||
+ | pidInList = 1234 | ||
+ | |||
+ | where { | ||
+ | # UID of record is given in field with marker {hiddenid} | ||
+ | data = GP:tx_powermail_pi1|field|hiddenid | ||
+ | |||
+ | wrap = uid=| | ||
+ | intval = 1 | ||
+ | } | ||
+ | } | ||
+ | renderObj = TEXT | ||
+ | renderObj { | ||
+ | field = nc_contactperson_email | ||
+ | override = alternative@mail.tld | ||
+ | override.if.isFalse.field = nc_contactperson_email | ||
+ | } | ||
+ | } | ||
+ | |||
+ | plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email < lib.powermailreceiver | ||
+ | </source> | ||
== ajax handler == | == ajax handler == | ||
Zeile 68: | Zeile 146: | ||
</source> | </source> | ||
* http://blog.teamgeist-medien.de/2014/02/typo3-ajax-schnittstelle-in-extbase-extension-einrichten.html | * http://blog.teamgeist-medien.de/2014/02/typo3-ajax-schnittstelle-in-extbase-extension-einrichten.html | ||
+ | |||
+ | |||
+ | * auch nett get typoscript config | ||
+ | <source lang=php> | ||
+ | $GLOBALS['TSFE']->config['config']['forceTypeValue'] | ||
+ | </source> | ||
== PIDinRootline == | == PIDinRootline == | ||
Zeile 99: | Zeile 183: | ||
* https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/MainClasses/UsefulFunctions/Index.html | * https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/MainClasses/UsefulFunctions/Index.html | ||
== Generell == | == Generell == | ||
+ | |||
+ | === Sprache === | ||
+ | |||
+ | folgendes über setzt was so in den Language Dateien steht | ||
+ | |||
+ | <<vendor>>_<<extensionname>>/Resources/Private/Language/de.locallang.xlf | ||
+ | |||
+ | <source lang=php> | ||
+ | echo \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('languagecode','<<vendor>>_<<extensionname>>' ); | ||
+ | |||
+ | |||
+ | echo $GLOBALS['TSFE']->sL('LLL:EXT:<<vendor>>_<<extensionname>>/Resources/Private/Language/de.locallang.xlf:languagecode'); | ||
+ | |||
+ | </source> | ||
=== Variablen === | === Variablen === | ||
Zeile 259: | Zeile 357: | ||
</source> | </source> | ||
+ | * auch interessant flexform von anderen Extension erweitern [https://docs.typo3.org/typo3cms/extensions/news/DeveloperManual/ExtendNews/ExtendFlexforms/Index.html#extend-flexforms-with-custom-fields Extend flexforms with custom fields] | ||
'''ancmycurrentextension/ext_localconf.php''' | '''ancmycurrentextension/ext_localconf.php''' | ||
Zeile 419: | Zeile 518: | ||
+ | </source> | ||
+ | |||
+ | |||
+ | ==== beim query die Page Id ändern ==== | ||
+ | <source lang=php> | ||
+ | $query = $this->createQuery(); | ||
+ | $querySettings = $query->getQuerySettings(); | ||
+ | |||
+ | if($setRespectStoragePage === false) { | ||
+ | $querySettings->setRespectStoragePage(FALSE); | ||
+ | |||
+ | } else if(is_array($setRespectStoragePage)) { | ||
+ | $querySettings->setStoragePageIds($setRespectStoragePage); | ||
+ | } | ||
+ | |||
+ | // debug it | ||
+ | $parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser'); | ||
+ | $queryParts = $parser->parseQuery($query); | ||
+ | krexx($queryParts['additionalWhereClause']); | ||
</source> | </source> | ||
Zeile 532: | Zeile 650: | ||
</source> | </source> | ||
* https://wiki.typo3.org/Fluid_Inline_Notation | * https://wiki.typo3.org/Fluid_Inline_Notation | ||
+ | |||
+ | |||
+ | === f:uri.action === | ||
+ | |||
+ | <source lang=html> | ||
+ | <p><f:uri.action action="detail" controller="Fam" arguments="{showProd: '{product.link_id}'}"/></p> | ||
+ | <script type="text/javascript"> | ||
+ | refurl= '{f:uri.action( action:"detail" controller:"Fam" arguments:"{showProd:\"{product.link_id}\"}" )}'; | ||
+ | |||
+ | |||
+ | </script> | ||
+ | </source> | ||
+ | |||
+ | |||
+ | === f:for === | ||
+ | |||
+ | <source lang=html> | ||
+ | |||
+ | <li>{f:if(condition: i.isLast, then: '{x}', else: '{x} ') | ||
+ | -> f:for(each: {0: 'one', 1: 'two', 2: 'three'}, as: 'x', iteration: 'i')}</li> | ||
+ | |||
+ | <li>{x -> f:for(each: {0: 'one1', 1: 'two2', 2: 'three3'}, as: 'x', iteration: 'i')}</li> | ||
+ | |||
+ | <li>{variant.type -> f:for(each:'{product.variants}', as: 'variant', iteration: 'i')}</li> | ||
+ | |||
+ | <li>{f:if(condition: variant.type, then: 'data-{variant.type}=true ', else: ' else ') | ||
+ | -> f:for(each:'{product.variants}', as: 'variant', iteration: 'i')}</li> | ||
+ | |||
+ | </source> | ||
== f:link.page == | == f:link.page == | ||
Zeile 581: | Zeile 728: | ||
== allgemein == | == allgemein == | ||
<source lang=html> | <source lang=html> | ||
− | <f:format.html parseFuncTSPath="lib.parseFunc">{ | + | <f:format.html parseFuncTSPath="lib.parseFunc">{ancttnews.bodytext}</f:format.html> |
</source> | </source> | ||
− | |||
− | |||
== Debuggen in fluid == | == Debuggen in fluid == | ||
Zeile 604: | Zeile 749: | ||
</source> | </source> | ||
+ | * https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Xclasses/Index.html | ||
* '''ancextension/Classes/Controller/NcEditDocumentController.php''' | * '''ancextension/Classes/Controller/NcEditDocumentController.php''' | ||
<source lang=php> | <source lang=php> | ||
Zeile 611: | Zeile 757: | ||
class NcEditDocumentController extends \TYPO3\CMS\Backend\Controller\EditDocumentController { | class NcEditDocumentController extends \TYPO3\CMS\Backend\Controller\EditDocumentController { | ||
+ | /** | ||
+ | * fnc fügt den save buttons ein javascript alert hinzu, wenn diese gedrückt werden | ||
+ | */ | ||
protected function getButtons() { | protected function getButtons() { | ||
− | + | parent::getButtons(); | |
− | + | $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); | |
− | + | ||
+ | $buttons = $buttonBar->getButtons(); | ||
+ | if(is_object($buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0])) { | ||
+ | $OnClick = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->getOnClick(); | ||
+ | $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->setOnClick($OnClick.' showPreview();'); | ||
+ | $Classes = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->getClasses(); | ||
+ | $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->setClasses('ncPreviewPopup '.$Classes); | ||
+ | } | ||
+ | |||
+ | if(is_object($buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0])) { | ||
+ | $OnClick = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->getOnClick(); | ||
+ | $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->setOnClick($OnClick.' showPreview();'); | ||
+ | $Classes = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->getClasses(); | ||
+ | $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->setClasses('ncPreviewPopup '.$Classes); | ||
+ | |||
+ | $savebuttons = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->getButton(); | ||
+ | foreach($savebuttons['options'] as $i => $inputbutton) { | ||
+ | $OnClick = $inputbutton->getOnClick(); | ||
+ | $inputbutton->setOnClick($OnClick.' showPreview();'); | ||
+ | $Classes = $inputbutton->getClasses(); | ||
+ | $inputbutton->setClasses('ncPreviewPopup '.$Classes); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | if(is_object($buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0])) { | ||
+ | $OnClick = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->getOnClick(); | ||
+ | $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->setOnClick($OnClick.' showPreview();'); | ||
+ | $Classes = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->getClasses(); | ||
+ | $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->setClasses('ncPreviewPopup '.$Classes); | ||
+ | } | ||
+ | } | ||
} | } | ||
</source> | </source> | ||
+ | |||
+ | |||
+ | * Alternativ vllt per Hook https://forge.typo3.org/issues/71362 | ||
== Page Seiten TSConfig (mit TCA foreign_table_where Beispiel) == | == Page Seiten TSConfig (mit TCA foreign_table_where Beispiel) == | ||
Zeile 660: | Zeile 843: | ||
== Javascript im Backend == | == Javascript im Backend == | ||
+ | |||
+ | === Axjax Schnittstelle im Backend bereitstellen === | ||
+ | * Achtung ist in lts 9 deprecated und nicht mehr vorhanden in lts 10 | ||
+ | |||
+ | * EXT:ancextension/Configuration/Backend/AjaxRoutes.php | ||
+ | |||
+ | <source lang=php> | ||
+ | <?php | ||
+ | return [ | ||
+ | 'ancextension_backend_module' => [ | ||
+ | 'path' => '/ancextension/backend/module', | ||
+ | 'target' => \Netzcoop\Ancextension\Controller\NcBackendAjaxController::class . '::dispatch' | ||
+ | ] | ||
+ | ]; | ||
+ | </source> | ||
+ | |||
+ | * EXT:ancextension/Classes/Controller/NcBackendAjaxController.php | ||
+ | |||
+ | <source lang=php> | ||
+ | <?php | ||
+ | namespace Netzcoop\Ancextension\Controller; | ||
+ | |||
+ | class NcBackendAjaxController { | ||
+ | |||
+ | /** | ||
+ | * optional, aber folgendes wird wahrscheinlich gebraucht | ||
+ | */ | ||
+ | public function __construct() { | ||
+ | $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager'); | ||
+ | $this->persistenceManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class); | ||
+ | $this->einRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\Netzcoop\Ancextension\Domain\Repository\AncRepository::class, $this->objectManager); | ||
+ | $this->einRepository->injectPersistenceManager($this->persistenceManager); | ||
+ | } | ||
+ | |||
+ | public function dispatch(\TYPO3\CMS\Core\Http\ServerRequest $request, \TYPO3\CMS\Core\Http\Response $response) { | ||
+ | $queryParams = $request->getQueryParams(); | ||
+ | krexx(array($request, $response, $queryParams)); | ||
+ | echo "simple content .... "; | ||
+ | return $response; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </source> | ||
+ | |||
+ | * EXT:ancextension/Resources/Public/JavaScript/ancbackendIframe.js | ||
+ | <source lang=javascript> | ||
+ | |||
+ | var ajaxUrl = TYPO3.settings.ajaxUrls['ancextension_backend_module']; | ||
+ | |||
+ | jQuery.ajax({ | ||
+ | url: ajaxUrl, | ||
+ | type: 'get', | ||
+ | dataType: 'html', | ||
+ | cache: false, | ||
+ | data: { | ||
+ | 'ncAction': 'getCatTree', | ||
+ | 'ncCatIds': '172,97,98,99' | ||
+ | } | ||
+ | }).done(function (response) { | ||
+ | console.log('response'); | ||
+ | console.log(response); | ||
+ | }); | ||
+ | </source> | ||
+ | |||
+ | === Javascript in Hauptseite (linke Menu Spalte, obere Leiste, mittlere Baumseiten Spalte) im Backend === | ||
+ | ==== Variante A über Extra Datei==== | ||
'''ext_localconf.php''' | '''ext_localconf.php''' | ||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
$GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'][] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY). '/backend_ext1.php'; | $GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'][] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY). '/backend_ext1.php'; | ||
− | |||
</source> | </source> | ||
Zeile 683: | Zeile 931: | ||
** in backend_ext1.php muss der relative Pfad angegeben werden (vom backend ;) ) | ** in backend_ext1.php muss der relative Pfad angegeben werden (vom backend ;) ) | ||
* http://www.typo3.net/forum/thematik/zeige/thema/117431/ | * http://www.typo3.net/forum/thematik/zeige/thema/117431/ | ||
+ | |||
+ | ==== Variante B über abgeleiteten BackendController ==== | ||
+ | * '''ext_localconf.php''' | ||
+ | <source lang=php> | ||
+ | // .... | ||
+ | $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Backend\Controller\BackendController'] = array( | ||
+ | 'className' => 'Netzcoop\Extensionsname\Controller\NcBackendController' | ||
+ | ); | ||
+ | </source> | ||
+ | |||
+ | * '''extensionsname/Classes/Controller/NcBackendController.php''' | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | namespace Netzcoop\Extensionsname\Controller; | ||
+ | |||
+ | |||
+ | class NcBackendController extends \TYPO3\CMS\Backend\Controller\BackendController { | ||
+ | public function __construct() { | ||
+ | parent::__construct(); | ||
+ | $path = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('extensionsname'); | ||
+ | $this->jsFiles['ancbackend'] = $path.'/Resources/Public/JavaScript/ancbackend.js'; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | === Javascript in Iframe im Backend === | ||
+ | |||
+ | (funzt so seit min LTS 9 nicht mehr, siehe [[TYPO3_LTS_9#javascript_im_iframe_im_Backend_einbinden]]) | ||
+ | |||
+ | * '''ext_localconf.php''' | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Backend\Form\FormResultCompiler'] = array( | ||
+ | 'className' => 'Netzcoop\Extensionsname\Form\NcFormResultCompiler' | ||
+ | ); | ||
+ | </source> | ||
+ | |||
+ | * '''extensionsname/Classes/Form/NcFormResultCompiler.php''' | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | namespace Netzcoop\Extensionsname\Form; | ||
+ | |||
+ | class NcFormResultCompiler extends \TYPO3\CMS\Backend\Form\FormResultCompiler { | ||
+ | |||
+ | // JSbottom() abzuleiten führt zu Problemen | ||
+ | |||
+ | public function printNeededJSFunctions() { | ||
+ | $path = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('extensionsname'); | ||
+ | $this->loadJavascriptLib($path.'/Resources/Public/JavaScript/ancbackendIframe.js'); | ||
+ | |||
+ | return parent::printNeededJSFunctions(); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
== CSS im Backend == | == CSS im Backend == | ||
+ | === Variante a === | ||
+ | '''ext_tables.php''' | ||
+ | <source lang=php> | ||
+ | $GLOBALS['TBE_STYLES']['skins']['extensionsname'] = array ( | ||
+ | 'name' => 'extensionsname', | ||
+ | 'stylesheetDirectories' => array( | ||
+ | 'css' => 'EXT:' . $_EXTKEY . '/Resources/Public/Stylesheets/' | ||
+ | ) | ||
+ | ); | ||
+ | </source> | ||
+ | * Cache muss gelehrt werden | ||
+ | * Achtung: CSS ist im iframe UND auf der Hauptseite gültig | ||
+ | |||
+ | |||
+ | * https://www.typo3.net/forum/thematik/zeige/thema/106463/?tx_typo3forum_pi1[showForm]=0&cHash=e6b199153ba1240044e42a9bd9cc050a | ||
+ | |||
+ | === Variante b === | ||
'''ext_tables.php''' | '''ext_tables.php''' | ||
<source lang=php> | <source lang=php> | ||
Zeile 694: | Zeile 1.013: | ||
* Cache muss gelehrt werden | * Cache muss gelehrt werden | ||
* Achtung: CSS ist nicht im iframe gültig | * Achtung: CSS ist nicht im iframe gültig | ||
− | |||
− | |||
== Transformation typo3 4.x => typo3 7.6 == | == Transformation typo3 4.x => typo3 7.6 == | ||
Zeile 888: | Zeile 1.205: | ||
</source> | </source> | ||
https://jweiland.net/typo3/codebeispiele/extension-programmierung/displaycond.html | https://jweiland.net/typo3/codebeispiele/extension-programmierung/displaycond.html | ||
+ | |||
+ | |||
+ | = schon existierendes flexform von anderen plugin's erweitern = | ||
+ | |||
+ | * vom Prinzip folgendes Tutorial | ||
+ | ** https://docs.typo3.org/typo3cms/extensions/news/DeveloperManual/ExtendNews/ExtendFlexforms/Index.html#extend-flexforms-with-custom-fields | ||
+ | |||
+ | trotzdem kurz noch mal hier | ||
+ | |||
+ | * ext_localconf.php | ||
+ | <source lang=php> | ||
+ | $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class]['flexParsing'][] = \Netzcoop\Ancextension\Hooks\FlexFormHook::class; | ||
+ | </source> | ||
+ | |||
+ | * Classes/Hooks/FlexFormHook.php | ||
+ | <source lang=php> | ||
+ | |||
+ | namespace Netzcoop\Ancextension\Hooks; | ||
+ | |||
+ | /* | ||
+ | * To change this license header, choose License Headers in Project Properties. | ||
+ | * To change this template file, choose Tools | Templates | ||
+ | * and open the template in the editor. | ||
+ | */ | ||
+ | |||
+ | /** | ||
+ | * Description of FlexFormHook | ||
+ | * | ||
+ | * @author nc | ||
+ | */ | ||
+ | class FlexFormHook | ||
+ | { | ||
+ | // For 7x | ||
+ | /** | ||
+ | * @param array $dataStructArray | ||
+ | * @param array $conf | ||
+ | * @param array $row | ||
+ | * @param string $table | ||
+ | */ | ||
+ | public function getFlexFormDS_postProcessDS(&$dataStructArray, $conf, $row, $table) | ||
+ | { | ||
+ | if ($table === 'tt_content' && $row['CType'] === 'list' && $row['list_type'] === 'Ncdownloads') { | ||
+ | $dataStructArray['sheets']['extraEntry'] = 'typo3conf/ext/ancextension/Configuration/FlexForms/Extensions/fluid_styled_content/fluidContent.xml'; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // For 8x | ||
+ | /** | ||
+ | * @param array $dataStructure | ||
+ | * @param array $identifier | ||
+ | * @return array | ||
+ | */ | ||
+ | public function parseDataStructureByIdentifierPostProcess(array $dataStructure, array $identifier): array | ||
+ | { | ||
+ | krexx($identifier); | ||
+ | if ($identifier['type'] === 'tca' && $identifier['tableName'] === 'tt_content' && $identifier['dataStructureKey'] === 'ancfiles_ncdownloads,list') { | ||
+ | $file = PATH_site . 'typo3conf/ext/ancextension/Configuration/FlexForms/Extensions/fluid_styled_content/fluidContent.xml'; | ||
+ | $content = file_get_contents($file); | ||
+ | |||
+ | if ($content) { | ||
+ | $dataStructure['sheets']['extraEntry'] = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($content); | ||
+ | } | ||
+ | krexx($dataStructure['sheets']['extraEntry']); | ||
+ | } | ||
+ | return $dataStructure; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | '''nützlich''' ist hier den krexx sich auszugeben, damit es nicht lange schwirigkeiten gibt den dataStructureKey zufinden | ||
+ | |||
+ | * Configuration/FlexForms/Extensions/fluid_styled_content/fluidContent.xml | ||
+ | <source lang=xml> | ||
+ | <extra> | ||
+ | <ROOT> | ||
+ | <TCEforms> | ||
+ | <sheetTitle>Fo</sheetTitle> | ||
+ | </TCEforms> | ||
+ | <type>array</type> | ||
+ | <el> | ||
+ | <settings.postsPerPage> | ||
+ | <TCEforms> | ||
+ | <label>Max. number of posts to display per page</label> | ||
+ | <config> | ||
+ | <type>input</type> | ||
+ | <size>2</size> | ||
+ | <eval>int</eval> | ||
+ | <default>3</default> | ||
+ | </config> | ||
+ | </TCEforms> | ||
+ | </settings.postsPerPage> | ||
+ | </el> | ||
+ | </ROOT> | ||
+ | </extra> | ||
+ | </source> | ||
= Sonstiges = | = Sonstiges = |
Aktuelle Version vom 30. Juni 2020, 11:58 Uhr
TYPO3 LTS 9 | TYPO3 LTS 8 | TYPO3.CMS 7.6 Schnipsel | Typo3 | Typo3 Entwicklereinstellungen | Typo3 Endbenutzer Hilfe
Inhaltsverzeichnis
- 1 Allgemeine Theorien
- 2 typoscript
- 3 extbase (php)
- 4 fluid
- 5 Backend
- 6 flexform
- 7 schon existierendes flexform von anderen plugin's erweitern
- 8 Sonstiges
Allgemeine Theorien
Template / Typoscript Ladereihenfolge
- keine ahnung was als erstes geladen,
- Basis-Template
- danach werden die statischen templates (ExtensionManagementUtility::addStaticFile()) welche im Backend bei den Seiten aus den Erweiterungen eingebunden werden können geladen (oben als erstes/unten als letztes)
- danach die constants/setup der Seite
- danach erst die alphabetisch die ext_typoscsript_setup.txt Dateien
typoscript
[globalVar = TSFE:id = 10|12|15] (ist enthalten)
[globalVar = TSFE:id != 10|12|15] (ist nicht enthalten)
Browser Internetexplorer
[global]
[browser = msie]
page.includeCSS.file900 = fileadmin/Resources/Public/Stylesheets/ie-fixes.css
[global]
if condition
if conditions im Zusammenhang mit Datenbanktabellen
Wert aus Datenbanktabelle in Variable schreiben und auch wenn Reihe nicht existiert Alternative nutzen
# Get Email address from fe_users by given POST-parameter
lib.powermailreceiverIni = CONTENT
lib.powermailreceiverIni {
table = tx_<<extname>>_domain_model_<<domainname>>
select {
# Page with records
pidInList = 123
where {
# UID is given in field with marker {hiddenid}
data = GP:tx_powermail_pi1|field|hiddenid
wrap = uid=|
intval = 1
}
}
renderObj = TEXT
renderObj {
field = nc_contactperson_email
}
}
plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email < lib.powermailreceiverIni
plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email.stdWrap.ifEmpty.cObject = TEXT
plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email.stdWrap.ifEmpty.cObject.value = alternative@mail.tld
Wert aus Datenbanktabelle in Variable schreiben und wenn Variable in existierender Reihe nicht vorhanden ist Alternative nutzen
- Achtung: Vergleiche hierzu auch #Wert aus Datenbanktabelle in Variable schreiben und auch wenn Reihe nicht existiert Alternative nutzen
- bei folgenden Beispiel funktioniert die Alternative wirklich nur, wenn die Tabellenreihe existiert, ansonsten führt es Alternative (override) nicht aus
lib.powermailreceiver = CONTENT
lib.powermailreceiver {
table = tx_<<extname>>_domain_model_<<modelname>>
select {
# Page with records
pidInList = 1234
where {
# UID of record is given in field with marker {hiddenid}
data = GP:tx_powermail_pi1|field|hiddenid
wrap = uid=|
intval = 1
}
}
renderObj = TEXT
renderObj {
field = nc_contactperson_email
override = alternative@mail.tld
override.if.isFalse.field = nc_contactperson_email
}
}
plugin.tx_powermail.settings.setup.receiver.predefinedReceiver.ncreceiverfromnccompany.email < lib.powermailreceiver
ajax handler
- Configuration/TypoScript/setup.txt
pageAjax = PAGE
pageAjax {
# type id muss eindeutig für die komplette seite sein, hier ist die nummer pageajax ins telefon eingetippt
typeNum = 72432529
10 = FLUIDTEMPLATE
10 {
file = EXT:anclistel20/Resources/Private/Templates/template-fluid-empty.html
partialRootPath = EXT:anclistel20/Resources/Private/Partials/
layoutRootPath = EXT:anclistel20/Resources/Private/Layouts/
variables.INHALT = CONTENT
variables.INHALT {
table = tt_content
select {
# Use the sorting of the backend. We could as well use the date field or the header.
orderBy = sorting
# normal column
where = tt_content.list_type='anclistel20_ancelementlist'
}
}
}
config {
absRefPrefix = {$page.config.absRefPrefix}
disableAllHeaderCode = 1
additionalHeaders = Content-type:text/html
xhtml_cleaning = 0
admPanel = 0
# debug = 0
no_cache = 1
}
}
- Resources/Private/Templates/template-fluid-empty.html
<f:layout name="Void" />
<f:section name="main">
<f:format.html parseFuncTSPath="">{INHALT}</f:format.html>
</f:section>
<f:section name="footer"></f:section>
- auch nett get typoscript config
$GLOBALS['TSFE']->config['config']['forceTypeValue']
PIDinRootline
[PIDinRootline = 31]
page.10.variables.INHALT >
page.10.variables.INHALT = TEXT
page.10.variables.INHALT.value = Sie sind auf Seite 31 !!!! und PIDinRootline darf nicht geschachtelt sein!!!!
[global]
- wichtig die PIDinRootline Condition, darf nicht innner halb von geschweiften {} Klammern geschachtelt stehen
Sprachübersetzungen typoscript
plugin.tx_name_LOCAL_LANG.de.greater = Gruß
plugin.tx_femanager_pi1._LOCAL_LANG.default.tx_femanager_domain_model_user.gender.item0 = Mr
plugin.tx_femanager_pi1._LOCAL_LANG.de.tx_femanager_domain_model_user.gender.item0 = Herr
plugin.tx_femanager_pi1._LOCAL_LANG.en.tx_femanager_domain_model_user.gender.item0 = Mr.
plugin.tx_femanager_pi1._LOCAL_LANG.default.tx_femanager_domain_model_user.gender.item1 = Mrs.
plugin.tx_femanager_pi1._LOCAL_LANG.de.tx_femanager_domain_model_user.gender.item1 = Frau
plugin.tx_femanager_pi1._LOCAL_LANG.en.tx_femanager_domain_model_user.gender.item1 = Mrs.
extbase (php)
Generell
Sprache
folgendes über setzt was so in den Language Dateien steht
<<vendor>>_<<extensionname>>/Resources/Private/Language/de.locallang.xlf
echo \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('languagecode','<<vendor>>_<<extensionname>>' );
echo $GLOBALS['TSFE']->sL('LLL:EXT:<<vendor>>_<<extensionname>>/Resources/Private/Language/de.locallang.xlf:languagecode');
Variablen
krexx($GLOBALS['TSFE']);
krexx($GLOBALS['TSFE']->tmpl);
krexx($GLOBALS['TSFE']->tmpl->constants);
krexx($GLOBALS['TSFE']->tmpl->setup);
krexx($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($GLOBALS['TCA']);
Konstanten
ContentObject (tt_content Inhaltselement Eintrag)
- hole aktuelles tt_content objekt, also in diesem (Controller Plugin) Fall, das plugin (Controller::Action) Inhaltselement
im Controller:
$this->contentObj = $this->configurationManager->getContentObject();
// unter
krexx($this->contentObj->data); // ist ein tt_content Datensatz
// zB.
$this->contentObj->data['pid']; // Seiten ID wo das Plugin (Inhaltselement) installiert ist
$this->contentObj->data['pages']; // Datensatzsammlung
Installations Domain absRefPrefix
$GLOBALS['TSFE']->absRefPrefix.'/'
_GET / _POST holen
\TYPO3\CMS\Core\Utility\GeneralUtility::_GET();
\TYPO3\CMS\Core\Utility\GeneralUtility::_POST();
hole Objektmanager um Klassen bzw Objekte zu laden
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$ncmail = $objectManager->get('Netzcoop\Extension\Services\Ncmail');
hole Extension Konfiguration aus dem Backend
Formularfelder die vorher in ext_conf_template.txt definiert und im Backend unter Erweiterungsmanager bei der Extension eingestellt wurden
ext_conf_template.txt
# cat=basic/enable/010; type=int; label=LLL:EXT:ancextension/Resources/Private/Language/locallang_be.xml:basic.varInt
varInt =
# cat=basic/enable/020; type=string; label=LLL:EXT:ancextension/Resources/Private/Language/locallang_be.xml:basic.varString
varString = default wert
werte holen
// im Controller
$confArray = unserialize($GLOBALS["TYPO3_CONF_VARS"]["EXT"]["extConf"][strtolower($this->extensionName)]);
// im Zweifel aber Extensionname (ancextension) angeben!!!!
$confArray = unserialize($GLOBALS["TYPO3_CONF_VARS"]["EXT"]["extConf"][strtolower('ancextension')]);
echo $confArray['varString'];
logout / login
protected function login($ncfeuserid) {
$user = $this->userRepository->findByUid($ncfeuserid);
$GLOBALS['TSFE']->fe_user->createUserSession($user->_getProperties());
$GLOBALS["TSFE"]->fe_user->user = $GLOBALS["TSFE"]->fe_user->fetchUserSession();
// es wird empfohlen jetzt zu redirect'en
}
protected function logout() {
$GLOBALS['TSFE']->fe_user->logoff();
}
Controller
Variablen, Argumente und Objekte
krexx($this->request->getArguments());
krexx($this->request->getArgument('testvar'));
krexx($this->configurationManager->getContentObject());
Controller::settings - Informationen aus Typoscript und Flexform
von Typoscript
- ancotherextension/Configuration/TypoScript/setup.txt
plugin.tx_ancmycurrentextension {
settings {
ancotherextension_typoscript_setup = TEXT
ancotherextension_typoscript_setup {
value = ancotherextension/Configuration/TypoScript/setup.txt
}
}
}
- ancotherextension/ext_typoscript_setup.txt
plugin.tx_ancmycurrentextension {
settings {
ancotherextension_ext_typoscript = TEXT
ancotherextension_ext_typoscript {
value = ancotherextension: ext_typoscript_setup.txt
}
}
}
von Flexform
- plugin Konfiguration beim Inhaltselement
ancmycurrentextension/Configuration/FlexForms/pi.xml
<T3DataStructure>
<meta>
<langDisable>1</langDisable>
</meta>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>examples.pi_flexform.sheetGeneral</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<settings.flexformvariable>
<TCEforms>
<label>flexformvariable label</label>
<config>
<type>input</type>
<size>10</size>
<max>10</max>
<eval>trim</eval>
</config>
</TCEforms>
</settings.flexformvariable>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
- auch interessant flexform von anderen Extension erweitern Extend flexforms with custom fields
ancmycurrentextension/ext_localconf.php
$pluginSignature = 'pi';
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Netzcoop.' . $_EXTKEY,
$pluginSignature,
array(
'Nctest' => 'show',
),
// non-cacheable actions
array(
'Nctest' => 'show',
)
);
ancmycurrentextension/ext_tables.php
$pluginSignature = 'pi';
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
$_EXTKEY,
$pluginSignature,
'ancmycurrentextension: pi'
);
$TCA['tt_content']['types']['list']['subtypes_addlist'][$_EXTKEY.'_'.strtolower($pluginSignature)]='pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue($_EXTKEY.'_'.strtolower($pluginSignature), 'FILE:EXT:'.$_EXTKEY.'/Configuration/FlexForms/'.$pluginSignature.'.xml');
nach Controller::settings
- ancmycurrentextension/Classes/Controller/NctestController.php
// ...
public function showAction() {
krexx($this->settings);
echo $this->settings['ancotherextension_typoscript_setup']['value'];
echo $this->settings['ancotherextension_ext_typoscript']['value'];
echo $this->settings['flexformvariable'];
}
// ...
Url/Link erstellen
$uriBuilder = $this->controllerContext->getUriBuilder();
$uriBuilder->reset();
$uriBuilder->setArguments(array(
strtolower($this->extensionName) => array(
'param1' => $user->getUid(),
'param2' => 'test',
)
));
$uriBuilder->setTargetPageUid(12);
$uriBuilder->setCreateAbsoluteUri(true); // mit Domain: sprich http://domain.tld/ - das fehlt sonst
$uri = $uriBuilder->build();
\TYPO3\CMS\Core\Utility\HttpUtility::redirect($uri, \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_303);
$uriBuilder = $this->objectManager->get(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
# ausserhalb vom Controller ists schwierig weil kontext fehlt
#$uriBuilder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
# backend uribuilder
# $uriBuilder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class);
$uriBuilder->setRequest($this->request);
$url = $uriBuilder->reset()->uriFor($action, $parameters, $controller);
- https://typo3.org/api/typo3cms/class_t_y_p_o3_1_1_c_m_s_1_1_extbase_1_1_mvc_1_1_web_1_1_routing_1_1_uri_builder.html
- Probleme gibt es ausserhalb von einem Controller und wenn mensch nicht eingeloggt ist
- Link erstellen
\TYPO3\CMS\Core\Utility\GeneralUtility::locationHeaderUrl(sprintf('/%s/....', $this->settings['langIso']));
Actions für ander extensions bereitstellen
Configuration/TypoScript/setup.txt
config.tx_extbase {
objects {
In2code\Powermail\Controller\FormController {
className = Netzcoop\Ancextension\Controller\FormController
}
}
}
- ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']['Powermail']['plugins']['Pi1']['controllers']['Form']['actions'][] = 'neue';
Domain
Repository nutzen
PageRepository: rekursiv den page pfad gehen
namespace <<vendor>>\<<extensionname>>\Services;
class XHelper {
public static $PageBacktraceTreeList = array();
public static function getPageBacktraceTreeList($iPid, \TYPO3\CMS\Frontend\Page\PageRepository $pageRepository=null) {
if(!array_key_exists($iPid, self::$PageBacktraceTreeList) || !self::$PageBacktraceTreeList[$iPid]) {
if(is_null($pageRepository)) {
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$pageRepository = $objectManager->get('TYPO3\CMS\Frontend\Page\PageRepository');
}
$page = $pageRepository->getPage($iPid);
if($page['pid']) {
self::$PageBacktraceTreeList[$iPid] = self::getPageBacktraceTreeList($page['pid'], $pageRepository).','.$iPid;
} else {
self::$PageBacktraceTreeList[$iPid] = ''.$iPid;
}
}
return self::$PageBacktraceTreeList[$iPid];
}
}
Einem Repository ein anderes Model zu weisen (set a model to a repository)
analog zum Konstrukter
$this->objectType = \TYPO3\CMS\Core\Utility\ClassNamingUtility::translateRepositoryNameToModelName('<<vendorname>>\<<extensionname>>\Domain\Repository\<<name>>Repository');
krexx(array($this->objectType, \TYPO3\CMS\Core\Utility\ClassNamingUtility::translateRepositoryNameToModelName('Netzcoop\Anchoexterbasic\Domain\Repository\EntryRepository')));
ein Repository zum Beispiel im Sheduler nutzen
- ausserhalb von einem controller oder so ein Repository nutzen
/** @var $querySettings \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings */
// $querySettings = $objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings::class);
$querySettings = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
$querySettings->setStoragePageIds(array(15));
$frontendUserRepository->setDefaultQuerySettings($querySettings);
$users=$frontendUserRepository->findAll();
krexx($users);
beim query die Page Id ändern
$query = $this->createQuery();
$querySettings = $query->getQuerySettings();
if($setRespectStoragePage === false) {
$querySettings->setRespectStoragePage(FALSE);
} else if(is_array($setRespectStoragePage)) {
$querySettings->setStoragePageIds($setRespectStoragePage);
}
// debug it
$parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser');
$queryParts = $parser->parseQuery($query);
krexx($queryParts['additionalWhereClause']);
Database
direktes sql
// prepare_SELECTquery ($select_fields, $from_table, $where_clause, $groupBy= '', $orderBy= '', $limit= '', array $input_parameters=array())
$statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery(
'*' // $select_fields
, 'tab1, tab1_mm as mm' // $from_table
, 'tt_news.uid = mm.uid_local ' // $where_clause
. 'AND tt_news.pid = :store_page_id '
. $ncsearchwhere.$between
, '' // $groupBy
, 'crdate DESC' // $orderBy
, '' // $limit
);
$statement->bindValues(array(
':store_page_id' => $store_page_id
));
if ($statement) {
$statement->execute();
$return = $statement->fetchAll();
$statement->free();
}
ext_conf_template.txt
vorhandene typen
ext_conf_template.txt
# cat=basic/enable/020;; type=int+; label=LLL:EXT:ancextension/Resources/Private/Language/locallang_be.xml:basic.forgotTimeForDeactivateLogin
forgotTimeForDeactivateLogin =
# cat=basic/enable/030;; type=string; label=LLL:EXT:ancextension/Resources/Private/Language/locallang_be.xml:basic.mailsubject
mailsubject =
# cat=basic/enable/017;; type=options[gleich=0,ungleich=1]; label=LLL:EXT:ancextension/Resources/Private/Language/locallang_be.xml:basic.emailcondition2
emailcondition2 =
eigener typ (als Viewhelper)
ext_conf_template.txt
# cat=basic/enable/050;; type=user[Netzcoop\Ancextension\ViewHelpers\TextArea->render]; label=LLL:EXT:ancextension/Resources/Private/Language/locallang_be.xml:basic.mailtext
mailtext =
Classes/ViewHelpers/TextArea.php
<?php
namespace Netzcoop\Ancextension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extensionmanager\ViewHelpers\Form\TypoScriptConstantsViewHelper;
/**
* @package jwparking
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
*
*/
class TextArea {
/**
* Tag builder instance
*
* @var \TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder
*/
protected $tag = NULL;
/**
* constructor of this class
*/
public function __construct() {
$this->tag = GeneralUtility::makeInstance('TYPO3\\CMS\\Fluid\\Core\\ViewHelper\\TagBuilder');
}
/**
* render textarea for extConf
*
* @param array $parameter
* @param TypoScriptConstantsViewHelper $parentObject
* @return string
*/
public function render(array $parameter = array(), TypoScriptConstantsViewHelper $parentObject) {
$this->tag->setTagName('textarea');
$this->tag->forceClosingTag(TRUE);
$this->tag->addAttribute('cols', 45);
$this->tag->addAttribute('rows', 7);
$this->tag->addAttribute('name', $parameter['fieldName']);
$this->tag->addAttribute('id', 'em-' . $parameter['fieldName']);
if ($parameter['fieldValue'] !== NULL) {
$this->tag->setContent(trim($parameter['fieldValue']));
}
return $this->tag->render();
}
}
fluid
if in geschweiften klammern
1: {f:if(condition: "{type}=='auto'", then:" dannDas" )}
2: <f:if condition="{type}=='auto'"> dannDas</f:if>
f:uri.action
<p><f:uri.action action="detail" controller="Fam" arguments="{showProd: '{product.link_id}'}"/></p>
<script type="text/javascript">
refurl= '{f:uri.action( action:"detail" controller:"Fam" arguments:"{showProd:\"{product.link_id}\"}" )}';
</script>
f:for
<li>{f:if(condition: i.isLast, then: '{x}', else: '{x} ')
-> f:for(each: {0: 'one', 1: 'two', 2: 'three'}, as: 'x', iteration: 'i')}</li>
<li>{x -> f:for(each: {0: 'one1', 1: 'two2', 2: 'three3'}, as: 'x', iteration: 'i')}</li>
<li>{variant.type -> f:for(each:'{product.variants}', as: 'variant', iteration: 'i')}</li>
<li>{f:if(condition: variant.type, then: 'data-{variant.type}=true ', else: ' else ')
-> f:for(each:'{product.variants}', as: 'variant', iteration: 'i')}</li>
f:link.page
Achtung: bei der inline Notation muss es eine Variable sein, es darf nicht einfach ein String angegeben werden!!!
<li>tag notation: <f:link.page pageUid="{settings.linkPageUid}" id="register-btn">{settings.linkText}</f:link.page></li>
<li>inline notation: {settings.linkText -> f:link.page(pageUid:'{settings.linkPageUid}', id:'register-btn')}</li>
elseif
<f:if condition="{var}!='<ul class=\"navi\"></ul>'">
<f:then>
hier ist if
</f:then>
<f:else>
<f:if condition="!{var}">
<f:then>
Hier ist else if
</f:then>
<f:else>
Hier ist Else
</f:else>
</f:if>
</f:else>
</f:if>
translate
- de.locallang.xlf
<trans-unit id="form.login.no.account.yet">
<target>Hier gleich ein Link <![CDATA[? <a href="%s" target="%s" id="register-btn">nein hier</a>]]></target>
</trans-unit>
<trans-unit id="linktest2">
<target>Weitere Informationen zu den Lizenzen<![CDATA[ <a href="%s" id="register-btn">finden Sie hier</a>]]></target>
</trans-unit>
- template
<f:translate key="form.login.no.account.yet" arguments="{0: '{f:uri.action(action: \'test\')}', 1: '_self'}" />
<f:format.html>{f:translate(key: 'form.login.no.account.yet', arguments: {0: 'dog', 1: 'fox'})}</f:format.html>
<p><f:format.html>{f:translate(key: 'linktest2', arguments: {0: '{settings.linkTo}'})}</f:format.html></p>
allgemein
<f:format.html parseFuncTSPath="lib.parseFunc">{ancttnews.bodytext}</f:format.html>
Debuggen in fluid
<f:debug title="Ausgabe im Frontent vom entry">{entry}</f:debug>
Backend
Backend Klassen ableiten
extends TYPO3\CMS\Backend\Controller\EditDocumentController
- ancextension/ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Backend\Controller\EditDocumentController'] = array(
'className' => 'Netzcoop\Ancextension\Controller\NcEditDocumentController'
);
- https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/Xclasses/Index.html
- ancextension/Classes/Controller/NcEditDocumentController.php
<?php
namespace Netzcoop\Ancextension\Controller;
class NcEditDocumentController extends \TYPO3\CMS\Backend\Controller\EditDocumentController {
/**
* fnc fügt den save buttons ein javascript alert hinzu, wenn diese gedrückt werden
*/
protected function getButtons() {
parent::getButtons();
$buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
$buttons = $buttonBar->getButtons();
if(is_object($buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0])) {
$OnClick = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->getOnClick();
$buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->setOnClick($OnClick.' showPreview();');
$Classes = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->getClasses();
$buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][1][0]->setClasses('ncPreviewPopup '.$Classes);
}
if(is_object($buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0])) {
$OnClick = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->getOnClick();
$buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->setOnClick($OnClick.' showPreview();');
$Classes = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->getClasses();
$buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->setClasses('ncPreviewPopup '.$Classes);
$savebuttons = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][2][0]->getButton();
foreach($savebuttons['options'] as $i => $inputbutton) {
$OnClick = $inputbutton->getOnClick();
$inputbutton->setOnClick($OnClick.' showPreview();');
$Classes = $inputbutton->getClasses();
$inputbutton->setClasses('ncPreviewPopup '.$Classes);
}
}
if(is_object($buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0])) {
$OnClick = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->getOnClick();
$buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->setOnClick($OnClick.' showPreview();');
$Classes = $buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->getClasses();
$buttons[\TYPO3\CMS\Backend\Template\Components\ButtonBar::BUTTON_POSITION_LEFT][3][0]->setClasses('ncPreviewPopup '.$Classes);
}
}
}
- Alternativ vllt per Hook https://forge.typo3.org/issues/71362
Page Seiten TSConfig (mit TCA foreign_table_where Beispiel)
Configuration/PageTSconfig/pageTSconfig.ts - diese Datei wird in diesem Beispiel immer geladen und stellt die default Einstellung dar!
TCEFORM.tx_extensionname_domain_model_entry.ancvendorid.PAGE_TSCONFIG_ID = 0
TCEFORM.tx_extensionname_domain_model_entry.ancvendorid.PAGE_TSCONFIG_IDLIST = 20,21,23
ext_localconf.php
// pageTSConfig.ts wird default mäßig immer geladen!
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:extensionname/Configuration/PageTSconfig/pageTSconfig.ts">');
Configuration/PageTSconfig/STORAGE_Markenprodukte.ts - diese Datei kann unter den Einstellungen einer Seite bequem für TSConfig eingezogen werden
TCEFORM.tx_bluemediaboard_domain_model_entry.ancvendorid.PAGE_TSCONFIG_ID = 20
ext_tables.php
// STORAGE_Markenprodukte.ts wird zur Auswahl angeboten!
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::registerPageTSConfigFile($_EXTKEY,'Configuration/PageTSconfig/STORAGE_Markenprodukte.ts','STORAGE Markenprodukte');
Configuration/TCA/Overrides/Entry.php (Beispiel das wenn nicht PAGE_TSCONFIG_ID bei einer Seite im TSConfig angegeben ist, er automatisch 20,21,23 nehmen soll)
'ancvendorid'=> array(
// ....
'config' => array(
'foreign_table_where' => 'AND tx_extensionname_domain_model_entry.type=12 AND (tx_extensionname_domain_model_entry.pid=###PAGE_TSCONFIG_ID### OR (!###PAGE_TSCONFIG_ID### AND tx_extensionname_domain_model_entry.pid in (###PAGE_TSCONFIG_IDLIST###)))',
),
// ....
),
- https://docs.typo3.org/typo3cms/TSconfigReference/PageTsconfig/TCEform/Index.html
- https://docs.typo3.org/typo3cms/TCAReference/Reference/Columns/Select/Index.html#foreign-table-where
Javascript im Backend
Axjax Schnittstelle im Backend bereitstellen
- Achtung ist in lts 9 deprecated und nicht mehr vorhanden in lts 10
- EXT:ancextension/Configuration/Backend/AjaxRoutes.php
<?php
return [
'ancextension_backend_module' => [
'path' => '/ancextension/backend/module',
'target' => \Netzcoop\Ancextension\Controller\NcBackendAjaxController::class . '::dispatch'
]
];
- EXT:ancextension/Classes/Controller/NcBackendAjaxController.php
<?php
namespace Netzcoop\Ancextension\Controller;
class NcBackendAjaxController {
/**
* optional, aber folgendes wird wahrscheinlich gebraucht
*/
public function __construct() {
$this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
$this->persistenceManager = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
$this->einRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\Netzcoop\Ancextension\Domain\Repository\AncRepository::class, $this->objectManager);
$this->einRepository->injectPersistenceManager($this->persistenceManager);
}
public function dispatch(\TYPO3\CMS\Core\Http\ServerRequest $request, \TYPO3\CMS\Core\Http\Response $response) {
$queryParams = $request->getQueryParams();
krexx(array($request, $response, $queryParams));
echo "simple content .... ";
return $response;
}
}
- EXT:ancextension/Resources/Public/JavaScript/ancbackendIframe.js
var ajaxUrl = TYPO3.settings.ajaxUrls['ancextension_backend_module'];
jQuery.ajax({
url: ajaxUrl,
type: 'get',
dataType: 'html',
cache: false,
data: {
'ncAction': 'getCatTree',
'ncCatIds': '172,97,98,99'
}
}).done(function (response) {
console.log('response');
console.log(response);
});
Javascript in Hauptseite (linke Menu Spalte, obere Leiste, mittlere Baumseiten Spalte) im Backend
Variante A über Extra Datei
ext_localconf.php
<?php
$GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'][] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY). '/backend_ext1.php';
backend_ext1.php
<?php
if (TYPO3_MODE=="BE" ) {
$pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
$path = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('extensionsname');
$pageRenderer->addJsFile('https://code.jquery.com/jquery-1.11.3.min.js', 'text/javascript', true, false);
$pageRenderer->addJsFile($path.'/Resources/Public/JavaScript/ancbackend.js', 'text/javascript', true, false);
}
- Achtung
- es muss extra der Weg über eine extra Datei gegangen werden, da $GLOBALS['TBE_TEMPLATE'] nicht geladen ist
- Cache muss natürlich gelöscht werden
- in ext_localconf muss der absolute Pfad angegeben werden
- in backend_ext1.php muss der relative Pfad angegeben werden (vom backend ;) )
- http://www.typo3.net/forum/thematik/zeige/thema/117431/
Variante B über abgeleiteten BackendController
- ext_localconf.php
// ....
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Backend\Controller\BackendController'] = array(
'className' => 'Netzcoop\Extensionsname\Controller\NcBackendController'
);
- extensionsname/Classes/Controller/NcBackendController.php
<?php
namespace Netzcoop\Extensionsname\Controller;
class NcBackendController extends \TYPO3\CMS\Backend\Controller\BackendController {
public function __construct() {
parent::__construct();
$path = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('extensionsname');
$this->jsFiles['ancbackend'] = $path.'/Resources/Public/JavaScript/ancbackend.js';
}
}
Javascript in Iframe im Backend
(funzt so seit min LTS 9 nicht mehr, siehe TYPO3_LTS_9#javascript_im_iframe_im_Backend_einbinden)
- ext_localconf.php
<?php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Backend\Form\FormResultCompiler'] = array(
'className' => 'Netzcoop\Extensionsname\Form\NcFormResultCompiler'
);
- extensionsname/Classes/Form/NcFormResultCompiler.php
<?php
namespace Netzcoop\Extensionsname\Form;
class NcFormResultCompiler extends \TYPO3\CMS\Backend\Form\FormResultCompiler {
// JSbottom() abzuleiten führt zu Problemen
public function printNeededJSFunctions() {
$path = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('extensionsname');
$this->loadJavascriptLib($path.'/Resources/Public/JavaScript/ancbackendIframe.js');
return parent::printNeededJSFunctions();
}
}
CSS im Backend
Variante a
ext_tables.php
$GLOBALS['TBE_STYLES']['skins']['extensionsname'] = array (
'name' => 'extensionsname',
'stylesheetDirectories' => array(
'css' => 'EXT:' . $_EXTKEY . '/Resources/Public/Stylesheets/'
)
);
- Cache muss gelehrt werden
- Achtung: CSS ist im iframe UND auf der Hauptseite gültig
- https://www.typo3.net/forum/thematik/zeige/thema/106463/?tx_typo3forum_pi1[showForm]=0&cHash=e6b199153ba1240044e42a9bd9cc050a
Variante b
ext_tables.php
if (TYPO3_MODE=="BE" ) {
$TBE_STYLES['inDocStyles_TBEstyle'] .= ' body {font-size: 100px;}";';
$TBE_STYLES['inDocStyles_TBEstyle'] .= '@import "/typo3conf/ext/'.$_EXTKEY.'/Resources/Public/Stylesheets/backend.css";';
}
- Cache muss gelehrt werden
- Achtung: CSS ist nicht im iframe gültig
Transformation typo3 4.x => typo3 7.6
GeneralUtility
alt
t3lib_div::
neu
\TYPO3\CMS\Core\Utility\GeneralUtility::
alt
$this->doc = t3lib_div::makeInstance('bigDoc');
neu
$this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
BaseScriptClass
alt
extends t3lib_SCbase
neu
extends \TYPO3\CMS\Backend\Module\BaseScriptClass
BackendUtility
alt
t3lib_BEfunc::
neu
BackendUtility:: use \TYPO3\CMS\Backend\Utility\BackendUtility;
BackendUtility
alt
t3lib_extMgm::
neu
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::
tt_news
fileupload maxFileSize für Medien im Artikel erstellen hochsetzen
z.B: 50 MB
typo3conf/ext/EXTENSIONNAME/ext_tables.php
// tt_news
$GLOBALS['TCA']['tt_news']['columns']['news_files']['config']['max_size'] = 500000;
// This changes the upload limit for image elements
$GLOBALS['TCA']['tt_content']['columns']['image']['config']['max_size'] = 500000;
// This changes the upload limit for media elements
$GLOBALS['TCA']['tt_content']['columns']['media']['config']['max_size'] = 500000;
// This changes the upload limit for multimedia elements
$GLOBALS['TCA']['tt_content']['columns']['multimedia']['config']['max_size'] = 500000;
flexform
Display Condition
displayCond innerhalb eines Sheet
Flexformfelder nur im bestimten Kontext anzeigen.
<el>
<switchableControllerActions>
<TCEforms>
<label>Select function</label>
<config>
<type>select</type>
<items>
<numIndex index="0">
<numIndex index="0">Testcontroller anzeigen</numIndex>
<numIndex index="1">Testcontroller->list</numIndex>
</numIndex>
....
<settings.test>
<TCEforms>
<label>Test</label>
<!-- wenn Testcontroller anzeigen ausgewählt wurde erscheint dieses input -->
<displayCond>FIELD:switchableControllerActions:=:Testcontroller->list</displayCond>
<config>
<type>input</type>
<size>20</size>
<max>120</max>
<eval>trim</eval>
</config>
</TCEforms
- Achtung: diese Art von displayCond funktioniert ausschließlich nur innerhalb eines Sheets!!!!!
- ein einzelnes Formularfeld anzeigen weil auf einem anderen sheet was ausgewählt wurde geht nicht ...
- Alternative ist das ganze sheet nicht anzuzeigen ... siehe unten
displayCond auf ganze Sheets abhängig vom FIELD:sDEF.switchableControllerActions
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>Basiseinstellungen</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<switchableControllerActions>
<TCEforms>
<label>Select function</label>
<onChange>reload</onChange>
<config>
<type>select</type>
<items>
<numIndex index="0">
<numIndex index="0">Liste/Ajax</numIndex>
<numIndex index="1">Ncelement->ncindex;Ncelement->ncajax</numIndex>
</numIndex>
<numIndex index="1">
<numIndex index="0">Einzelansicht</numIndex>
<numIndex index="1">Ncelement->ncshow</numIndex>
</numIndex>
<numIndex index="2">
<numIndex index="0">Ajax-Handler</numIndex>
<numIndex index="1">Ncelement->ncajax</numIndex>
</numIndex>
<numIndex index="3">
<numIndex index="0">Liste</numIndex>
<numIndex index="1">Ncelement->ncindex</numIndex>
</numIndex>
</items>
</config>
</TCEforms>
</switchableControllerActions>
</el>
</ROOT>
</sDEF>
<sheetlist>
<ROOT>
<TCEforms>
<sheetTitle>Liste</sheetTitle>
<!-- dieser sheet wird nur angezeigt wenn Liste (Ncelement->ncindex) oder Liste/Ajax (Ncelement->ncindex;Ncelement->ncajax) ausgewählt wird -->
<displayCond>FIELD:sDEF.switchableControllerActions:IN:Ncelement->ncindex,Ncelement->ncindex;Ncelement->ncajax</displayCond>
</TCEforms>
<type>array</type>
<el>
</el>
</ROOT>
</sheetlist>
</sheets>
</T3DataStructure>
Andere Beispiel mit AND und OR
<feld1>
<TCEforms>
<label>Feld 1</label>
<config>
<type>input</type>
<size>30</size>
</config>
</TCEforms>
</feld1>
<feld2>
<TCEforms>
<label>Feld 2</label>
<config>
<type>input</type>
<size>30</size>
</config>
</TCEforms>
</feld2>
<cond>
<TCEforms>
<label>Teste Bedingung</label>
<displayCond>
<AND>
<numIndex index="0">FIELD:feld1:REQ:TRUE</numIndex>
<numIndex index="1">FIELD:feld2:REQ:TRUE</numIndex>
<OR>
<numIndex index="0"><![CDATA[FIELD:feld1:<:12]]></numIndex>
<numIndex index="1">FIELD:feld2:>:20</numIndex>
</OR>
</AND>
</displayCond>
<config>
<type>input</type>
<size>30</size>
</config>
</TCEforms>
</cond>
https://jweiland.net/typo3/codebeispiele/extension-programmierung/displaycond.html
schon existierendes flexform von anderen plugin's erweitern
- vom Prinzip folgendes Tutorial
trotzdem kurz noch mal hier
- ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class]['flexParsing'][] = \Netzcoop\Ancextension\Hooks\FlexFormHook::class;
- Classes/Hooks/FlexFormHook.php
namespace Netzcoop\Ancextension\Hooks;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
* Description of FlexFormHook
*
* @author nc
*/
class FlexFormHook
{
// For 7x
/**
* @param array $dataStructArray
* @param array $conf
* @param array $row
* @param string $table
*/
public function getFlexFormDS_postProcessDS(&$dataStructArray, $conf, $row, $table)
{
if ($table === 'tt_content' && $row['CType'] === 'list' && $row['list_type'] === 'Ncdownloads') {
$dataStructArray['sheets']['extraEntry'] = 'typo3conf/ext/ancextension/Configuration/FlexForms/Extensions/fluid_styled_content/fluidContent.xml';
}
}
// For 8x
/**
* @param array $dataStructure
* @param array $identifier
* @return array
*/
public function parseDataStructureByIdentifierPostProcess(array $dataStructure, array $identifier): array
{
krexx($identifier);
if ($identifier['type'] === 'tca' && $identifier['tableName'] === 'tt_content' && $identifier['dataStructureKey'] === 'ancfiles_ncdownloads,list') {
$file = PATH_site . 'typo3conf/ext/ancextension/Configuration/FlexForms/Extensions/fluid_styled_content/fluidContent.xml';
$content = file_get_contents($file);
if ($content) {
$dataStructure['sheets']['extraEntry'] = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($content);
}
krexx($dataStructure['sheets']['extraEntry']);
}
return $dataStructure;
}
}
nützlich ist hier den krexx sich auszugeben, damit es nicht lange schwirigkeiten gibt den dataStructureKey zufinden
- Configuration/FlexForms/Extensions/fluid_styled_content/fluidContent.xml
<extra>
<ROOT>
<TCEforms>
<sheetTitle>Fo</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<settings.postsPerPage>
<TCEforms>
<label>Max. number of posts to display per page</label>
<config>
<type>input</type>
<size>2</size>
<eval>int</eval>
<default>3</default>
</config>
</TCEforms>
</settings.postsPerPage>
</el>
</ROOT>
</extra>
Sonstiges
Indexed Search
Extension indexieren lassen von indexed_search
ext_localconf.php
$pluginSignature = 'Beispielplugin';
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Firma.' . $_EXTKEY,
$pluginSignature,
array(
'Controllername' => 'list',show,
)
// non-cacheable actions
array(
'Controllername' => 'list',
)
;
...
if (!is_array($TYPO3_CONF_VARS['SYS']['caching']['cacheConfigurations']['beispielextension_extCache'])) {
$TYPO3_CONF_VARS['SYS']['caching']['cacheConfigurations']['beispielextension_extCache'] = array();
}
...