orange-hive/simplyment

为TYPO3开发者简化开发

安装: 497

依赖项: 0

建议者: 0

安全: 0

星标: 6

关注者: 3

分叉: 0

开放问题: 0

类型:typo3-cms-extension

2.0.1 2024-07-15 11:55 UTC

This package is auto-updated.

Last update: 2024-09-18 07:26:29 UTC


README

本扩展的目标是减少在配置、设置和跳转于TYPO3扩展代码以执行常见任务上所花费的时间。
通过约定存储位置(例如后端布局)或使用类和属性的PHP属性来简化扩展的开发。
将更多时间集中在有趣的方面,如编写逻辑,并加快开发速度!

要求

  • PHP 8.0或更高版本
  • TYPO3 11.5

安装

  • 使用Composer安装扩展 - 依赖项名称:orange-hive/simplyment

配置

在加载用于定义页面配置typoscript的静态typoscript之前,将静态“Simplyment”包含到您的模板中
如果您想使用Simplyment的后端布局和前端模板加载。这已经定义了页面=PAGE,并使用了10 = FLUIDTEMPLATE。
如果您想自己定义页面对象,可以使用基于后端布局名称的模板自动加载
使用以下代码为templateName

templateName < simplyment.page.resolveTemplateName

将以下代码添加到您的扩展中 - 就这么简单!

  • 文件:Configuration/Services.yaml
services:
  MyVendorName\MyExtensionKey:
    tags:
      - name: simplyment

或者,您可以选择跳过在Configuration/Services.yaml中的注册,并手动注册您的扩展以用于Simplyment

  • 文件:ext_localconf.php
\OrangeHive\Simplyment\Loader::extLocalconf(
  vendorName: 'MyVendorName',
  extensionName: 'my_extension_key'
);
  • 文件:ext_tables.php
\OrangeHive\Simplyment\Loader::extTables(
  vendorName: 'MyVendorName',
  extensionName: 'my_extension_key'
);

作为第三个参数,您可以将loaders作为包含您想要使用的加载器的数组添加。如果没有定义加载器,则将使用所有加载器。

使用方法

后端布局

加载器:BackendLayoutLoader

您可以通过创建扩展名为.ts、.tsconfig、.typoscript或.txt的TypoScript文件来创建后端布局定义
在您的扩展目录EXT:<MY_EXTENSION>\Resources\Private\BackendLayouts中。
文件名必须写成lower_snake_case。
在文件中使用以下结构

{
    title = My title
    description = My template description
    icon = EXT:my_extension/Resources/Public/Images/BackendLayouts/default.png
    config {
        backend_layout {
            colCount = 1
            rowCount = 1
            rows {
                1 {
                    columns {
                        1 {
                            name = LLL:EXT:my_extension/Resources/Private/Language/locallang_be.xlf:backend_layout.column.normal
                            colPos = 0
                        }
                    }
                }
            }
        }
    }
}

对于titledescription属性,您可以使用LLL-notation来使用本地化翻译。

前端模板由您的TemplatesRootPath目录自动确定。
您的模板文件名必须与后端布局文件名相同,但使用UpperCamelCase代替lower_snake_case!


插件

加载器:PluginLoader

您可以直接在ActionController上使用PHP属性Plugin来注册新的插件。您可以通过在动作方法上添加PHP属性PluginAction来添加插件操作。

向您的插件添加FlexForm

您可以使用在Plugin PHP属性中的flexFormPath属性轻松地将FlexForm添加到插件中。此属性的值必须是一个以EXT:开头的字符串,并定义了FlexForm XML文件的路径。如果没有定义FlexForm,Simplyment会尝试在位置EXT:my_extension/Configuration/FlexForms/MyPluginName.xml中找到FlexForm文件,并自动添加此文件。

要使用此功能,请将以下代码添加到您的扩展中的TCA/Overrides/tt_content.php文件

\OrangeHive\Simplyment\Loader::tcaTtContentOverrides('MyVendorName', 'my_extension_key');

数据库模型

加载器:DatabaseModelLoader

使用PHP属性DatabaseTable注册新的数据库模型。应将PHP属性DatabaseField定义的字段类型应用于模型应持久化到数据库表的属性。

要生成TCA,请将PHP属性TcaField添加到您的属性中。
您还可以将PHP属性Tca添加到您的类中,以定义以下选项

  • 图标:包含模型自定义图标路径的字符串,如果没有提供,则使用Simplyment扩展图标
  • allowOnStandardPage:布尔值 - 允许在标准页面上添加表条目,而不仅仅是文件夹中,默认:false
  • config:数组 - 全局TCA配置,可以覆盖此模型的TCA值

对于新数据库模型的TCA配置,如果不存在,则在清除缓存时由Simplyment自动在 配置/TCA/ 中生成TCA文件,包含以下内容

<?php

