def make_form(fields=None, layout=None, layout_class=None, base_class=None,
              get_form_field=None, name=None, rules=None, **kwargs):
    """
    Make a from according dict data:

    {'fields':[
            {'name':'name', 'type':'str', 'label':'label,
                'rules':{
                        'required':
                        'email'
                        'required:back|front' #back means server side, front means front side
                    }
            ...},
            ...
        ],
    #layout_class should be defined in settings.ini, just like
    #[FORM_LAYOUT_CLASSES]
    #bs3 = '#{appname}.form_help.Bootstrap3Layout'
    #is also can be a Layout Class
    #default is BootstrapLayout
    'layout_class':'bs3',
    'layout':{
        'rows':[
            '-- legend title --',
            'field_name',
            ['group_fieldname', 'group_fieldname']
            {'name':'name', 'colspan':3}
        ],
    }
    'base_class':'form class if not existed, then use Form'
    }

    get_form_field is a callback function, used to defined customized field class
    if has name then it'll be cached
    """
    from uliweb.utils.sorteddict import SortedDict

    get_form_field = get_form_field or (lambda name, f:None)

    #make fields
    props = SortedDict({})
    for f in fields or []:
        if isinstance(f, BaseField):
            props[f.name] = get_form_field(f.name, f) or f
        else:
            props[f['name']] = get_form_field(f['name'], f) or make_field(**f)

    #set other props
    if layout:
        props['layout'] = layout
    if layout_class:
        props['layout_class'] = layout_class
    if rules:
        props['rules'] = rules
    layout_class_args = kwargs.pop('layout_class_args', None)
    if layout_class_args:
        props['layout_class_args'] = layout_class_args

    cls = type(name or 'MakeForm_', (base_class or Form,), props)
    return cls
Make a from according dict data:

    {'fields':[
            {'name':'name', 'type':'str', 'label':'label,
                'rules':{
                        'required':
                        'email'
                        'required:back|front' #back means server side, front means front side
                    }
            ...},
            ...
        ],
    #layout_class should be defined in settings.ini, just like
    #[FORM_LAYOUT_CLASSES]
    #bs3 = '#{appname}.form_help.Bootstrap3Layout'
    #is also can be a Layout Class
    #default is BootstrapLayout
    'layout_class':'bs3',
    'layout':{
        'rows':[
            '-- legend title --',
            'field_name',
            ['group_fieldname', 'group_fieldname']
            {'name':'name', 'colspan':3}
        ],
    }
    'base_class':'form class if not existed, then use Form'
    }

    get_form_field is a callback function, used to defined customized field class
    if has name then it'll be cached