Simplicity is key! I think nobody would oppose to this little sentence but in the TYPO3 ecosystem, many things are not very simple – at least not for new users. Even the most popular extensions need a deep knowledge of how to configure them before they can be used. And good documentation is most of time a rare thing!
So why not build an extension that works out of the box and configures itself as far as possible to give users an instant feeling of success? The constants.txt
or setup.txt
TypoScript files of the extensions can contain almost all default settings. But things get difficult if the required configuration depends on dynamic things like page IDs. Then, all hope of simplicity is lost and users have to add the necessary settings themselves again.
Is this really true?
The signal/slot mechanism described in the article about executing scripts after installing an extension provides the tools to get things done. Although, the article is very generic and I would like to go into more detail about how we’ve implemented things in the Aimeos web shop distribution.
The distribution imports some pages from the data.t3d
file and the TYPO3 importer cares about avoiding conflicts with existing pages by reassigning the page IDs. Problems arose after we’ve added some required TypoScript settings for access restricted pages like the “MyAccount” page. In order to redirect to the login form when a user isn’t logged in, you have to configure its page ID. That seems to be impossible at the first glance when the page ID will differ in each TYPO3 installation.
The solution is to look up the page ID from the database dynamically after the extension is installed and generate a constants.txt
file that will then contain the actual page ID. The constants in this file can be used in the TypoScript setup.txt
file afterwards.
But first, you need to make sure your code will be executed automatically after the extension is installed. Remember the steps from the article about executing scripts? The first one was to register your extension for listening to the signal for extension installation:
if (TYPO3_MODE === 'BE') {
$class = 'TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher';
$dispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($class);
$dispatcher->connect(
'TYPO3\\CMS\\Extensionmanager\\Service\\ExtensionManagementService',
'hasInstalledExtensions',
'\\\\',
''
);
}
Please replace <vendor>, <extension>, <classname> and <method> with the strings that fits for your extension. Afterwards, you must implement the method of your class you’ve registered for listening. We use the name of the Aimeos setup class in our example because you can have a look at it’s implementation for reference.
<?php
namespace \;
use \TYPO3\CMS\Core\Utility\GeneralUtility;
use \TYPO3\CMS\Backend\Utility\BackendUtility;
class Setup
{
public function process( $extname = null )
{
if( $extname !== '' ) {
return;
}
$data = '';
$ds = DIRECTORY_SEPARATOR;
$filename = dirname( __DIR__ ) . $ds . 'Configuration' . $ds . 'TypoScript' . $ds . 'constants.txt';
$records = BackendUtility::getRecordsByField( 'pages', 'title', 'My account' );
foreach( $records as $record ) {
$data .= 'config.typolinkLinkAccessRestrictedPages = ' . intval( $record['uid'] ) . "\n";
}
GeneralUtility::writeFile( $filename, $data );
}
}
First we have to ensure that the constants.txt
file is only created if our own extension is installed. Thus, we check for the extension name to filter out all other extension installations.
The TYPO3 backend utilities contains some nice methods to retrieve records from the database with only little effort. For example, you can use the getRecordsByField()
method from the BackendUtility
class to fetch all records from a table where a field matches a certain value. Here we want to get all records where the “title” equals “My account” from the “pages” table.
Make sure you generate valid TypoScript afterwards, including new lines and keep an eye on security by enforcing the types you are expecting! The foreach()
loop is a great way to deal with no records and several returned records too because both can an will happen sooner or later. Don’t throw an exception if something unexpected happens because it may lead to not being able to install your extension at all! It’s better to drop those records and add a message to the log file.
constants.txt
that contains a dynamic value. Instead, you can also define them like “page.myaccount.id = 123” and reference the constants in your setup.txt
with “{$page.myaccount.id}”. This is especially handy to keep your constants.txt
small and if you need the value several times.At last, your extension has to write the TypoScript statements to the constants.txt
file. The GeneralUtiltiy
class from the TYPO3 core contains a little writeFile()
helper function to get this done within one line.
Simple, isn’t it?
These few additional lines can make the difference between an easy installable extension and hours of frustrations bugging your users. I think the little effort during the development of your extension is worth the hours saved later on. Your users will thank you for your work by using your extension more often!
A special thanks for the inspiration to this tutorial goes to Stephan Schuler from netlogix.
Wow, great blog.Thanks Again. Awesome.