Skip to content

Instantly share code, notes, and snippets.

@calien666
Created May 6, 2022 07:28
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save calien666/a51c657a8d602b9cbb7f8f31d4fdb8cc to your computer and use it in GitHub Desktop.
Save calien666/a51c657a8d602b9cbb7f8f31d4fdb8cc to your computer and use it in GitHub Desktop.
New TYPO3 content element generator with ddev command
# place as .ddev/commands/web/newce
#!/usr/bin/env bash
## Description: Creates new content element for TYPO3
## Usage: newce
## Example: "ddev newce"
php .ddev/scripts/newContentElement.php
git add packages/template/.
<?php
// place as .ddev/scripts/newContentElement.php
/**
* Markus Hofmann
* 07.07.21 15:39
* typo3-default-sitepackage
*/
$classLoader = require __DIR__.'/../../vendor/autoload.php';
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(
1,
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_CLI
);
\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader);
ContentElement::run();
/**
* Adds new content element to your TYPO3
* change the default template path, if needed (line 41)
*/
class ContentElement {
public static function run()
{
$tca = $GLOBALS['TCA'];
$actualCe = $tca['tt_content']['types'];
do {
$copyElement = readline('Element to copy: ');
} while (!array_key_exists(trim($copyElement), $actualCe));
do {
$newElement = readline('New element CType (ex: my_new_element): ');
} while (array_key_exists(trim($newElement), $actualCe));
$newElementNameEn = readline('New element name (EN): ');
$newElementNameDe = readline('New element name (DE): ');
$newElementDescriptionEn = readline('New element description (EN): ');
$newElementDescriptionDe = readline('New element description (DE): ');
$templateDir = realpath($GLOBALS['ENV']['TYPO3_PATH_APP']).'/packages/template';
$typoScriptDir = $templateDir . '/Configuration/TypoScript';
$tsConfigDir = $templateDir . '/Configuration/TSconfig';
$overridesDir = $templateDir . '/Configuration/TCA/Overrides';
if (!is_dir($typoScriptDir . '/Elements')) {
mkdir($typoScriptDir . '/Elements', 0774, true);
file_put_contents(
$typoScriptDir . '/setup.typoscript',
sprintf(PHP_EOL.'@import \'%s\''.PHP_EOL, $typoScriptDir . '/Elements/'),
FILE_APPEND
);
}
if (!is_dir($tsConfigDir . '/Elements')) {
mkdir($tsConfigDir . '/Elements', 0774, true);
file_put_contents(
$tsConfigDir . '/page.tsconfig',
sprintf(PHP_EOL.'@import \'%s*.tsconfig\''.PHP_EOL, $tsConfigDir . '/Elements/'),
FILE_APPEND
);
}
if (!is_dir($overridesDir)) {
mkdir($overridesDir, 0774, true);
}
$contentDir = $templateDir . '/Resources/Private/Extensions/Content';
if (!is_dir($contentDir)) {
$contentDir = $templateDir . '/Resources/Private/Extensions/FluidStyledContent';
if (!is_dir($contentDir)) {
mkdir($contentDir, 0774, true);
exec(sprintf(
'rsync -avz %s %s/',
$GLOBALS['ENV']['TYPO3_PATH_APP'].'/private/typo3/sysext/fluid_styled_content/Resources/Private/',
$contentDir
));
if (!file_exists($typoScriptDir . '/Lib/contentElement.typoscript')) {
if (!is_dir($typoScriptDir . '/Lib')) {
mkdir($typoScriptDir . '/Lib', 0774, true);
file_put_contents(
$typoScriptDir . '/setup.typoscript',
sprintf(PHP_EOL.'@import \'%s\''.PHP_EOL, $typoScriptDir . '/Lib/'),
FILE_APPEND
);
}
touch($typoScriptDir . '/Lib/contentElement.typoscript');
file_put_contents(
$typoScriptDir . '/Lib/contentElement.typoscript',
self::$standardFluidElement
);
}
}
}
$oldTemplateName = \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($copyElement);
$newTemplateName = \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($newElement);
file_put_contents(
sprintf(
'%s/Templates/%s.html',
$contentDir,
$newTemplateName
),
file_get_contents(
sprintf(
'%s/Templates/%s.html',
$contentDir,
$oldTemplateName
)
)
);
file_put_contents(
sprintf(
'%s/Elements/%s.typoscript',
$typoScriptDir,
$newTemplateName
),
sprintf(
self::$typoScriptConfig,
$newElement,
$copyElement,
$newTemplateName
)
);
file_put_contents(
sprintf(
'%s/Elements/%s.tsconfig',
$tsConfigDir,
$newTemplateName
),
sprintf(
self::$tsConfig,
$newElement
)
);
file_put_contents(
sprintf(
'%s/tt_content-%s.php',
$overridesDir,
$newElement
),
sprintf(
self::$tcaConfig,
$newElement,
$copyElement
)
);
$llEn = file_get_contents(
$templateDir . '/Resources/Private/Language/locallang.xlf'
);
$newLlEn = str_replace(
'</body>',
sprintf(
self::$locallangEn,
$newElement,
$newElementNameEn,
$newElementDescriptionEn
),
$llEn
);
file_put_contents(
$templateDir . '/Resources/Private/Language/locallang.xlf',
$newLlEn
);
$llDe = file_get_contents(
$templateDir . '/Resources/Private/Language/de.locallang.xlf'
);
$newLlDe = str_replace(
'</body>',
sprintf(
self::$locallangDe,
$newElement,
$newElementNameEn,
$newElementDescriptionEn,
$newElementNameDe,
$newElementDescriptionDe
),
$llDe
);
file_put_contents(
$templateDir . '/Resources/Private/Language/de.locallang.xlf',
$newLlDe
);
exit(0);
}
protected static string $typoScriptConfig = <<<'EOL'
tt_content {
%1$s < .%2$s
%1$s {
templateName = %3$s.html
}
}
EOL;
protected static string $tsConfig = <<<'EOL'
mod.wizards.newContentElement.wizardItems.common {
elements {
%1$s {
iconIdentifier = content-text
title = LLL:EXT:template/Resources/Private/Language/locallang.xlf:%1$s.wizard.title
description = LLL:EXT:template/Resources/Private/Language/locallang.xlf:%1$s.wizard.description
tt_content_defValues {
CType = %1$s
}
}
}
show := addToList(%1$s)
}
EOL;
protected static string $tcaConfig = <<<'EOL'
<?php
declare(strict_types=1);
call_user_func(function () {
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
[
'LLL:EXT:template/Resources/Private/Language/locallang.xlf:backend.elements.%1$s',
'%1$s',
'EXT:template/Resources/Public/Icons/Extension.svg'
],
'CType',
'template'
);
$GLOBALS['TCA']['tt_content']['types']['%1$s'] = $GLOBALS['TCA']['tt_content']['types']['%2$s'];
});
EOL;
protected static string $standardFluidElement = <<<'EOL'
################################################
#### CONTENT ELEMENTS
################################################
lib.contentElement {
templateRootPaths {
100 = EXT:template/Resources/Private/Extensions/FluidStyledContent/Templates/
200 = EXT:template/Resources/Private/Extensions/Container/Templates
}
partialRootPaths {
100 = EXT:template/Resources/Private/Extensions/FluidStyledContent/Partials/
200 = EXT:template/Resources/Private/Extensions/Container/Partials
}
layoutRootPaths {
200 = EXT:template/Resources/Private/Extensions/FluidStyledContent/Layouts/
}
}
EOL;
protected static string $locallangEn = <<<'EOL'
<trans-unit id="%1$s.wizard.title">
<source>%2$s</source>
</trans-unit>
<trans-unit id="backend.elements.%1$s">
<source>%2$s</source>
</trans-unit>
<trans-unit id="%1$s.wizard.description">
<source>%3$s</source>
</trans-unit>
</body>
EOL;
protected static string $locallangDe = <<<'EOL'
<trans-unit id="%1$s.wizard.title">
<source>%2$s</source>
<target>%4$s</target>
</trans-unit>
<trans-unit id="backend.elements.%1$s">
<source>%2$s</source>
<target>%4$s</target>
</trans-unit>
<trans-unit id="%1$s.wizard.description">
<source>%3$s</source>
<target>%5$s</target>
</trans-unit>
</body>
EOL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment