class AccordionFormMixin(ManageChildrenFormMixin, EntangledModelFormMixin): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={'size': '3', 'style': 'width: 5em !important;'}), label=_("Groups"), help_text=_("Number of groups for this accordion."), ) close_others = BooleanField( label=_("Close others"), initial=True, required=False, help_text=_("Open only one card at a time.") ) first_is_open = BooleanField( label=_("First open"), initial=True, required=False, help_text=_("Start with the first card open.") ) class Meta: untangled_fields = ['num_children'] entangled_fields = {'glossary': ['close_others', 'first_is_open']}
class PanelGroupForm(ManageChildrenFormMixin, ModelForm): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={ 'size': '3', 'style': 'width: 5em;' }), label=_("Panels"), help_text=_("Number of panels for this panel group."))
class TabForm(ManageChildrenFormMixin, ModelForm): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={ 'size': '3', 'style': 'width: 5em !important;' }), label=_("Tabs"), help_text=_("Number of tabs."))
class ProcessBarForm(ManageChildrenFormMixin, ModelForm): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={ 'size': '3', 'style': 'width: 5em;' }), label=_("Steps"), help_text=_("Number of steps for this proceed bar."))
class AccordionForm(ManageChildrenFormMixin, ModelForm): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={ 'size': '3', 'style': 'width: 5em !important;' }), label=_("Groups"), help_text=_("Number of groups for this accordion."))
class CarouselSlidesForm(ManageChildrenFormMixin, ModelForm): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={ 'size': '3', 'style': 'width: 5em !important;' }), label=_('Slides'), help_text=_('Number of slides for this carousel.'), )
class TabSetFormMixin(ManageChildrenFormMixin, EntangledModelFormMixin): num_children = IntegerField( min_value=1, initial=1, widget=NumberInputWidget(attrs={ 'size': '3', 'style': 'width: 5em !important;' }), label=_("Number of Tabs"), help_text=_("Number can be adjusted at any time."), ) justified = BooleanField( label=_("Justified tabs"), required=False, ) class Meta: untangled_fields = ['num_children'] entangled_fields = {'glossary': ['justified']}
class CarouselPlugin(BootstrapPluginBase): name = _("Carousel") default_css_class = 'carousel' default_css_attributes = ('options', ) parent_classes = ['BootstrapColumnPlugin'] render_template = os.path.join('cms', framework, 'carousel.html') default_inline_styles = {'overflow': 'hidden'} default_data_options = {'ride': 'carousel'} partial_fields = ( PartialFormField( '-num-children-', # temporary field, not stored in the database NumberInputWidget(attrs={'size': '2'}), label=_('Number of Slides'), help_text=_('Number of slides for this carousel.')), PartialFormField( 'data_options', MultipleTextInputWidget(['interval', 'pause']), label=_('Carousel Options'), help_text=_('Adjust interval and pause for the carousel.')), PartialFormField( 'options', widgets.CheckboxSelectMultiple(choices=(('slide', _('Animate')), )), label=_('Options'), ), PartialFormField('inline_styles', MultipleInlineStylesWidget(['height']), label=_('Inline Styles'), help_text=_('Height of carousel.')), ) @classmethod def get_identifier(cls, obj): num_cols = obj.get_children().count() return ungettext_lazy('with {0} slide', 'with {0} slides', num_cols).format(num_cols) def save_model(self, request, obj, form, change): wanted_children = int(obj.context['-num-children-']) super(CarouselPlugin, self).save_model(request, obj, form, change) self.extend_children(obj, wanted_children, SlidePlugin)
class PanelGroupPlugin(BootstrapPluginBase): name = _("Panel Group") default_css_class = 'panel-group' parent_classes = ['BootstrapColumnPlugin'] require_parent = True render_template = 'cms/bootstrap3/collapse.html' partial_fields = ( PartialFormField('-num-children-', # temporary field, not stored in the database NumberInputWidget(attrs={ 'style': 'width: 30px;' }), label=_('Number of Panels'), help_text=_('Number of panels for this panel group.') ), ) @classmethod def get_identifier(cls, obj): num_cols = obj.get_children().count() return ungettext_lazy('with {0} panel', 'with {0} panels', num_cols).format(num_cols) def save_model(self, request, obj, form, change): wanted_children = int(obj.context['-num-children-']) super(PanelGroupPlugin, self).save_model(request, obj, form, change) self.extend_children(obj, wanted_children, PanelPlugin)
class CarouselPlugin(BootstrapPluginBase): name = _("Carousel") form = CarouselSlidesForm default_css_class = 'carousel' default_css_attributes = ('options', ) parent_classes = ['BootstrapColumnPlugin', 'SimpleWrapperPlugin'] render_template = 'cascade/bootstrap3/{}/carousel.html' default_inline_styles = {'overflow': 'hidden'} fields = ( 'num_children', 'glossary', ) DEFAULT_CAROUSEL_ATTRIBUTES = {'data-ride': 'carousel'} OPTION_CHOICES = ( ('slide', _("Animate")), ('pause', _("Pause")), ('wrap', _("Wrap")), ) interval = GlossaryField( NumberInputWidget(attrs={ 'size': '2', 'style': 'width: 4em;', 'min': '1' }), label=_("Interval"), initial=5, help_text=_("Change slide after this number of seconds."), ) options = GlossaryField( widgets.CheckboxSelectMultiple(choices=OPTION_CHOICES), label=_('Options'), initial=['slide', 'wrap', 'pause'], help_text=_("Adjust interval for the carousel."), ) container_max_heights = GlossaryField( MultipleCascadingSizeWidget(list( tp[0] for tp in settings.CMSPLUGIN_CASCADE['bootstrap3']['breakpoints']), allowed_units=['px']), label=_("Carousel heights"), initial=dict( (bp[0], '{}px'.format(100 + 50 * i)) for i, bp in enumerate( settings.CMSPLUGIN_CASCADE['bootstrap3']['breakpoints'])), help_text= _("Heights of Carousel in pixels for distinct Bootstrap's breakpoints." ), ) resize_options = GlossaryField( widgets.CheckboxSelectMultiple( choices=BootstrapPicturePlugin.RESIZE_OPTIONS), label=_("Resize Options"), help_text=_("Options to use when resizing the image."), initial=['upscale', 'crop', 'subject_location', 'high_resolution']) def get_form(self, request, obj=None, **kwargs): utils.reduce_breakpoints(self, 'container_max_heights', request) return super(CarouselPlugin, self).get_form(request, obj, **kwargs) @classmethod def get_identifier(cls, obj): identifier = super(CarouselPlugin, cls).get_identifier(obj) num_cols = obj.get_children().count() content = ungettext_lazy('with {0} slide', 'with {0} slides', num_cols).format(num_cols) return format_html('{0}{1}', identifier, content) @classmethod def get_css_classes(cls, obj): css_classes = super(CarouselPlugin, cls).get_css_classes(obj) if 'slide' in obj.glossary.get('options', []): css_classes.append('slide') return css_classes @classmethod def get_html_tag_attributes(cls, obj): attributes = super(CarouselPlugin, cls).get_html_tag_attributes(obj) attributes.update(cls.DEFAULT_CAROUSEL_ATTRIBUTES) attributes['data-interval'] = 1000 * int( obj.glossary.get('interval', 5)) options = obj.glossary.get('options', []) attributes['data-pause'] = 'pause' in options and 'hover' or 'false' attributes['data-wrap'] = 'wrap' in options and 'true' or 'false' return attributes def save_model(self, request, obj, form, change): wanted_children = int(form.cleaned_data.get('num_children')) super(CarouselPlugin, self).save_model(request, obj, form, change) self.extend_children(obj, wanted_children, CarouselSlidePlugin) @classmethod def sanitize_model(cls, obj): sanitized = super(CarouselPlugin, cls).sanitize_model(obj) complete_glossary = obj.get_complete_glossary() # fill all invalid heights for this container to a meaningful value max_height = max(obj.glossary['container_max_heights'].values()) pattern = re.compile(r'^(\d+)px$') for bp in complete_glossary.get('breakpoints', ()): if not pattern.match(obj.glossary['container_max_heights'].get( bp, '')): obj.glossary['container_max_heights'][bp] = max_height return sanitized