Skip to content

Commit

Permalink
[WIP][FEATURE] Add support for extbase plugins
Browse files Browse the repository at this point in the history
@todo:
- Integrate into make:content-block
- Allow to set a custom (layout) template in Frontend.html
- Documentation
  • Loading branch information
nhovratov committed Feb 3, 2024
1 parent 242408f commit 8660c3c
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 12 deletions.
3 changes: 2 additions & 1 deletion Classes/Command/CreateContentBlockCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
iconProvider: '',
hostExtension: $extension,
extPath: $this->getExtPath($extension, $contentType),
contentType: $contentType
contentType: $contentType,
isPlugin: false,
);

$this->contentBlockBuilder->create($contentBlockConfiguration);
Expand Down
11 changes: 10 additions & 1 deletion Classes/Definition/Factory/Processing/ProcessedContentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,16 @@ public function toArray(bool $isRootTable, string $identifier): array
$contentType['iconProvider'] = $contentTypeIcon->iconProvider;
$contentType['typeIconIdentifier'] = $this->buildTypeIconIdentifier($contentTypeIcon);
if ($this->contentBlock->getContentType() === ContentType::CONTENT_ELEMENT) {
$contentType['group'] = $yaml['group'] ?? $this->contentBlock->getContentType()->getDefaultGroup();
$group = $yaml['group'] ?? '';
if ($group !== '') {
$contentType['group'] = $group;
} else {
if ($this->contentBlock->isPlugin()) {
$contentType['group'] = 'plugins';
} else {
$contentType['group'] = $this->contentBlock->getContentType()->getDefaultGroup();
}
}
$contentType['saveAndClose'] = (bool)($yaml['saveAndClose'] ?? false);
}
return $contentType;
Expand Down
40 changes: 36 additions & 4 deletions Classes/Generator/TypoScriptGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,21 @@ public function __invoke(BootCompletedEvent $event): void

protected function generate(ContentTypeInterface $typeDefinition): string
{
$privatePath = $this->contentBlockRegistry->getContentBlockExtPath($typeDefinition->getName()) . '/' . ContentBlockPathUtility::getPrivateFolder();
$template = ContentBlockPathUtility::getFrontendTemplateFileNameWithoutExtension();
$contentBlock = $this->contentBlockRegistry->getContentBlock($typeDefinition->getName());
$privatePath = $contentBlock->getExtPath() . '/' . ContentBlockPathUtility::getPrivateFolder();

if ($contentBlock->isPlugin()) {
return $this->getTemplateForPlugin($typeDefinition->getTypeName(), $contentBlock->getHostExtension());
}
return $this->getTemplateForContentElement($typeDefinition->getTypeName(), $privatePath);
}

protected function getTemplateForContentElement(string $typeName, string $privatePath): string
{
$template = ContentBlockPathUtility::getFrontendTemplateFileNameWithoutExtension();
return <<<HEREDOC
tt_content.{$typeDefinition->getTypeName()} =< lib.contentBlock
tt_content.{$typeDefinition->getTypeName()} {
tt_content.$typeName =< lib.contentBlock
tt_content.$typeName {
templateName = {$template}
templateRootPaths {
20 = $privatePath/
Expand All @@ -67,4 +76,27 @@ protected function generate(ContentTypeInterface $typeDefinition): string
}
HEREDOC;
}

protected function getTemplateForPlugin(string $typeName, string $extensionName): string
{
$extensionName = $this->convertExtensionName($extensionName);
return <<<HEREDOC
tt_content.$typeName =< lib.contentBlock
tt_content.$typeName {
template = TEXT
template.value = <f:cObject typoscriptObjectPath="tt_content.$typeName.20" data="{data}" table="tt_content" />
20 = EXTBASEPLUGIN
20 {
extensionName = $extensionName
pluginName = $typeName
}
}
HEREDOC;
}

protected function convertExtensionName(string $extensionName): string
{
$extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName)));
return $extensionName;
}
}
11 changes: 9 additions & 2 deletions Classes/Loader/ContentBlockLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ public function loadUncached(): ContentBlockRegistry
if (is_dir($recordTypesFolder)) {
$loadedContentBlocks[] = $this->loadContentBlocksInExtension($recordTypesFolder, $extensionKey, ContentType::RECORD_TYPE);
}
$pluginsFolder = $package->getPackagePath() . ContentBlockPathUtility::getRelativePluginPath();
if (is_dir($pluginsFolder)) {
$loadedContentBlocks[] = $this->loadContentBlocksInExtension($pluginsFolder, $extensionKey, ContentType::CONTENT_ELEMENT, true);
}
}
$loadedContentBlocks = array_merge([], ...$loadedContentBlocks);
$sortByPriority = fn(LoadedContentBlock $a, LoadedContentBlock $b): int => (int)($b->getYaml()['priority'] ?? 0) <=> (int)($a->getYaml()['priority'] ?? 0);
Expand All @@ -132,7 +136,7 @@ public function loadUncached(): ContentBlockRegistry
/**
* @return LoadedContentBlock[]
*/
protected function loadContentBlocksInExtension(string $path, string $extensionKey, ContentType $contentType): array
protected function loadContentBlocksInExtension(string $path, string $extensionKey, ContentType $contentType, bool $isPlugin = false): array
{
$result = [];
$finder = new Finder();
Expand All @@ -149,6 +153,7 @@ protected function loadContentBlocksInExtension(string $path, string $extensionK
$extensionKey,
$contentBlockExtPath,
$editorInterfaceYaml,
$isPlugin,
);
}
return $result;
Expand Down Expand Up @@ -196,6 +201,7 @@ protected function loadSingleContentBlock(
string $extensionKey,
string $extPath,
array $yaml,
bool $isPlugin,
): LoadedContentBlock {
if (!file_exists($absolutePath)) {
throw new \RuntimeException('Content Block "' . $name . '" could not be found in "' . $absolutePath . '".', 1678699637);
Expand All @@ -209,7 +215,7 @@ protected function loadSingleContentBlock(

$yaml = $this->basicsService->applyBasics($yaml);
$iconIdentifier = ContentBlockPathUtility::getIconNameWithoutFileExtension();
$contentBlockIcon = ContentTypeIconResolver::resolve($name, $absolutePath, $extPath, $iconIdentifier, $contentType);
$contentBlockIcon = ContentTypeIconResolver::resolve($name, $absolutePath, $extPath, $iconIdentifier, $contentType, $isPlugin);

return new LoadedContentBlock(
name: $name,
Expand All @@ -219,6 +225,7 @@ protected function loadSingleContentBlock(
hostExtension: $extensionKey,
extPath: $extPath,
contentType: $contentType,
isPlugin: $isPlugin,
);
}

Expand Down
10 changes: 9 additions & 1 deletion Classes/Loader/LoadedContentBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public function __construct(
private readonly string $hostExtension,
private readonly string $extPath,
private readonly ContentType $contentType,
private readonly bool $isPlugin,
) {}

public static function fromArray(array $array): LoadedContentBlock
Expand All @@ -48,7 +49,8 @@ public static function fromArray(array $array): LoadedContentBlock
iconProvider: (string)($array['iconProvider'] ?? ''),
hostExtension: (string)($array['hostExtension'] ?? ''),
extPath: (string)($array['extPath'] ?? ''),
contentType: ContentType::getByTable($table)
contentType: ContentType::getByTable($table),
isPlugin: (bool)($array['isPlugin'] ?? false),
);
}

Expand All @@ -61,6 +63,7 @@ public function toArray(): array
'iconProvider' => $this->iconProvider,
'hostExtension' => $this->hostExtension,
'extPath' => $this->extPath,
'isPlugin' => $this->isPlugin,
];
}

