|
1 # copyright 2011-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 """This module provide highlevel helpers to avoid uicfg boilerplate |
|
19 for most common tasks such as fields ordering, widget customization, etc. |
|
20 |
|
21 |
|
22 Here are a few helpers to customize *action box* rendering: |
|
23 |
|
24 .. autofunction:: cubicweb.web.uihelper.append_to_addmenu |
|
25 .. autofunction:: cubicweb.web.uihelper.remove_from_addmenu |
|
26 |
|
27 |
|
28 and a few other ones for *form configuration*: |
|
29 |
|
30 .. autofunction:: cubicweb.web.uihelper.set_fields_order |
|
31 .. autofunction:: cubicweb.web.uihelper.hide_field |
|
32 .. autofunction:: cubicweb.web.uihelper.hide_fields |
|
33 .. autofunction:: cubicweb.web.uihelper.set_field_kwargs |
|
34 .. autofunction:: cubicweb.web.uihelper.set_field |
|
35 .. autofunction:: cubicweb.web.uihelper.edit_inline |
|
36 .. autofunction:: cubicweb.web.uihelper.edit_as_attr |
|
37 .. autofunction:: cubicweb.web.uihelper.set_muledit_editable |
|
38 |
|
39 The module also provides a :class:`FormConfig` base class that lets you gather |
|
40 uicfg declaration in the scope of a single class, which can sometimes |
|
41 be clearer to read than a bunch of sequential function calls. |
|
42 |
|
43 .. autoclass:: cubicweb.web.uihelper.FormConfig |
|
44 |
|
45 """ |
|
46 __docformat__ = "restructuredtext en" |
|
47 |
|
48 from six import add_metaclass |
|
49 |
|
50 from logilab.common.deprecation import deprecated |
|
51 from cubicweb.web.views import uicfg |
|
52 |
|
53 |
|
54 ## generic uicfg helpers ###################################################### |
|
55 |
|
56 backward_compat_funcs = (('append_to_addmenu', uicfg.actionbox_appearsin_addmenu), |
|
57 ('remove_from_addmenu', uicfg.actionbox_appearsin_addmenu), |
|
58 ('set_fields_order', uicfg.autoform_field_kwargs), |
|
59 ('hide_field', uicfg.autoform_section), |
|
60 ('hide_fields', uicfg.autoform_section), |
|
61 ('set_field_kwargs', uicfg.autoform_field_kwargs), |
|
62 ('set_field', uicfg.autoform_field), |
|
63 ('edit_inline', uicfg.autoform_section), |
|
64 ('edit_as_attr', uicfg.autoform_section), |
|
65 ('set_muledit_editable', uicfg.autoform_section), |
|
66 ) |
|
67 |
|
68 for funcname, tag in backward_compat_funcs: |
|
69 msg = ('[3.16] uihelper.%(name)s is deprecated, please use ' |
|
70 'web.views.uicfg.%(rtagid)s.%(name)s' % dict( |
|
71 name=funcname, rtagid=tag.__regid__)) |
|
72 globals()[funcname] = deprecated(msg)(getattr(tag, funcname)) |
|
73 |
|
74 |
|
75 class meta_formconfig(type): |
|
76 """metaclass of FormConfig classes, only for easier declaration purpose""" |
|
77 def __init__(cls, name, bases, classdict): |
|
78 if cls.etype is None: |
|
79 return |
|
80 uicfg_afs = cls.uicfg_afs or uicfg.autoform_section |
|
81 uicfg_aff = cls.uicfg_aff or uicfg.autoform_field |
|
82 uicfg_affk = cls.uicfg_affk or uicfg.autoform_field_kwargs |
|
83 for attr_role in cls.hidden: |
|
84 uicfg_afs.hide_field(cls.etype, attr_role, formtype=cls.formtype) |
|
85 for attr_role in cls.rels_as_attrs: |
|
86 uicfg_afs.edit_as_attr(cls.etype, attr_role, formtype=cls.formtype) |
|
87 for attr_role in cls.inlined: |
|
88 uicfg_afs.edit_inline(cls.etype, attr_role, formtype=cls.formtype) |
|
89 for rtype, widget in cls.widgets.items(): |
|
90 uicfg_affk.set_field_kwargs(cls.etype, rtype, widget=widget) |
|
91 for rtype, field in cls.fields.items(): |
|
92 uicfg_aff.set_field(cls.etype, rtype, field) |
|
93 uicfg_affk.set_fields_order(cls.etype, cls.fields_order) |
|
94 super(meta_formconfig, cls).__init__(name, bases, classdict) |
|
95 |
|
96 |
|
97 @add_metaclass(meta_formconfig) |
|
98 class FormConfig: |
|
99 """helper base class to define uicfg rules on a given entity type. |
|
100 |
|
101 In all descriptions below, attributes list can either be a list of |
|
102 attribute names of a list of 2-tuples (relation name, role of |
|
103 the edited entity in the relation). |
|
104 |
|
105 **Attributes** |
|
106 |
|
107 :attr:`etype` |
|
108 which entity type the form config is for. This attribute is **mandatory** |
|
109 |
|
110 :attr:`formtype` |
|
111 the formtype the class tries toc customize (i.e. *main*, *inlined*, or *muledit*), |
|
112 default is *main*. |
|
113 |
|
114 :attr:`hidden` |
|
115 the list of attributes or relations to hide. |
|
116 |
|
117 :attr:`rels_as_attrs` |
|
118 the list of attributes to edit in the *attributes* section. |
|
119 |
|
120 :attr:`inlined` |
|
121 the list of attributes to edit in the *inlined* section. |
|
122 |
|
123 :attr:`fields_order` |
|
124 the list of attributes to edit, in the desired order. Unspecified |
|
125 fields will be displayed after specified ones, their order |
|
126 being consistent with the schema definition. |
|
127 |
|
128 :attr:`widgets` |
|
129 a dictionary mapping attribute names to widget instances. |
|
130 |
|
131 :attr:`fields` |
|
132 a dictionary mapping attribute names to field instances. |
|
133 |
|
134 :attr:`uicfg_afs` |
|
135 an instance of ``cubicweb.web.uicfg.AutoformSectionRelationTags`` |
|
136 Default is None, meaning ``cubicweb.web.uicfg.autoform_section`` is used. |
|
137 |
|
138 :attr:`uicfg_aff` |
|
139 an instance of ``cubicweb.web.uicfg.AutoformFieldTags`` |
|
140 Default is None, meaning ``cubicweb.web.uicfg.autoform_field`` is used. |
|
141 |
|
142 :attr:`uicfg_affk` |
|
143 an instance of ``cubicweb.web.uicfg.AutoformFieldKwargsTags`` |
|
144 Default is None, meaning ``cubicweb.web.uicfg.autoform_field_kwargs`` is used. |
|
145 |
|
146 Examples: |
|
147 |
|
148 .. sourcecode:: python |
|
149 |
|
150 from cubicweb.web import uihelper, formwidgets as fwdgs |
|
151 |
|
152 class LinkFormConfig(uihelper.FormConfig): |
|
153 etype = 'Link' |
|
154 hidden = ('title', 'description', 'embed') |
|
155 widgets = dict( |
|
156 url=fwdgs.TextInput(attrs={'size':40}), |
|
157 ) |
|
158 |
|
159 class UserFormConfig(uihelper.FormConfig): |
|
160 etype = 'CWUser' |
|
161 hidden = ('login',) |
|
162 rels_as_attrs = ('in_group',) |
|
163 fields_order = ('firstname', 'surname', 'in_group', 'use_email') |
|
164 inlined = ('use_email',) |
|
165 |
|
166 """ |
|
167 formtype = 'main' |
|
168 etype = None # must be defined in concrete subclasses |
|
169 hidden = () |
|
170 rels_as_attrs = () |
|
171 inlined = () |
|
172 fields_order = () |
|
173 widgets = {} |
|
174 fields = {} |
|
175 uicfg_afs = None |
|
176 uicfg_aff = None |
|
177 uicfg_affk = None |