class Bootstrap3ListGroupPlugin(CMSPlugin): """ Component - List group: "Wrapper" Model http://getbootstrap.com/components/#alerts """ add_list_group_class = models.BooleanField( verbose_name='.list-group', default=True, blank=True, help_text=_( 'Adds the list-group and subsequent list-group-item classes.'), ) classes = model_fields.Classes() attributes = AttributesField( verbose_name=_('Attributes'), blank=True, excluded_keys=['class'], ) cmsplugin_ptr = model_fields.CMSPluginField() def get_short_description(self): instance = self.get_plugin_instance()[0] if not instance: return ugettext('<empty>') column_count = len(self.child_plugin_instances or []) column_count_str = ungettext('1 item', '%(count)i items', column_count) % { 'count': column_count } return column_count_str
class Boostrap3JumbotronPlugin(CMSPlugin): """ Component - Jumbotron: Model http://getbootstrap.com/components/#jumbotron """ label = models.CharField( verbose_name=_('Label'), blank=True, max_length=255, ) grid = models.BooleanField( verbose_name=_('Add container'), default=False, blank=True, help_text=_('Adds a ".container" element inside the "Jumbotron" ' 'for use outside of a grid.'), ) classes = model_fields.Classes() attributes = AttributesField( verbose_name=_('Attributes'), blank=True, excluded_keys=['class'], ) cmsplugin_ptr = model_fields.CMSPluginField() def __str__(self): return self.label or str(self.pk)
class Boostrap3BlockquotePlugin(CMSPlugin): """ CSS - Typography: "Blockquote" Model http://getbootstrap.com/css/#type-blockquotes """ reverse = models.BooleanField( verbose_name=_('Reverse quote'), default=False, blank=True, help_text=_('Reverses the position by adding the Bootstrap 3 ' '"blockquote-reverse" class.'), ) classes = model_fields.Classes() attributes = AttributesField( verbose_name=_('Attributes'), blank=True, excluded_keys=['class'], ) cmsplugin_ptr = model_fields.CMSPluginField() def __str__(self): if self.reverse: return '.blockquote-reverse' return ''
class Bootstrap3FilePlugin(CMSPlugin): """ Custom - File: Model """ file = filer.fields.file.FilerFileField( verbose_name=_('File'), null=True, blank=False, on_delete=models.SET_NULL, related_name='+', ) name = model_fields.MiniText( verbose_name=_('Name'), default='', blank=True, ) open_new_window = models.BooleanField( verbose_name=_('Open in new window'), default=False, ) show_file_size = models.BooleanField( verbose_name=_('Show file size'), default=False, ) # common fields icon_left = model_fields.Icon() icon_right = model_fields.Icon() # additional fields classes = model_fields.Classes() attributes = AttributesField( verbose_name=_('Attributes'), blank=True, excluded_keys=['class', 'target'], ) cmsplugin_ptr = model_fields.CMSPluginField() def __str__(self): label = self.name if not label: if self.file_id: label = self.file.label else: label = 'File' return label
class Bootstrap3ButtonPlugin(CMSPlugin, model_fields.LinkMixin): """ CSS - Buttons: "Button/Link" Model http://getbootstrap.com/css/#buttons """ label = models.CharField( verbose_name=_('Display name'), blank=True, default='', max_length=255, ) type = model_fields.LinkOrButton( verbose_name=_('Type'), ) # button specific fields btn_context = model_fields.Context( verbose_name=_('Context'), choices=constants.BUTTON_CONTEXT_CHOICES, default=constants.BUTTON_CONTEXT_DEFAULT, ) btn_size = model_fields.Size( verbose_name=_('Size'), ) btn_block = models.BooleanField( verbose_name=_('Block'), default=False, ) # text link specific fields txt_context = model_fields.Context( verbose_name=_('Context'), choices=constants.TEXT_LINK_CONTEXT_CHOICES, default=constants.TEXT_LINK_CONTEXT_DEFAULT, blank=True, ) # common fields icon_left = model_fields.Icon( verbose_name=_('Icon left'), ) icon_right = model_fields.Icon( verbose_name=_('Icon right'), ) classes = model_fields.Classes() cmsplugin_ptr = model_fields.CMSPluginField() def __str__(self): return self.label
class Bootstrap3CarouselPlugin(CMSPlugin): """ JavaScript - Carousel: "Wrapper" Model http://getbootstrap.com/javascript/#carousel """ STYLE_DEFAULT = 'standard' STYLE_CHOICES = [ (STYLE_DEFAULT, _('Standard')), ] TRANSITION_EFFECT_CHOICES = (('slide', _('Slide')), ) style = models.CharField( verbose_name=_('Style'), choices=STYLE_CHOICES + model_fields.get_additional_styles(), default=STYLE_DEFAULT, max_length=255, ) aspect_ratio = models.CharField( verbose_name=_('Aspect ratio'), choices=constants.ASPECT_RATIO_CHOICES, blank=True, default='', max_length=255, help_text=_('Determines width and height of the image ' 'according to the selected ratio.'), ) transition_effect = models.CharField( verbose_name=_('Transition effect'), choices=TRANSITION_EFFECT_CHOICES, default='', blank=True, max_length=255, ) ride = models.BooleanField( verbose_name=_('Ride'), default=True, help_text=_('Auto-starts animation of the carousel.'), ) interval = models.IntegerField( verbose_name=_('Interval'), default=5000, help_text=_('Time (in milliseconds) between items.'), ) wrap = models.BooleanField( verbose_name=_('Wrap'), default=True, blank=True, help_text=_('Loops carousel animation.'), ) pause = models.BooleanField( verbose_name=_('Pause'), default=True, blank=True, help_text=_('Pauses the carousel on hover.'), ) classes = model_fields.Classes() attributes = AttributesField( verbose_name=_('Attributes'), blank=True, excluded_keys=[ 'class', # data attributes et via settings 'data-ride', 'data-interval', 'data-pause', 'data-wrap' ], ) cmsplugin_ptr = model_fields.CMSPluginField() def __str__(self): data = django.forms.models.model_to_dict(self) data.update( dict( style_label=_('Style'), transition_effect_label=_('Transition effect'), ride_label=_('Ride'), interval_label=_('Interval'), aspect_ratio_label=_('Aspect ratio'), )) fields = [ 'style', 'transition_effect', 'ride', 'interval', 'aspect_ratio', ] if not data['ride']: fields.remove('interval') return ', '.join([ '{key}: {value}'.format(key=data['{}_label'.format(field)], value=data[field]) for field in fields ]) def srcset(self): # more or less copied from image plugin. # TODO: replace with generic sizes/srcset solution items = collections.OrderedDict() if self.aspect_ratio: aspect_width, aspect_height = tuple( [int(i) for i in self.aspect_ratio.split('x')]) else: aspect_width, aspect_height = None, None for device in constants.DEVICES: width = device[ 'width_gutter'] # TODO: should this should be based on the containing col size? width_tag = str(width) if aspect_width is not None and aspect_height is not None: height = int( float(width) * float(aspect_height) / float(aspect_width)) crop = True else: height = 0 crop = False items[device['identifier']] = { 'size': (width, height), 'size_str': '{}x{}'.format(width, height), 'width_str': '{}w'.format(width), # 'subject_location': self.file.subject_location, 'upscale': True, 'crop': crop, 'aspect_ratio': (aspect_width, aspect_height), 'width_tag': width_tag, } return items
class Boostrap3ImagePlugin(CMSPlugin): """ CSS - Images: Model http://getbootstrap.com/css/#images """ file = filer.fields.image.FilerImageField( verbose_name=_('Image'), blank=False, null=True, on_delete=models.SET_NULL, related_name='+', ) alt = model_fields.MiniText( verbose_name=_('Alternative text'), blank=True, default='', ) title = model_fields.MiniText( verbose_name=_('Title'), blank=True, default='', ) use_original_image = models.BooleanField( verbose_name=_('Use original image'), blank=True, default=False, help_text=_('Outputs the raw image without cropping.')) override_width = models.IntegerField( verbose_name=_('Override width'), blank=True, null=True, help_text=_('The image width as number in pixels. ' 'Example: "720" and not "720px".'), ) override_height = models.IntegerField( verbose_name=_('Override height'), blank=True, null=True, help_text=_('The image height as number in pixels. ' 'Example: "720" and not "720px".'), ) aspect_ratio = models.CharField( verbose_name=_('Aspect ratio'), choices=constants.ASPECT_RATIO_CHOICES, blank=True, default='', max_length=255, help_text=_('Determines width and height of the image ' 'according to the selected ratio.'), ) shape = models.CharField( verbose_name=_('Shape'), choices=( ('rounded', '.img-rounded'), ('circle', '.img-circle'), ), default='', blank=True, max_length=255, ) thumbnail = models.BooleanField( verbose_name='.img-thumbnail', default=False, blank=True, help_text=_('Adds the Bootstrap 3 ".img-thumbnail" class.'), ) img_responsive = models.BooleanField( verbose_name='.img-responsive', default=True, blank=True, help_text=_('Adds the Bootstrap 3 ".img-responsive" class.')) attributes = AttributesField( verbose_name=_('Attributes'), blank=True, excluded_keys=['src', 'alt', 'class', 'title'], ) classes = model_fields.Classes() cmsplugin_ptr = model_fields.CMSPluginField() def __str__(self): txt = '' if self.file_id and self.file.label: txt = self.file.label return txt def srcset(self): if not self.file: return [] items = collections.OrderedDict() if self.aspect_ratio: aspect_width, aspect_height = tuple( [int(i) for i in self.aspect_ratio.split('x')]) else: aspect_width, aspect_height = None, None for device in constants.DEVICES: if self.override_width: width = self.override_width else: # TODO: should this should be based on the containing col size? width = device['width_gutter'] width_tag = str(width) if aspect_width is not None and aspect_height is not None: height = int( float(width) * float(aspect_height) / float(aspect_width)) crop = True else: if self.override_height: height = self.override_height else: height = 0 crop = False items[device['identifier']] = { 'size': (width, height), 'size_str': '{}x{}'.format(width, height), 'width_str': '{}w'.format(width), 'subject_location': self.file.subject_location, 'upscale': True, 'crop': crop, 'aspect_ratio': (aspect_width, aspect_height), 'width_tag': width_tag, } return items