effiana / jsonform
将 Symfony 表单转换为 Json Schema 的库
Requires
- php: ^7.2
- symfony/form: ^4.2 | ^5.0
- symfony/serializer: ^4.2 | ^5.0
- symfony/translation: ^4.2 | ^5.0
README
Liform 是一个将 Symfony 表单序列化为 JSON schema 的库。它可以与 liform-react 或 json-editor 一起使用,或者任何基于 json-schema 的其他表单生成器。
它被 LiformBundle 使用,但也可以作为独立的库使用。
维护后端表单以匹配客户端技术(如 JavaScript)中的表单非常烦人。维护此类表单的文档也很烦人。而且很容易出错。
Liform 生成一个 JSON schema 表示,作为文档使用,并可用于文档化、验证数据,如果您想的话,还可以使用生成器生成表单。
安装
打开控制台,进入您的项目目录,并执行以下命令以下载此库的最新稳定版本
$ composer require limenius/liform
此命令要求您全局安装了 Composer,如 Composer 文档的 安装章节 所述。
Liform 使用其类的 PSR-4 命名约定,这意味着您可以轻松地集成
Liform
类的自动加载。
使用
将表单序列化为 JSON Schema
use Effiana\JsonForm\Resolver; use Effiana\JsonForm\Liform; use Effiana\JsonForm\Liform\Transformer; $resolver = new Resolver(); $resolver->setTransformer('text', Transformer\StringTransformer); $resolver->setTransformer('textarea', Transformer\StringTransformer, 'textarea'); // more transformers you might need, for a complete list of what is used in Symfony // see https://github.com/Limenius/LiformBundle/blob/master/Resources/config/transformers.xml $liform = new Liform($resolver); $form = $this->createForm(CarType::class, $car, ['csrf_protection' => false]); $schema = json_encode($liform->transform($form));
然后 $schema
将包含如下 JSON Schema 表示
{ "title":null, "properties":{ "name":{ "type":"string", "title":"Name", "propertyOrder":1 }, "color":{ "type":"string", "title":"Color", "attr":{ "placeholder":"444444" }, "description":"3 hexadecimal digits", "propertyOrder":2 }, "drivers":{ "type":"array", "title":"hola", "items":{ "title":"Drivers", "properties":{ "firstName":{ "type":"string", "propertyOrder":1 }, "familyName":{ "type":"string", "propertyOrder":2 } }, "required":[ "firstName", "familyName" ], "type":"object" }, "propertyOrder":3 } }, "required":[ "name", "drivers" ] }
使用您自己的转换器
Liform 通过递归检查表单,为每个子项找到(解析)正确的转换器,并使用该转换器构建相应的 json-schema 片段。因此,如果您想修改特定表单类型的转换方式,应设置一个与该 block_prefix
匹配的转换器。
为此,您可以使用 Resolver
类的 setTransformer
方法。在这种情况下,我们重用了 StringTransformer,通过重写 widget 属性并将其设置为 my_widget
来重用,但您也可以使用您自己的转换器,如果喜欢的话
use Effiana\JsonForm\Liform; $stringTransformer = $this->get('liform.transformer.string'); $resolver = $this->get('liform.resolver'); $resolver->setTransformer('file', $stringTransformer, 'file_widget'); $liform = new Liform($resolver);
序列化初始值
此库提供了一种标准化方法,可以将 FormView
(您可以使用 $form->createView()
创建一个)序列化为一组初始值。
use Effiana\JsonForm\Serializer\Normalizer\FormViewNormalizer; $encoders = array(new XmlEncoder(), new JsonEncoder()); $normalizers = array(new FormViewNormalizer()); $serializer = new Serializer($normalizers, $encoders); $initialValues = $serializer->normalize($form),
以获取与您的 json-schema 匹配的初始值数组。
序列化错误
此库提供了一种标准化方法,可以将带有错误的表单序列化为一个数组。这部分内容无耻地借鉴自 FOSRestBundle。要使用此功能,请将以下代码复制到您的控制器操作中
use Effiana\JsonForm\Serializer\Normalizer\FormErrorNormalizer; $encoders = array(new XmlEncoder(), new JsonEncoder()); $normalizers = array(new FormErrorNormalizer()); $serializer = new Serializer($normalizers, $encoders); $errors = $serializer->normalize($form),
以获取包含您表单错误的数组。如果使用 liform-react,它可以理解此格式。
提取到 JSON-schema 的信息
Liform 的目标是尽可能从表单中提取数据,以便在 schema 中有一个完整的表示,包括验证和 UI 提示。目前支持以下选项。
一些数据可以从通常的表单属性中提取,但一些属性将使用传递给表单选项的特殊 liform
数组提供。为此,提供了一个 表单扩展。请参阅 AddLiformExtension.php
必填项
如果字段是必需的(在Symfony中默认如此),它将在模式中体现。
class DummyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someText', Type\TextType::class); } }
{ "title":"dummy", "type":"object", "properties":{ "someText":{ "type":"string", "title":"someText", "propertyOrder":1 } }, "required":[ "someText" ] }
小部件
有时你可能希望以不同于该类型的默认行为来渲染字段。通过使用liform属性,你可以指定一个特定的组件,该组件决定了该字段如何渲染。
如果提供了liform的widget
属性,如下所示
class DummyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someText', Type\TextType::class, [ 'liform' => [ 'widget' => 'my_widget' ] ]); } }
生成的模式将包含该widget
选项
{ "title":"dummy", "type":"object", "properties":{ "someText":{ "type":"string", "widget":"my_widget", "title":"someText", "propertyOrder":1 } }, "required":[ "someText" ] }
标签/标题
如果你提供了label
,它将被用作模式中的标题。
class DummyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someText', Type\TextType::class, [ 'label' => 'Some text', ]); } }
{ "title":"dummy", "type":"object", "properties":{ "someText":{ "type":"string", "title":"Some text", "propertyOrder":1 } }, "required":[ "someText" ] }
模式
如果提供了attr的pattern
属性,如下所示
class DummyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someText', Type\TextType::class, [ 'attr' => [ 'pattern' => '.{5,}', ], ]); } }
它将被提取为pattern
选项,因此可用于验证。请注意,此外,提供给attr的所有内容也将保留。
{ "title":"dummy", "type":"object", "properties":{ "someText":{ "type":"string", "title":"someText", "attr":{ "pattern":".{5,}" }, "pattern":".{5,}", "propertyOrder":1 } }, "required":[ "someText" ] }
描述
如果提供了liform的description
属性,如下所示,它将被提取到模式中
class DummyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someText', Type\TextType::class, [ 'label' => 'Some text', 'liform' => [ 'description' => 'This is a help message', ] ]); } }
{ "title":"dummy", "type":"object", "properties":{ "someText":{ "type":"string", "title":"Some text", "description":"This is a help message", "propertyOrder":1 } }, "required":[ "someText" ] }
许可证
此库受MIT许可证的许可。请参阅文件中的完整许可证
LICENSE.md
致谢
使用解析器和还原器转换表单的技术灵感来源于Symfony Console Form