FluidTYPO3 的 flux 包

安装数: 810 380

依赖项: 29

建议者: 0

安全性: 0

星标: 146

关注者: 5

分支: 212

开放问题: 31

类型:typo3-cms-extension

10.0.10 2024-05-07 11:37 UTC

README

Flux

Coverage Status Documentation Coverage Status Performance profiling sponsored by Blackfire

Flux 自动化 Fluid 与 TYPO3 的集成,使 Fluid 成为开发者的入口点。名称 "Flux" 有多重含义,但在此上下文中,它主要指的是在电子硬件中组装组件时使用的胶状流体,这使得在组件之间创建连接更容易,并提高了连接的耐用性。

Flux 有两个主要目的

  1. 允许开发者通过 Fluid 模板配置 TYPO3 的页面模板和添加自定义内容类型,而无需详细了解 TYPO3 通常如何要求设置此类。
  2. 允许嵌入元数据,例如在编辑内容元素时显示哪些字段、内容或页面模板的描述等。

附加功能:嵌套内容区域以创建内容网格。

文档

工作原理

Flux 有两种主要的工作模式 - 或者您允许 Flux 自动创建一个全站的 "设计" 文件夹来包含您的模板文件,这提供了 100% 的开箱体验。或者您更喜欢更高级、受控的集成,在这种情况下,您将禁用全站模板文件夹的自动创建,并自行提供(通过扩展)。

自动模式是默认设置。 这意味着如果您对如何设置 TYPO3 一无所知,Flux 是一个理想的起点。您可以从自动化开始,随着您对 TYPO3 的了解不断深入,您可以进一步细化集成并不断改进其工作方式。或者,如果自动化适合您的所有需求,您可以继续使用自动化。

要开始,您只需要知道如何安装 TYPO3 扩展,无论是使用 Composer 还是对于非 Composer 网站,都可以通过扩展管理器进行。

集成类型

Flux 有多种方式来存储您的页面和内容模板(这些也是类型定义)

  1. 通过全站 "设计" 文件夹在公共根目录中完全自动化。这种集成使用起来最简单,但强制您的模板在 Flux 的上下文中渲染,并且不便于设置扩展特定的资产存储,并且不如其他方法便携 - 另一方面,它可以直接使用。适用于简单的单域网站,只需几分钟即可开始。
  2. 扩展特定的,意味着您使用一个 TYPO3 扩展(由您自己编写)来存储所有页面和内容模板以及额外的资源,如翻译、图标等。这种方法是最便携的,意味着您可以将整个网站模板打包在一个扩展中,可以重用,并且是唯一允许您将 PHP 类(例如 ViewHelpers)与网站模板一起打包的方法。
  3. 对于内容类型而言,您可以使用根级数据库记录(每个类型一个)来定义新的类型。此方法可以在不触及文件系统的情况下完全使用,但可移植性较低。您可以使用此方法通过TYPO3表单以更直观的方式快速创建内容类型的原型。此方法还具有导出功能,允许您生成可以与任何其他方法一起使用的必要的Fluid模板。

方法1和方法3旨在让您尽快开始。方法2旨在为更复杂的设置服务,这些设置通过使用自定义TYPO3扩展提供不仅仅是网站模板。

三种方法都可以组合使用或单独使用。

Composer安装

推荐!

composer req fluidtypo3/flux
./vendor/bin/typo3 extension:install flux
# alternatively, instead of extension:install, activate in Extension Manager backend module

非Composer安装

不推荐!

  1. 在扩展管理器后端模块中,搜索flux
  2. 选择使用扩展密钥flux安装结果

设置

  • 使用Flux内容类型不需要任何必需的设置(但您几乎肯定需要安装fluid_styled_content才能渲染任何内容)。
  • 要使用没有内容网格的页面模板(假设您已使用pageTSconfig或其他方式定义了一个网格),您只需在编辑页面时在页面布局中选择要使用的模板(从顶级页面开始)。
  • 如果您的页面模板还包含网格,您还必须在外观选项卡的两个后端布局字段中选中从选定的“页面布局”中的列作为值。

