effiana/jsonform

将 Symfony 表单转换为 Json Schema 的库

v1.0.2 2020-01-21 11:14 UTC

This package is auto-updated.

Last update: 2024-09-27 18:44:01 UTC


README

Liform 是一个将 Symfony 表单序列化为 JSON schema 的库。它可以与 liform-reactjson-editor 一起使用,或者任何基于 json-schema 的其他表单生成器。

它被 LiformBundle 使用,但也可以作为独立的库使用。

维护后端表单以匹配客户端技术(如 JavaScript)中的表单非常烦人。维护此类表单的文档也很烦人。而且很容易出错。

Liform 生成一个 JSON schema 表示,作为文档使用,并可用于文档化、验证数据,如果您想的话,还可以使用生成器生成表单。

Build Status Latest Stable Version Latest Unstable Version License

安装

打开控制台,进入您的项目目录,并执行以下命令以下载此库的最新稳定版本

$ 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