-
Notifications
You must be signed in to change notification settings - Fork 13
/
renderer.py
165 lines (132 loc) · 6.03 KB
/
renderer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from django.forms import (CheckboxInput, CheckboxSelectMultiple, EmailInput, HiddenInput, NumberInput, PasswordInput,
RadioSelect, Textarea, TextInput, Select, SelectMultiple)
from .cms_plugins import SPAPluginMixin
class BaseSPARenderer(object):
"""
Some base data needs to be available for all plugins.
"""
frontend_component_name = ''
plugin_class = None
def render(self, request, plugin, instance=None, editable=False):
context = {
'content': {},
'type': self.frontend_component_name
}
if editable:
# This is the structure of the template `cms/toolbar/plugin.html` that is used to register
# the frontend editing.
context['cms'] = [
'cms-plugin-{}'.format(instance.id),
{
'type': 'plugin',
'page_language': instance.language,
'placeholder_id': instance.placeholder.id,
'plugin_name': str(instance._meta.verbose_name),
'plugin_type': self.plugin_class.__class__.__name__,
'plugin_id': instance.id,
'plugin_language': instance.language,
'plugin_parent': instance.parent.id if instance.parent else None,
'plugin_order': instance.position,
'plugin_restriction': self.plugin_class.get_child_classes(instance.placeholder,
instance.page) or [],
'plugin_parent_restriction': self.plugin_class.get_parent_classes(instance.placeholder,
instance.page) or [],
'onClose': False,
'addPluginHelpTitle': 'Add plugin to {parent_plugin_name}'.format(
parent_plugin_name=instance.get_plugin_name()),
'urls': instance.get_action_urls()
}
]
return context
class MixinPluginRenderer(BaseSPARenderer):
"""
Renders the plugins which use the SPAPluginMixin.
"""
def __init__(self, plugin_class: SPAPluginMixin):
super().__init__()
self.plugin_class = plugin_class
@property
def frontend_component_name(self):
return self.plugin_class.frontend_component_name
def render(self, request, plugin, instance=None, editable=False):
context = super(MixinPluginRenderer, self).render(request, plugin, instance, editable)
return plugin.render_spa(request=request, context=context, instance=instance)
class SPAFormFieldWidgetRenderer(object):
def __init__(self, form, field, name):
self.form = form
self.field = field
self.name = name
def render(self):
context = {
'id': self.name,
'label': str(self.field.label),
'component': self._get_component_name(),
'val': self._get_value_for_field()
}
messages = self._get_messages_for_field()
context['messages'] = messages
state = self._get_state_for_field()
context['state'] = state
if hasattr(self.field.widget, 'input_type'):
context['type'] = self.field.widget.input_type
if self.field.widget.attrs.get('placeholder'):
context['placeholder'] = str(self.field.widget.attrs['placeholder'])
if self.field.widget.attrs.get('spa_attrs'):
context.update(self.field.widget.attrs['spa_attrs'])
try:
widget_context = self.field.widget.render_spa(field=self.field)
except:
widget_context = {}
context.update(widget_context)
return context
def _get_component_name(self):
widget_class = type(self.field.widget)
if issubclass(widget_class, TextInput) or issubclass(widget_class, PasswordInput):
return 'cmp-form-field-input'
elif issubclass(widget_class, NumberInput):
return 'cmp-form-field-input'
elif issubclass(widget_class, EmailInput):
return 'cmp-form-field-input'
elif issubclass(widget_class, CheckboxInput):
return 'cmp-form-field-bool'
elif issubclass(widget_class, CheckboxSelectMultiple):
return 'cmp-form-field-bool'
elif issubclass(widget_class, RadioSelect):
return 'cmp-form-field-bool'
elif issubclass(type(self.field.widget), SelectMultiple):
return 'cmp-form-field-checkbox'
elif issubclass(type(self.field.widget), Textarea):
return 'cmp-form-field-textarea'
elif issubclass(type(self.field.widget), Select):
return 'cmp-form-field-select'
elif issubclass(type(self.field.widget), HiddenInput):
return 'cmp-form-field-hidden'
else:
return ''
def _get_value_for_field(self):
if hasattr(self.form, 'cleaned_data') and self.name in self.form.cleaned_data.keys():
return str(self.form.cleaned_data[self.name])
elif self.name in self.form.data.keys():
return str(self.form.data[self.name])
elif self.name in self.form.initial.keys():
return self.form.initial[self.name]
elif self.field.initial is not None:
return self.field.initial
return ''
def _get_messages_for_field(self):
messages = {}
if self.field.help_text:
messages['info'] = self.field.help_text
if self.name in self.form.errors.keys():
messages['error'] = [str(error.message) for error in self.form.errors[self.name].data]
return messages
def _get_state_for_field(self):
state = {}
if self.field.required:
state['required'] = True
if hasattr(self.field, 'is_disabled') and self.field.is_disabled:
state['disabled'] = True
# Add errors
if self.name in self.form.errors.keys():
state['error'] = True
return state