$base = \OrangeHive\Simplyment\Utility\ModelTcaUtility::getTca(\MyVendor\MyExtension\Domain\Model\MyModel::class);

$custom = [];

\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($base, $custom);


return $base;

注意

\MyVendor\MyExtension\Domain\Model\MyModel 将是模型的完全限定类名。
在数组 $custom 中,您可以覆盖自动生成的TCA配置。


扩展现有表

可以通过在DatabaseTable属性中添加 tableName 属性来扩展现有表。

可以在表中定义为属性(无需任何PHP属性)的现有字段。自定义字段必须接收 DatabaseFieldTcaField PHP属性。示例

<?php

namespace MyVendor\MyExtension\Domain\Model;

use OrangeHive\Simplyment\Attributes\DatabaseField;
use OrangeHive\Simplyment\Attributes\DatabaseTable;
use OrangeHive\Simplyment\Attributes\TcaField;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

#[DatabaseTable(
    tableName: 'pages' // extending table 'pages'
)]
class Page extends AbstractEntity
{

    protected string $title = ''; // already existent field title

    #[DatabaseField(type: 'text')]
    #[TcaField]
    protected string $txMyField; // custom field

    /**
     * @return string
     */
    public function getTitle(): string
    {
        return $this->title;
    }

    /**
     * @return string
     */
    public function getTxMyField(): string
    {
        return $this->txMyField;
    }

}

除了 配置/TCA/ 中的文件外,还会在 配置/TCA/Overrides/ 中创建一个以tableName为文件名的文件。
如果不存在,则在清除缓存时由Simplyment自动生成文件的内容,包含以下内容

<?php

use OrangeHive\Simplyment\Utility\ModelTcaUtility;


$customColumnOverrides = [];
ModelTcaUtility::addColumnTcaOverrides(
    fqcn: (\MyVendor\MyExtension\Domain\Model\MyModel::class,
    tableName: 'givenTableName',
    columnOverrides: $customColumnOverrides
);

ModelTcaUtility::addColumnsToAllTcaTypes(
    fqcn: (\MyVendor\MyExtension\Domain\Model\MyModel::class,
    tableName: 'givenTableName'
);

注意

\MyVendor\MyExtension\Domain\Model\MyModel 将是模型的完全限定类名。
givenTableName 将是DatabaseTable属性中定义的tableName。

您在模型中定义的所有自定义字段将被添加到所有TCA类型中。在 ModelTcaUtility::addColumnsToAllTcaTypes 方法中,您可以使用 fieldsOverride 参数限制要添加的字段(或通过提供自定义数组中的字段来更改顺序)来限制要添加的字段。此外,您可以使用包含以逗号分隔的值的字符串的 typeList 参数来定义字段应仅添加的类型。还可以使用 position 属性定义插入的位置。

逻辑基于 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes (https://docs.typo3.org/m/typo3/reference-coreapi/11.5/en-us/ExtensionArchitecture/HowTo/ExtendingTca/Examples/Index.html)。


与ObjectStorage的关系

对于ObjectStorage关系,如通常在属性上面的文档块中定义ObjectStorage的PHP注解一样编写

/**
 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\MyVendor\MyExtension\Domain\Model\MySubModel>
 */

您可以定义TCA,或者使用具有 typetargetClass 参数的 TcaField 属性。
这将通过反射扫描定义的目标类,并搜索具有您模型类型的属性,从而从您引用的子模型引用该模型。此属性用作TCA中的外键字段。默认情况下,foreign_sortby 设置为 sorting

#[DatabaseField(sql: 'int')]
#[TcaField(
    label: 'Sub models',
    type: TcaFieldTypeEnum::INLINE,
    targetClass: TestSubModel::class
)]
protected ObjectStorage $subModels;

有预定义的类型用于引用FAL文件(TcaFieldTypeEnum::FILE) 、图像(TcaFieldTypeEnum::FILE_IMAGE) 或媒体(TcaFieldTypeEnum::FILE_MEDIA)。

仅通过FAL引用图像的示例

/**
 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
 */
#[DatabaseField(sql: 'int')]
#[TcaField(
    label: 'My images',
    type: TcaFieldTypeEnum::FILE_IMAGE
)]
protected ObjectStorage $images;

自定义内容元素

加载器:ContentElementLoader

必须在您的扩展中的 Classes\Domain\Model\Content 目录中创建自定义内容元素。对于每个自定义内容元素,创建一个新的PHP类并使用PHP属性 ContentElement,并设置属性 name
类必须扩展 TYPO3\CMS\Extbase\DomainObject\AbstractEntity

使用类中的属性定义内容元素字段。您可以重用现有字段。
对于自定义字段,将其作为属性添加,并添加PHP属性 DatabaseField(用于在SQL中生成字段)和 TcaField(用于定义字段的配置)。

对于现有字段,可以通过使用PHP属性 TcaField 来覆盖TCA配置。

