TYPO3.CMS 7.6 Schnipsel

Aus Vosp.info
Version vom 11. März 2019, 23:18 Uhr von F (Diskussion | Beiträge) (Axjax Schnittstelle im Backend bereitstellen)
Wechseln zu:Navigation, Suche

typo3 | Typo3 Entwicklereinstellungen | TYPO3 LTS 8

Inhaltsverzeichnis

Allgemeine Theorien

Template / Typoscript Ladereihenfolge

  1. keine ahnung was als erstes geladen,
  2. Basis-Template
  3. 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)
    1. danach die constants/setup der Seite
  4. 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


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>

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);
  • 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);

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[?&nbsp; <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[&nbsp;<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'
);
<?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);
              }
      }	
}


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###)))',
	),
	// ....
),

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


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

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();
}
...