Expand Down Expand Up @@ -121,4 +124,9 @@ public function getContentType(): ContentType
{
return $this->contentType;
}

public function isPlugin(): bool
{
return $this->isPlugin;
}
}
9 changes: 6 additions & 3 deletions Classes/Service/ContentTypeIconResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
*/
class ContentTypeIconResolver
{
public static function resolve(string $name, string $absolutePath, string $extPath, string $identifier, ContentType $contentType): ContentTypeIcon
public static function resolve(string $name, string $absolutePath, string $extPath, string $identifier, ContentType $contentType, bool $isPlugin = false): ContentTypeIcon
{
foreach (['svg', 'png', 'gif'] as $fileExtension) {
$iconPathWithoutFileExtension = ContentBlockPathUtility::getPublicFolder() . '/' . $identifier;
Expand All @@ -51,13 +51,16 @@ public static function resolve(string $name, string $absolutePath, string $extPa
return $contentTypeIcon;
}
$contentTypeIcon = new ContentTypeIcon();
$contentTypeIcon->iconPath = self::getDefaultContentTypeIcon($contentType);
$contentTypeIcon->iconPath = self::getDefaultContentTypeIcon($contentType, $isPlugin);
$contentTypeIcon->iconProvider = SvgIconProvider::class;
return $contentTypeIcon;
}

public static function getDefaultContentTypeIcon(ContentType $contentType): string
public static function getDefaultContentTypeIcon(ContentType $contentType, bool $isPlugin = false): string
{
if ($isPlugin) {
return 'EXT:content_blocks/Resources/Public/Icons/DefaultPluginIcon.svg';
}
$iconPath = match ($contentType) {
ContentType::CONTENT_ELEMENT => 'EXT:content_blocks/Resources/Public/Icons/DefaultContentElementIcon.svg',
ContentType::PAGE_TYPE => 'EXT:content_blocks/Resources/Public/Icons/DefaultPageTypeIcon.svg',
Expand Down
10 changes: 10 additions & 0 deletions Classes/Utility/ContentBlockPathUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ public static function getRelativeRecordTypesPath(): string
return self::getSubDirectoryName() . '/' . self::getRecordTypesFolder();
}

public static function getRelativePluginPath(): string
{
return self::getSubDirectoryName() . '/' . self::getPluginsFolder();
}

public static function getSubDirectoryName(): string
{
return 'ContentBlocks';
Expand All @@ -124,6 +129,11 @@ public static function getRecordTypesFolder(): string
return 'RecordTypes';
}

public static function getPluginsFolder(): string
{
return 'Plugins';
}

public static function getPublicFolder(): string
{
return 'Assets';
Expand Down
1 change: 1 addition & 0 deletions Resources/Public/Icons/DefaultPluginIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8660c3c

Please sign in to comment.