剩余的标签、表单字段、网格组成等设置都可以在您的Fluid模板内完成。

它是如何工作的?

当Flux在扩展管理器中安装并启用,并且如果自动创建全局Flux模板已启用(默认情况下是启用的),以下操作将自动执行

  • 在公共目录中创建一个名为design的文件夹(此目录可能在不同的TYPO3版本之间有所不同,可以通过配置进行更改,但在大多数最新版本的TYPO3中,它是项目公共文件夹中的public)。
  • 此文件夹包含一组包含非常基本的嵌入式Flux元数据的骨架模板。
  • design/Templates/Page中创建的文件可以作为页面模板选择(Flux为页面可编辑属性添加了一个页面布局选项卡)。
  • design/Templates/Content中创建的文件成为自定义内容类型,可以像插入标准TYPO3内容类型(如创建文本、图像等)一样插入。

在这些文件夹中重命名、删除或添加文件将自动将这些文件注册为页面模板或内容类型,具体取决于位置。**请注意在重命名或删除文件时的谨慎:如果页面模板或内容模板已在使用中,这可能会破坏您的系统,直到您选择另一个页面模板并禁用/删除已删除或重命名的内容类型。不会对正在使用的类型给出警告!**

从那时起,您可以使用自定义内容类型创建一个完全定制的站点,并使用您喜欢的前端框架(或没有任何框架)制作滑块等,您只需了解非常基本的Fluid(这是一个基于XML标记引擎的标记语言,它为每个可使用的标签提供自动渲染的文档)。

它不做什么?

Flux并没有消除学习“TYPO3方式”的必要性——您仍然应该努力了解更多关于TYPO3如何工作。Flux只是使开始更快,并提供了一定程度的自动化;复杂网站几乎肯定仍然需要您学习一些关于TYPO3的知识(例如,如何修改<meta>部分以及如何使用第三方插件来处理新闻等。)

通量也不是像fluid_styled_content这样的东西的替代品(尽管它可以不使用它而工作)——通量创建自定义内容类型,它不会替换TYPO3的本地内容类型(尽管您可以隐藏这些类型,仅使用自定义类型)。

最后,通量在定义表单字段方面只有有限的抽象。要知道每种类型字段的所有具体细节,您仍然需要了解TYPO3的"TCA"(该文档已经非常详细)。通量尽可能使用与TCA相同的表单字段属性名称。如果您不理解某个属性或者不确定使用哪种字段类型,请始终查阅TCA文档(请记住,并非所有字段类型都适用:通量字段基于FlexForm字段。当FlexForm不支持字段类型时,会在TCA文档中进行说明)。

VHS推荐

VHS是FluidTYPO3家族中的另一个扩展,强烈建议与通量一起使用。VHS在这里被提到的原因是它提供了基于TypoScript的内容和菜单渲染指令的替代方案,允许您使用Fluid。

鉴于TypoScript中特别菜单渲染设置的难度很大(由于结构非常古老,基本上从未改变过),初学者可能更喜欢使用特殊的XHTML标签以及一些CSS类属性,或者自定义循环来输出菜单项及其链接。

通量表单API

通量允许您在Fluid中构建和修改表单,这些表单成为通过TYPO3后端编辑内容/页面属性的表单字段。

<flux:form id="myform">
  <flux:field.input name="myField" label="My special field" />
</flux:form>

通量还允许您为内容元素(嵌套内容区域)构建网格。

<flux:grid>
  <flux:grid.row>
    <flux:grid.column colPos="0" name="main" label="Main content area" />
  </flux:grid.row>
</flux:form>

然后通量能够提取这些嵌入的结构以读取表单字段、标签、内容网格、后端预览输出等——简而言之,您的模板文件嵌入如何集成和渲染模板的指令。