如果 TcaField 中没有定义标签,并且属性具有 DatabaseField PHP属性,则使用翻译密钥 LLL:EXT:<MY_EXTENSION>/Resources/Private/Language/locallang.xlf:tt_content.<field_name>

重要

为所有属性添加获取器方法,以便在前端模板中访问这些属性!


为了加载自定义内容元素的TCA配置,请将以下代码添加到 <MY_EXTENSION>\Configuration\TCA\Overrides\tt_content.php

\OrangeHive\Simplyment\Loader::tcaTtContentOverrides('MyVendorName', 'my_extension_key');

注意

如果该文件不存在,则由Simplyment在清除缓存时自动生成。


此外,将以下代码添加到 <MY_EXTENSION>\Configuration\Extbase\Persistence\Classes.php 以自动将自定义内容元素映射到tt_content表

$mapping = \OrangeHive\Simplyment\Loader::classes('##VENDOR_NAME##', '##EXTENSION_KEY##');

$custom = [];

return array_merge($mapping, $custom);

注意

如果该文件不存在,则由Simplyment在清除缓存时自动生成。


自定义内容元素PHP类的示例

<?php

namespace MyVendor\MyExtension\Domain\Model\Content;

use OrangeHive\Simplyment\Attributes\ContentElement;
use OrangeHive\Simplyment\Attributes\DatabaseField;
use OrangeHive\Simplyment\Attributes\TcaField;
use OrangeHive\Simplyment\Enumeration\TcaFieldTypeEnum;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

#[ContentElement(
    name: 'Teaser'
)]
class Teaser extends AbstractEntity
{

    protected string $header = ''; // use already existent header field

    #[TcaField(
        type: TcaFieldTypeEnum::TEXT,
        config: [
            'enableRichtext' => true,
        ]
    )]
    protected string $bodytext = ''; // use already existent bodytext field and define it as type='text' with richtext enabled

    #[TcaField(
        type: TcaFieldTypeEnum::TEXT,
        config: [
            'enableRichtext' => true,
        ]
    )]
    #[DatabaseField(type: 'mediumtext')]
    protected string $txAdditionalText = ''; // create custom field tx_additional_text and define it as type='text' with richtext enabled

    /**
     * @return string
     */
    public function getHeader(): string
    {
        return $this->header;
    }

    /**
     * @return string
     */
    public function getBodytext(): string
    {
        return $this->bodytext;
    }

    /**
     * @return string
     */
    public function getTxAdditionalText(): string
    {
        return $this->txAdditionalText;
    }

}

自定义内容元素的模板文件位于 EXT:<MY_EXTENSION>/Resources/Privat/Templates/Content/。前端模板的名称与PHP类的名称相同,后端模板的名称为PHP类名称加上后缀 Backend
如果文件不存在,则由Simplyment在清除缓存时自动创建带有虚拟内容的这两个文件。


将FlexForm添加到您的自定义内容元素中

您可以使用 ContentElement PHP属性中的 flexFormPath 属性轻松地将FlexForms添加到自定义内容元素中。此属性的值必须是一个以 EXT: 开头的字符串,并定义到您的FlexForm XML文件的路径。如果没有定义FlexForm,Simplyment将尝试在 EXT:my_extension/Configuration/FlexForms/Content/MyContentElementName.xml 位置查找FlexForm文件,并自动添加。

FlexForm将自动添加到您的列的末尾。您可以通过定义以下方式在您的Model中指定位置

#[TcaField(
    type: TcaFieldTypeEnum::FLEX
)]
protected string $piFlexform = '';

要获取Fluid模板中的FlexForm内容,请在您的内容元素模型中添加以下代码的getter

public function getPiFlexform(): array
{
    return \OrangeHive\Simplyment\Utility\FlexFormUtility::xml2array((string)$this->piFlexform);
}

要使用此功能,请将以下代码添加到您的扩展中的TCA/Overrides/tt_content.php文件

\OrangeHive\Simplyment\Loader::tcaTtContentOverrides('MyVendorName', 'my_extension_key');

钩子

加载器:HookLoader

可以通过使用PHP属性 Hook 来注册钩子。定义您的钩子类或方法应该绑定的 identifierkey
示例

namespace OrangeHive\Simplyment\Hook;

use OrangeHive\Simplyment\Attributes\Hook;
use TYPO3\CMS\Backend\View\BackendLayout\DataProviderInterface;

#[Hook(identifier: 'TYPO3_CONF_VARS/SC_OPTIONS/BackendLayoutDataProvider', key: 'simplyment')]
class BackendLayoutDataProvider implements DataProviderInterface
{
 // not relevant
}

将在您的扩展的 ext_localconf.php 中产生以下原生钩子

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['BackendLayoutDataProvider']['simplyment'] = 'OrangeHive\Simplyment\Hook\BackendLayoutDataProvider';

注意

如果未设置 key 属性,则将使用当前时间戳作为键。