For coders TYPO3 Tech Corner

Manipulate slug fields

Manipulate slug fields

Hide slug edit button

We support a large number of universities and colleges in the TYPO3 environment. What is almost identical in all of these institutions is a large number of editors and deeply nested pages in the CMS. By customizing a slug, anyone could simulate a high-quality page at the root level by assigning a slug "/important" - even if this page is rather unimportant and in the fifth level. This often needs to be prevented.

Unfortunately, it is not possible to hide the "Create new slug" and "Edit slug" buttons for different backend user groups in TYPO3 via TCA. However, we want only "editors in chief" to be able to create (custom) slugs. If it is enough for you to hide one or both buttons via CSS, we have the solution for you here.

You can store this CSS file in your site package, for example:

// Recreate slug .btn.btn-default.t3js-form-field-slug-recreate { display: none; } // Enable slug field .btn.btn-default.t3js-form-field-slug-toggle { display: none; }

You can make CSS loadable via PHP via ext_tables.php:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Backend\Template\ModuleTemplate::class] = ['className' => \In2code\In2template\XClass\Backend\Template\ModuleTemplate::class];

And then we want to show the file for normal editors in a ModuleTemplate.php:

<?php declare(strict_types=1); namespace In2code\In2template\XClass\Backend\Template; use In2code\In2template\Utility\BackendUtility; use TYPO3\CMS\Backend\Template\ModuleTemplate as ModuleTemplateCore; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Class ModuleTemplate * to add an additional css file in backend context to hide the button (enable slug field) * but only for normal editors (supereditor class can be defined) and only for page edit view (not for news or * event view) */ class ModuleTemplate extends ModuleTemplateCore { protected string $file = '../typo3conf/ext/in2template/Resources/Public/Css/Backend/Editor/noslugenable.css'; /** * Don't add stylesheet if this usergroup is added to user * * @var int */ protected int $usergroup = 123; protected function loadStylesheets() { parent::loadStylesheets(); $this->addEditorStylesheet(); } protected function addEditorStylesheet(): void { if ($this->isDefaultEditor() && $this->isPageEditView()) { $this->pageRenderer->addCssFile($this->file); } } protected function isDefaultEditor(): bool { $currentGroupList = BackendUtility::getBackendUserProperties()['usergroup']; return GeneralUtility::inList($currentGroupList, $this->usergroup) === false && BackendUtility::isAdministrator() === false; } protected function isPageEditView(): bool { $edit = GeneralUtility::_GP('edit'); if ($edit !== null) { if (array_key_exists('pages', $edit)) { return array_values($edit['pages'])[0] === 'edit'; } } return false; } }

In this example, the CSS is not included if the user group 123 has been assigned to a user (e.g. editors-in-chief). Also, the CSS is not included when you open a news record for editing, for example, or when you are an administrator.

By the way, a suitable backend utility could look like this:

<?php declare(strict_types=1); namespace In2code\In2template\Utility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; /** * Class BackendUtility */ class BackendUtility { /** * @return array */ public static function getBackendUserProperties(): ?array { $beUserAuthentication = self::getBackendUserAuthentication(); if ($beUserAuthentication !== null) { return $beUserAuthentication->user; } return null; } /** * @return bool */ public static function isAdministrator(): bool { $beUserAuthentication = self::getBackendUserAuthentication(); if ($beUserAuthentication !== null) { return (int)$beUserAuthentication->user['admin'] === 1; } return false; } /** * @return BackendUserAuthentication|null * @SuppressWarnings(PHPMD.Superglobals) */ protected static function getBackendUserAuthentication() { return $GLOBALS['BE_USER']; } }


Hide slug prefix

While the visible prefix in the slug field (e.g. makes sense within the pages, the prefix in extensions (e.g. tx_news_domain_model_news.path_segment) is rather confusing because the path to the detail page is not displayed. We can simply hide this prefix for individual extensions.


/** * Remove slug prefix */ $GLOBALS['TCA']['tx_news_domain_model_news']['columns']['path_segment']['config']['appearance']['prefix'] = \In2code\In2template\Form\SlugPrefix::class . '->getEmptyPrefix';


<?php declare(strict_types=1); namespace In2code\In2template\Form; use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSlug; class SlugPrefix { public function getEmptyPrefix(array $parameters, TcaSlug $reference): string { return ''; } }


"Code faster, look at the time" - does this sound familiar to you?

How about time and respect for code quality? Working in a team? Automated tests?

Join us