其他API

随着您创建更复杂的项目,它们通常有更复杂的要求——这些要求可能仍然会从通量功能中受益,例如为自定义插件创建通量表单的方式。由于通量通过不断增加对TYPO3核心功能的API的抽象(以Fluid的“风味”为最浓缩和抽象)而工作,通量还宣布这些不断增加的抽象层为公共API。

这意味着通量也有一个老式的PHP方式来声明表单等。

$form = \FluidTYPO3\Flux\Form::create();
$form->setName('myform');
$form->createField('Input', 'myField', 'My special field');

并支持纯数组(以允许JSON等来源)。

$json = '{name: "myform", fields: [{"name": "myField", "type": "Input"}]}';
$asArray = json_decode($json, JSON_OBJECT_AS_ARRAY);
$form = \FluidTYPO3\Flux\Form::create($asArray);

并可以使用TypoScript。

plugin.tx_flux.providers {
  myextension_myplugin {
    tableName = tt_content
    fieldName = pi_flexform
    listType = myextension_myplugin
    extensionKey = Vendor.MyPlugin
    form {
      name = myform
      fields {
        myField {
          type = Input
          label = My special field
        }
      }
    }
  }
}

所有这些都创建了一个具有单个输入字段myField的表单,该字段的标签值为我的特殊字段。最后一个示例显示了嵌套在Provider(另一个通量概念)中的form结构,该Provider将相关tt_content插件记录类型的pi_flexform字段与表单连接起来。

字段值数据转换

通量能够在将值分配为模板变量之前转换字段值。您可以使用此功能确保模板中的变量具有正确的类型——您还可以将其用作将选择的外部记录转换为领域模型实例的快速方法。考虑以下示例

<flux:form id="myform">
  <flux:field.input name="myField" label="My special field" transform="boolean" />
</flux:form>

当通量渲染包含此表单的模板时,变量{myField}将被转换为适当的布尔值。

