Skip to content

Commit

Permalink
[FEATURE] Allow to define custom icon for is site root state
Browse files Browse the repository at this point in the history
Fixes: #221
  • Loading branch information
nhovratov committed Aug 10, 2024
1 parent e6d3748 commit 480b246
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 35 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion Classes/Command/CreateContentBlockCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
name: $contentBlockName,
yaml: $yamlConfiguration,
icon: new ContentTypeIcon(),
iconHideInMenu: new ContentTypeIcon(),
hostExtension: $extension,
extPath: $this->getExtPath($extension, $contentType),
contentType: $contentType
Expand Down
30 changes: 30 additions & 0 deletions Classes/Definition/ContentType/PageIconSet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\ContentBlocks\Definition\ContentType;

/**
* @internal Not part of TYPO3's public API.
*/
final class PageIconSet
{
public function __construct(
public readonly ContentTypeIcon $iconHideInMenu,
public readonly ContentTypeIcon $iconRoot,
) {
}
}
15 changes: 9 additions & 6 deletions Classes/Definition/ContentType/PageTypeDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
*/
final class PageTypeDefinition extends ContentTypeDefinition implements ContentTypeInterface
{
private ContentTypeIcon $typeIconHideInMenu;
private PageIconSet $pageIconSet;

public static function createFromArray(array $array, string $table): PageTypeDefinition
{
$self = new self();
$iconHideInMenu = ContentTypeIcon::fromArray($array['typeIconHideInMenu'] ?? []);
$iconRoot = ContentTypeIcon::fromArray($array['typeIconRoot'] ?? []);
$pageIconSet = new PageIconSet($iconHideInMenu, $iconRoot);
return $self
->withTable($table)
->withIdentifier($array['identifier'])
Expand All @@ -39,22 +42,22 @@ public static function createFromArray(array $array, string $table): PageTypeDef
->withVendor($array['vendor'] ?? '')
->withPackage($array['package'] ?? '')
->withTypeIcon(ContentTypeIcon::fromArray($array['typeIcon'] ?? []))
->withTypeIconHideInMenu(ContentTypeIcon::fromArray($array['typeIconHideInMenu'] ?? []))
->withPageIconSet($pageIconSet)
->withPriority($array['priority'] ?? 0)
->withLanguagePathTitle($array['languagePathTitle'] ?? null)
->withLanguagePathDescription($array['languagePathDescription'] ?? null)
->withGroup($array['group']);
}

public function withTypeIconHideInMenu(ContentTypeIcon $typeIconHideInMenu): self
public function withPageIconSet(PageIconSet $pageIconSet): self
{
$clone = clone $this;
$clone->typeIconHideInMenu = $typeIconHideInMenu;
$clone->pageIconSet = $pageIconSet;
return $clone;
}

public function getTypeIconHideInMenu(): ContentTypeIcon
public function getPageIconSet(): PageIconSet
{
return $this->typeIconHideInMenu;
return $this->pageIconSet;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public function toArray(bool $isRootTable, string $identifier): array
}
$contentType['typeIcon'] = $contentTypeIcon->toArray();
if ($this->contentBlock->getContentType() === ContentType::PAGE_TYPE) {
$contentType['typeIconHideInMenu'] = $this->contentBlock->getIconHideInMenu()->toArray();
$contentType['typeIconHideInMenu'] = $this->contentBlock->getPageIconSet()->iconHideInMenu->toArray();
$contentType['typeIconRoot'] = $this->contentBlock->getPageIconSet()->iconRoot->toArray();
}
$contentType['group'] = $yaml['group'] ?? $this->contentBlock->getContentType()->getDefaultGroup();
if ($this->contentBlock->getContentType() === ContentType::CONTENT_ELEMENT) {
Expand Down
9 changes: 7 additions & 2 deletions Classes/Generator/TcaGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,13 @@ protected function generateTableTca(TableDefinition $tableDefinition, array $bas
$tca['types'][$typeDefinition->getTypeName()] = $this->processTypeDefinition($typeDefinition, $tableDefinition);
if ($tableDefinition->hasTypeField()) {
$tca['ctrl']['typeicon_classes'][$typeDefinition->getTypeName()] = $typeDefinition->getTypeIcon()->iconIdentifier;
if ($typeDefinition instanceof PageTypeDefinition && $typeDefinition->getTypeIconHideInMenu()->iconIdentifier !== '') {
$tca['ctrl']['typeicon_classes'][$typeDefinition->getTypeName() . '-hideinmenu'] = $typeDefinition->getTypeIconHideInMenu()->iconIdentifier;
if ($typeDefinition instanceof PageTypeDefinition) {
if ($typeDefinition->getPageIconSet()->iconHideInMenu->iconIdentifier !== '') {
$tca['ctrl']['typeicon_classes'][$typeDefinition->getTypeName() . '-hideinmenu'] = $typeDefinition->getPageIconSet()->iconHideInMenu->iconIdentifier;
}
if ($typeDefinition->getPageIconSet()->iconRoot->iconIdentifier !== '') {
$tca['ctrl']['typeicon_classes'][$typeDefinition->getTypeName() . '-root'] = $typeDefinition->getPageIconSet()->iconRoot->iconIdentifier;
}
}
}
if ($tableDefinition->getContentType() === ContentType::RECORD_TYPE) {
Expand Down
47 changes: 35 additions & 12 deletions Classes/Loader/ContentBlockLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Symfony\Component\Finder\Finder;
use Symfony\Component\Yaml\Yaml;
use TYPO3\CMS\ContentBlocks\Basics\BasicsService;
use TYPO3\CMS\ContentBlocks\Definition\ContentType\PageIconSet;
use TYPO3\CMS\ContentBlocks\Definition\ContentType\ContentType;
use TYPO3\CMS\ContentBlocks\Definition\ContentType\ContentTypeIcon;
use TYPO3\CMS\ContentBlocks\Definition\Factory\UniqueIdentifierCreator;
Expand Down Expand Up @@ -221,7 +222,7 @@ protected function loadSingleContentBlock(
$yaml = $this->basicsService->applyBasics($yaml);
$iconIdentifier = ContentBlockPathUtility::getIconNameWithoutFileExtension();
$contentBlockIcon = new ContentTypeIcon();
$baseInstruction = new ContentTypeIconResolverInput(
$baseIconInput = new ContentTypeIconResolverInput(
name: $name,
absolutePath: $absolutePath,
extension: $extensionKey,
Expand All @@ -230,29 +231,51 @@ protected function loadSingleContentBlock(
table: $table,
typeName: $typeName
);
$this->iconProcessor->addInstruction($contentBlockIcon, $baseInstruction);
$pageIconHideInMenu = new ContentTypeIcon();
$this->iconProcessor->addInstruction($contentBlockIcon, $baseIconInput);
$pageIconSet = null;
if ($contentType === ContentType::PAGE_TYPE) {
$iconIdentifierHideInMenu = ContentBlockPathUtility::getIconHideInMenuNameWithoutFileExtension();
$pageIconHideInMenuInput = clone $baseInstruction;
$pageIconHideInMenuInput->identifier = $iconIdentifierHideInMenu;
$pageIconHideInMenuInput->suffix = '-hide-in-menu';
$this->iconProcessor->addInstruction(
$pageIconHideInMenu,
$pageIconHideInMenuInput
);
$pageIconSet = $this->constructPageIconSet($baseIconInput);
}
return new LoadedContentBlock(
name: $name,
yaml: $yaml,
icon: $contentBlockIcon,
iconHideInMenu: $pageIconHideInMenu,
hostExtension: $extensionKey,
extPath: $extPath,
contentType: $contentType,
pageIconSet: $pageIconSet,
);
}

protected function constructPageIconSet(ContentTypeIconResolverInput $baseIconInput): ?PageIconSet
{
$pageIconHideInMenuFileName = ContentBlockPathUtility::getIconHideInMenuNameWithoutFileExtension();
$pageIconHideInMenu = $this->createPageIcon($baseIconInput, $pageIconHideInMenuFileName, '-hide-in-menu');

$pageIconRootFileName = ContentBlockPathUtility::getIconRootNameWithoutFileExtension();
$pageIconRoot = $this->createPageIcon($baseIconInput, $pageIconRootFileName, '-root');

$pageIconSet = new PageIconSet(
$pageIconHideInMenu,
$pageIconRoot,
);
return $pageIconSet;
}

protected function createPageIcon(
ContentTypeIconResolverInput $baseIconInput,
string $fileName,
string $suffix,
): ContentTypeIcon {
$pageIcon = new ContentTypeIcon();
$iconIdentifier = $fileName;
$pageIconInput = clone $baseIconInput;
$pageIconInput->identifier = $iconIdentifier;
$pageIconInput->suffix = $suffix;
$this->iconProcessor->addInstruction($pageIcon, $pageIconInput);
return $pageIcon;
}

/**
* @param LoadedContentBlock[] $loadedContentBlocks
*/
Expand Down
21 changes: 15 additions & 6 deletions Classes/Loader/LoadedContentBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace TYPO3\CMS\ContentBlocks\Loader;

use TYPO3\CMS\ContentBlocks\Definition\ContentType\PageIconSet;
use TYPO3\CMS\ContentBlocks\Definition\ContentType\ContentType;
use TYPO3\CMS\ContentBlocks\Definition\ContentType\ContentTypeIcon;
use TYPO3\CMS\ContentBlocks\Definition\Factory\PrefixType;
Expand All @@ -30,10 +31,10 @@ public function __construct(
private readonly string $name,
private readonly array $yaml,
private readonly ContentTypeIcon $icon,
private readonly ContentTypeIcon $iconHideInMenu,
private readonly string $hostExtension,
private readonly string $extPath,
private readonly ContentType $contentType,
private readonly ?PageIconSet $pageIconSet = null,
) {}

public static function fromArray(array $array): LoadedContentBlock
Expand All @@ -42,14 +43,21 @@ public static function fromArray(array $array): LoadedContentBlock
if ($table === '') {
throw new \InvalidArgumentException('Failed to load Content Block: Missing "table".', 1689198195);
}
$contentType = ContentType::getByTable($table);
$pageIconSet = null;
if ($contentType === ContentType::PAGE_TYPE) {
$IconHideInMenu = ContentTypeIcon::fromArray($array['iconHideInMenu'] ?? []);
$iconRoot = ContentTypeIcon::fromArray($array['iconRoot'] ?? []);
$pageIconSet = new PageIconSet($IconHideInMenu, $iconRoot);
}
return new self(
name: (string)($array['name'] ?? ''),
yaml: (array)($array['yaml'] ?? []),
icon: ContentTypeIcon::fromArray($array['icon'] ?? []),
iconHideInMenu: ContentTypeIcon::fromArray($array['iconHideInMenu'] ?? []),
hostExtension: (string)($array['hostExtension'] ?? ''),
extPath: (string)($array['extPath'] ?? ''),
contentType: ContentType::getByTable($table)
contentType: ContentType::getByTable($table),
pageIconSet: $pageIconSet
);
}

Expand All @@ -59,7 +67,8 @@ public function toArray(): array
'name' => $this->name,
'yaml' => $this->yaml,
'icon' => $this->icon->toArray(),
'iconHideInMenu' => $this->iconHideInMenu->toArray(),
'iconHideInMenu' => $this->pageIconSet?->iconHideInMenu->toArray(),
'iconRoot' => $this->pageIconSet?->iconRoot->toArray(),
'hostExtension' => $this->hostExtension,
'extPath' => $this->extPath,
];
Expand Down Expand Up @@ -90,9 +99,9 @@ public function getIcon(): ContentTypeIcon
return $this->icon;
}

public function getIconHideInMenu(): ContentTypeIcon
public function getPageIconSet(): ?PageIconSet
{
return $this->iconHideInMenu;
return $this->pageIconSet;
}

public function getHostExtension(): string
Expand Down
18 changes: 13 additions & 5 deletions Classes/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,19 @@ public static function getContentBlockIcons(ContainerInterface $container): \Arr
'provider' => $icon->iconProvider,
],
];
if ($typeDefinition instanceof PageTypeDefinition && $typeDefinition->getTypeIconHideInMenu()->iconIdentifier !== '') {
$hideInMenuIcon = $typeDefinition->getTypeIconHideInMenu();
$iconConfig[$hideInMenuIcon->iconIdentifier] = [
'source' => $hideInMenuIcon->iconPath,
];
if ($typeDefinition instanceof PageTypeDefinition) {
if ($typeDefinition->getPageIconSet()->iconHideInMenu->iconIdentifier !== '') {
$hideInMenuIcon = $typeDefinition->getPageIconSet()->iconHideInMenu;
$iconConfig[$hideInMenuIcon->iconIdentifier] = [
'source' => $hideInMenuIcon->iconPath,
];
}
if ($typeDefinition->getPageIconSet()->iconRoot->iconIdentifier !== '') {
$rootIcon = $typeDefinition->getPageIconSet()->iconRoot;
$iconConfig[$rootIcon->iconIdentifier] = [
'source' => $rootIcon->iconPath,
];
}
}
$arrayObject->exchangeArray(array_merge($arrayObject->getArrayCopy(), $iconConfig));
}
Expand Down
5 changes: 5 additions & 0 deletions Classes/Utility/ContentBlockPathUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ public static function getIconHideInMenuNameWithoutFileExtension(): string
return 'IconHideInMenu';
}

public static function getIconRootNameWithoutFileExtension(): string
{
return 'IconRoot';
}

public static function getIconPathWithoutFileExtension(): string
{
return self::getPublicFolder() . '/' . self::getIconNameWithoutFileExtension();
Expand Down
6 changes: 6 additions & 0 deletions Documentation/Definition/Assets/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ IconHideInMenu.svg

This is a special icon for Page Types for the "hide in menu" state. The same
logic applies as for the standard Icon.svg.

IconRoot.svg
============

This is a special icon for Page Types for the "is_siteroot" state. The same
logic applies as for the standard Icon.svg.
5 changes: 3 additions & 2 deletions Documentation/Guides/PageTypes/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ Icons for states

Page Types can have special states like disabled or hidden in menu. Depending
on this state, the icon changes or is overlayed with another icon. As for now,
only the "hide in menu" state can be supplied with a custom icon. Put an icon
with the name **IconHideInMenu.svg** inside your Assets folder to use it.
the "hide in menu" and "is site root" states can be supplied via a custom icons.
Put an icon with the name **IconHideInMenu.svg** and one with **IconRoot.svg**
inside your Assets folder to use them.

Processing of page data
=======================
Expand Down

0 comments on commit 480b246

Please sign in to comment.