以下转换类型是内置的

  • 字符串
  • 整数(别名:int
  • 布尔(别名:bool
  • 数组(将通过逗号拆分值,例如a,b,c变为['a', 'b', 'c']
  • 浮点数(别名:decimaldouble
  • 文件
  • 文件引用
  • 文件
  • 文件引用

这些类型file等将转换通过IRRE FAL字段添加的文件引用到FileFileReference对象,如果您使用复数形式,则转换为这样的对象的数组。

您还可以指定一个域模型的类名作为 transform 类型。Flux 将尝试使用匹配的仓储来加载该域模型的单个实例。数据库中保存的值必须是相关对象的整数 uid(例如,flux:field.relation 字段类型将保存此类值)。如果您需要从多选字段(如 flux:field.multiRelation)获取多个实例,您必须使用复合转换类型,例如

transform="\TYPO3\CMS\Extbase\Persistence\ObjectStorage<\My\Extension\Domain\Model\MyObject>"

或者,您可以使用自定义容器类代替 ObjectStorage,例如,如果您有一个按特定方式排序对象的迭代器。容器类将接收一个包含域模型实例的数组作为第一个构造函数参数。

transform="\My\Extension\Iterator\SpecialSorter<\My\Extension\Domain\Model\MyObject>"

或者,您可以指定任何接受构造函数参数的类。然后 Flux 将使用数据库值作为构造函数参数创建指定类的实例。例如,使用 \DateTime 作为转换类型,并在数据库中具有 now 的值将导致具有当前日期+时间的 DateTime 实例

transform="\DateTime"

最后,您还可以创建一个实现 FluidTYPO3\Flux\Form\Transformation\DataTransformerInterface 的实现,以支持任何类型的数据转换

<?php
namespace My\Extension\Transformation;

use FluidTYPO3\Flux\Attribute\DataTransformer;
use FluidTYPO3\Flux\Form\ContainerInterface;
use FluidTYPO3\Flux\Form\FieldInterface;
use FluidTYPO3\Flux\Form\FormInterface;
use FluidTYPO3\Flux\Form\Transformation\DataTransformerInterface;

/* PHP 8.0 registration with class attribute. ID must be unique! */
#[DataTransformer('myextension.datatransformer.mytransform')]
class MyTransformer implements DataTransformerInterface
{
    public function canTransformToType(string $type): bool
    {
        // Support transform of any type that begins with "myextension:"
        return strpos($type, 'myextension:') === 0;
    }

    public function getPriority(): int
    {
        // Higher priority means your DataTransformer is checked before others with lower priority.
        return 10;
    }

    /**
     * @var FieldInterface|ContainerInterface $component
     * @var mixed $value
     * @return mixed
     */
    public function transform(FormInterface $component, string $type, $value)
    {
        $converted = null;
        switch ($type) {
            case 'myextension:foo':
                $converted = 'call something to transform $value to one type';
                break;
            case 'myextension:bar':
                $converted = 'call something else to transform $value to another type';
                break;
        }
        return $converted;
    }
}

上述类将支持通过相同类同时支持 transform="myexternsion:foo"transform="myextension:bar"。显然,数据转换器也可以只支持单一类型。

您可以通过从 getPriority 方法返回更高的数字来覆盖其他数据转换器或为支持相同类型的自己的数据转换器提供优先级。

关于 PHP 7.4 的特殊说明

由于 PHP 7.4 不支持 PHP 8.0 和以上版本的属性,您需要在扩展的 Configuration/Services.yaml 中手动指定类的 DI 标签

services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  My\Extension\:
    resource: '../Classes/*'

  My\Extension\Transformation\MyTransformer:
    tags:
      - name: flux.datatransformer
        identifier: 'myextension.datatransformer.mytransform'

在 PHP 8.0+ 中这不是必需的,因为 DI 容器将扫描 #[DataTransformer('id')] 属性并将您的类自动标记为 Flux 的数据转换器。

Flux 功能亮点

  • 为内容元素添加了新功能 - 将内容网格(遵循 backend_layout 方法)添加到任何内容/插件。
  • 多个 API 用于从许多不同的上下文访问相同的功能,使用相同的命名和嵌套样式。
  • 多个 API 抽象级别 - 当您需要更多控制时,可以在您的代码中使用较低的 API 抽象级别。
  • 灵活地替换单个部分:模板、控制器操作等。
  • 操作现有表单的属性 - 改变字段标签、默认值、添加字段、表格等。
  • 数据类型转换 - 定义所需的目标类型,并让 Extbase 的 TypeConverters 处理转换。
  • 为您的自定义组件提供可能 - 使用相同的 API 支持任何其他 Flux 组件。
  • 为与 Fluid 的高级集成提供几个 Utility 类。

注意事项

  • 请记住,正确配置您的 PHP/HTTP 以接受相当多的输入字段。当嵌套部分/对象时,提交的字段数量会急剧增加。需要考虑的 php.ini 配置设置是 max_input_vars。如果这个数字太小,那么 TYPO3 后端(作为 PHP)将拒绝提交后端编辑表单,并以“无效的 CSRF Token”消息退出,因为 POST 数据不完整(被截断)。
  • 当与自定义提供程序类一起工作时:1)确保您在扩展的服务配置中将每个提供程序类声明为 public: true。2)如果提供程序需要用于多个特定的页面/内容/记录类型,请确保还将提供程序声明为 shared: false。您可以在 Flux 的 Configuration/Services.yaml 文件中找到一个此类配置的示例。
  • 当与自定义控制器类一起工作时,确保在扩展的服务配置中将每个控制器类声明为public: true
  • 请注意,提供者和控制器都使用依赖项的构造函数注入。如果您使用自定义控制器和/或提供者,并且这些类覆盖了__construct方法,请确保它们接受与父类相同的参数,并在您的覆盖的__construct方法中使用这些参数调用parent::__construct()