class RelatedServicesPlugin(CMSPlugin): # NOTE: This one does NOT subclass NewsBlogCMSPlugin. This is because this # plugin can really only be placed on the article detail view in an apphook. cmsplugin_ptr = models.OneToOneField( CMSPlugin, on_delete=models.CASCADE, related_name='+', parent_link=True) title = models.CharField(max_length=255, blank=True, verbose_name=_('Title')) icon = Icon(blank=False, default='') image = FilerImageField(on_delete=models.SET_NULL, null=True, blank=True, related_name='+') count = models.PositiveSmallIntegerField(verbose_name=_('Number services')) layout = models.CharField(max_length=30, verbose_name=_('layout')) background_color = RGBColorField(verbose_name=_('Background Color'), blank=True, null=True) full_screen = models.BooleanField(_('Show full screen'), default=False) related_services = SortedManyToManyField('js_services.Service', verbose_name=_('related services'), blank=True, symmetrical=False) related_sections = SortedManyToManyField(ServicesConfig, verbose_name=_('related sections'), blank=True, symmetrical=False) related_people = SortedManyToManyField(Person, verbose_name=_('key people'), blank=True, symmetrical=False) related_categories = SortedManyToManyField('aldryn_categories.Category', verbose_name=_('related categories'), blank=True, symmetrical=False) def copy_relations(self, oldinstance): self.related_services.set(oldinstance.related_services.all()) self.related_sections.set(oldinstance.related_sections.all()) self.related_people.set(oldinstance.related_people.all()) self.related_categories.set(oldinstance.related_categories.all()) if IS_THERE_COMPANIES: self.related_companies.set(oldinstance.related_companies.all()) def __str__(self): return str(self.pk)
class Counter(CMSPlugin): body = models.CharField(_('Title'), max_length=255, null=True, blank=True) counter = models.CharField(_('counter'), max_length=255) image = FilerImageField( verbose_name=_('Image'), blank=True, null=True, on_delete=models.SET_NULL, related_name='+', ) icon = Icon(verbose_name=_('Icon'), null=True, blank=True) prefix = models.CharField(_('prefix'), max_length=255, null=True, blank=True) suffix = models.CharField(_('suffix'), max_length=255, null=True, blank=True) content = HTMLField(verbose_name=_('Content'), default='', blank=True) layout = models.CharField(blank=True, default='', max_length=60, verbose_name=_('layout')) def __str__(self): return str(self.pk)
class RelatedPeoplePlugin(CMSPlugin): # NOTE: This one does NOT subclass NewsBlogCMSPlugin. This is because this # plugin can really only be placed on the article detail view in an apphook. cmsplugin_ptr = models.OneToOneField( CMSPlugin, on_delete=models.CASCADE, related_name='+', parent_link=True) title = models.CharField(max_length=255, blank=True, verbose_name=_('Title')) icon = Icon(blank=False, default='') image = FilerImageField(on_delete=models.SET_NULL, null=True, blank=True, related_name="main_image") number_of_people = models.PositiveSmallIntegerField(verbose_name=_('Number of people')) layout = models.CharField(max_length=30, verbose_name=_('layout')) related_people = SortedManyToManyField(Person, verbose_name=_('key people'), blank=True, symmetrical=False) related_groups = SortedManyToManyField(Group, verbose_name=_('related groups'), blank=True, symmetrical=False) related_locations = SortedManyToManyField('js_locations.Location', verbose_name=_('related locations'), blank=True, symmetrical=False) related_categories = SortedManyToManyField('aldryn_categories.Category', verbose_name=_('related categories'), blank=True, symmetrical=False) related_services = SortedManyToManyField('js_services.Service', verbose_name=_('related services'), blank=True, symmetrical=False) more_button_is_shown = models.BooleanField(blank=True, default=False, verbose_name=_('Show “See More Button”')) more_button_text = models.CharField(max_length=255, blank=True, verbose_name=_('See More Button Text')) more_button_link = models.CharField(max_length=255, blank=True, verbose_name=_('See More Button Link')) def copy_relations(self, oldinstance): self.related_people.set(oldinstance.related_people.all()) self.related_groups.set(oldinstance.related_groups.all()) self.related_locations.set(oldinstance.related_locations.all()) self.related_services.set(oldinstance.related_services.all()) self.related_categories.set(oldinstance.related_categories.all()) if IS_THERE_COMPANIES: self.related_companies.set(oldinstance.related_companies.all()) def __str__(self): return text_type(self.pk)
class RelatedSpeakersPlugin(CMSPlugin): # NOTE: This one does NOT subclass NewsBlogCMSPlugin. This is because this # plugin can really only be placed on the article detail view in an apphook. cmsplugin_ptr = models.OneToOneField(CMSPlugin, on_delete=models.CASCADE, related_name='+', parent_link=True) title = models.CharField(max_length=255, blank=True, verbose_name=_('Title')) icon = Icon(blank=False, default='') image = FilerImageField(on_delete=models.SET_NULL, null=True, blank=True, related_name="related_speakers") number_of_people = models.PositiveSmallIntegerField( verbose_name=_('Number of people')) layout = models.CharField(max_length=30, verbose_name=_('layout'), blank=True, default='', choices=[]) speakers = SortedManyToManyField(Speaker, verbose_name=_('speakers'), blank=True, symmetrical=False) def copy_relations(self, oldinstance): self.speakers.set(oldinstance.speakers.all()) def __str__(self): return get_template_title(RELATED_SPEAKERS_LAYOUTS, self.layout)
class PortfolioItemPluginConfig(PluginAbstractLink): image = FilerImageField(blank=True, null=True, related_name="pfi_image", on_delete=DO_NOTHING) sub_heading = CharField(max_length=100, blank=True, null=True) icon = Icon() def get_short_description(self): return "%s" % self.title
class NewsBlogJSRelatedPlugin(PluginEditModeMixin, AdjustableCacheModelMixin, CMSPlugin): # NOTE: This one does NOT subclass NewsBlogCMSPlugin. This is because this # plugin can really only be placed on the article detail view in an apphook. cmsplugin_ptr = models.OneToOneField(CMSPlugin, related_name='+', parent_link=True) title = models.CharField(max_length=255, blank=True, verbose_name=_('Title')) icon = Icon(blank=False, default='fa-') image = FilerImageField(null=True, blank=True, related_name="title_image") number_of_articles = models.PositiveSmallIntegerField( verbose_name=_('Number of articles'), validators=[django.core.validators.MaxValueValidator(120)]) layout = models.CharField(max_length=30, verbose_name=_('layout')) featured = models.BooleanField(blank=True, default=False) exclude_current_article = models.BooleanField(blank=True, default=False) related_types = SortedManyToManyField(NewsBlogConfig, verbose_name=_('related sections'), blank=True, symmetrical=False) related_categories = SortedManyToManyField( Category, verbose_name=_('related categories'), blank=True, symmetrical=False) related_services = SortedManyToManyField( 'js_services.Service', verbose_name=_('related services'), blank=True, symmetrical=False) related_authors = SortedManyToManyField(Person, verbose_name=_('related authors'), blank=True, symmetrical=False) def copy_relations(self, oldinstance): self.related_types = oldinstance.related_types.all() self.related_categories = oldinstance.related_categories.all() self.related_services = oldinstance.related_services.all() self.related_authors = oldinstance.related_authors.all() # def get_articles(self, article, request): # """ # Returns a queryset of articles that are related to the given article. # """ # languages = get_valid_languages_from_request( # article.app_config.namespace, request) # if self.language not in languages: # return Article.objects.none() # qs = article.related.translated(*languages) # if not self.get_edit_mode(request): # qs = qs.published() # return qs def __str__(self): return ugettext('Related articles')
class CounterModel(CMSPlugin): counter_text = models.CharField(max_length=255, blank=True, null=True) counter_value = models.CharField(max_length=255, blank=True, null=True) icon = Icon(blank=False, default='fa-') image = FilerImageField(null=True, blank=True, related_name="conter_image") def __unicode__(self): return self.counter_text or 'counter'
class Bootstrap4Link(AbstractLink): """ Components > "Button" Plugin https://getbootstrap.com/docs/4.0/components/buttons/ """ link_type = models.CharField( verbose_name=_('Type'), choices=LINK_CHOICES, default=LINK_CHOICES[0][0], max_length=255, help_text=_('Adds either the .btn-* or .text-* classes.'), ) link_context = models.CharField( verbose_name=_('Context'), choices=COLOR_STYLE_CHOICES, blank=True, max_length=255, ) link_size = models.CharField( verbose_name=_('Size'), choices=LINK_SIZE_CHOICES, blank=True, max_length=255, ) link_alignment = models.CharField( verbose_name=_('Alignment'), choices=LINK_ALIGNMENTS, blank=True, max_length=255, ) link_outline = models.BooleanField( verbose_name=_('Outline'), default=False, help_text=_('Applies the .btn-outline class to the elements.'), ) link_block = models.BooleanField( verbose_name=_('Block'), default=False, help_text=_('Extends the button to the width of its container.'), ) icon_left = Icon(verbose_name=_('Icon left'), ) icon_right = Icon(verbose_name=_('Icon right'), ) def __str__(self): return str(self.pk)
class JSLink(CMSPlugin): layout = models.CharField(blank=True, default='', max_length=60, verbose_name=_('layout')) icon = Icon(blank=False, default='fa-') image = FilerImageField(on_delete=models.SET_NULL, null=True, blank=True, related_name="image") text = models.CharField(max_length=255, blank=True) url = models.CharField(max_length=255, blank=True, null=True) file = FilerFileField(verbose_name='File', blank=True, null=True, on_delete=models.SET_NULL, related_name='+') svg = FilerFileField(verbose_name='SVG Image', blank=True, null=True, on_delete=models.SET_NULL, related_name='+') attributes = AttributesField(verbose_name='Attributes', blank=True) def copy_relations(self, oldinstance): self.image = oldinstance.image self.svg = oldinstance.svg def __str__(self): if self.text: return Truncator(strip_tags(self.text)).words(3, truncate="...") elif self.url: return strip_tags(self.url) @property def img_src(self): if self.svg: return self.svg.url elif self.image: return self.image.url return ''
class Bootstrap4GridRow(CMSPlugin): """ Layout > Grid: "Row" Plugin https://getbootstrap.com/docs/4.0/layout/grid/ """ vertical_alignment = models.CharField( verbose_name=_('Vertical alignment'), choices=GRID_ROW_VERTICAL_ALIGNMENT_CHOICES, blank=True, max_length=255, help_text=mark_safe_lazy(_( 'Read more in the <a href="{link}" target="_blank">documentation</a>.') .format(link='https://getbootstrap.com/docs/4.0/layout/grid/#vertical-alignment') ), ) horizontal_alignment = models.CharField( verbose_name=_('Horizontal alignment'), choices=GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES, blank=True, max_length=255, help_text=mark_safe_lazy(_( 'Read more in the <a href="{link}" target="_blank">documentation</a>.') .format(link='https://getbootstrap.com/docs/4.0/layout/grid/#horizontal-alignment') ), ) gutters = models.BooleanField( verbose_name=_('Remove gutters'), default=False, help_text=_('Removes the marginal gutters from the grid.'), ) tag_type = TagTypeField() attributes = AttributesField() background_color = RGBColorField( verbose_name=_('Background Color'), blank=True, null=True ) background_image = FilerImageField( verbose_name=_('Background Image'), null=True, blank=True, related_name='row_bg_image' ) icon = Icon( verbose_name=_('Icon'), null=True, blank=True ) title = models.CharField( verbose_name=_('Title'), null=True, blank=True, max_length=255, ) display_title = models.BooleanField( verbose_name=_('Display Title'), default=False, ) def __str__(self): return str(self.pk) 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 column)', '(%(count)i columns)', column_count ) % {'count': column_count} # column_count_str += ' .{}'.format( # ' .'.join(instance.attributes['class'].split()) # ) return column_count_str
class PromoUnit(CMSPlugin): icon = Icon(verbose_name=_('Icon'), blank=True, default='') image = FilerImageField( verbose_name=_('Image'), blank=True, null=True, on_delete=models.SET_NULL, related_name='+', ) svg = FilerFileField( verbose_name=_('SVG Image'), blank=True, null=True, on_delete=models.SET_NULL, related_name='+', ) file_src = FilerFileField( verbose_name=_('File'), blank=True, null=True, on_delete=models.SET_NULL, related_name='+', ) title = models.CharField( max_length=255, verbose_name=_('Title'), null=True, blank=True, ) subtitle = models.CharField( max_length=255, verbose_name=_('Subtitle'), null=True, blank=True, ) content = HTMLField(verbose_name=_('Content'), default='', blank=True) rollover_content = HTMLField(verbose_name=_('Rollover Content'), default='', blank=True) background_video = models.CharField( max_length=255, verbose_name=_('Background Video'), null=True, blank=True, ) link_url = models.CharField(max_length=255, blank=True, verbose_name=_('Link URL')) link_text = models.CharField(max_length=255, blank=True, verbose_name=_('Link Text')) open_in_new_window = models.BooleanField( default=False, verbose_name=_('Open in new window')) show_filesize = models.BooleanField(default=True, verbose_name=_('Show Filesize')) alignment = models.CharField( verbose_name=_('Alignment'), default='', blank=True, max_length=255, ) layout = models.CharField(blank=True, default='', max_length=60, verbose_name=_('layout')) modal_id = models.CharField( blank=True, default='', max_length=60, verbose_name=_('Modal Id'), help_text=_('Do not include a preceding "#" symbol.'), ) color = RGBColorField(verbose_name=_('Color'), blank=True, null=True) full_height = models.BooleanField(default=False, verbose_name=_('Full Height')) attributes = AttributesField() def __str__(self): return self.title or str(self.pk)
class EventRelatedPlugin(PluginEditModeMixin, AdjustableCacheModelMixin, CMSPlugin): # NOTE: This one does NOT subclass NewsBlogCMSPlugin. This is because this # plugin can really only be placed on the article detail view in an apphook. cmsplugin_ptr = models.OneToOneField(CMSPlugin, on_delete=models.CASCADE, related_name='+', parent_link=True) title = models.CharField(max_length=255, blank=True, verbose_name=_('Title')) icon = Icon(blank=False, default='') image = FilerImageField(on_delete=models.SET_NULL, null=True, blank=True, related_name="related_events_title_image") number_of_items = models.PositiveSmallIntegerField( verbose_name=_('Number of events')) layout = models.CharField(max_length=30, verbose_name=_('layout'), blank=True, default='', choices=[]) time_period = models.CharField(max_length=30, verbose_name=_('Time Period')) featured = models.BooleanField(blank=True, default=False) exclude_current_item = models.BooleanField( blank=True, default=False, verbose_name=_('Exclude current event')) related_types = SortedManyToManyField(EventsConfig, verbose_name=_('related sections'), blank=True, symmetrical=False) related_categories = SortedManyToManyField( Category, verbose_name=_('related categories'), blank=True, symmetrical=False) related_service_sections = SortedManyToManyField( 'js_services.ServicesConfig', verbose_name=_('related service section'), blank=True, symmetrical=False) related_services = SortedManyToManyField( 'js_services.Service', verbose_name=_('related services'), blank=True, symmetrical=False) related_hosts = SortedManyToManyField(Person, verbose_name=_('related hosts'), blank=True, symmetrical=False) related_locations = SortedManyToManyField( 'js_locations.location', verbose_name=_('related locations'), blank=True) more_button_is_shown = models.BooleanField( blank=True, default=False, verbose_name=_('Show “See More Button”')) more_button_text = models.CharField(max_length=255, blank=True, verbose_name=_('See More Button Text')) more_button_link = models.CharField(max_length=255, blank=True, verbose_name=_('See More Button Link')) def copy_relations(self, oldinstance): self.related_types.set(oldinstance.related_types.all()) self.related_categories.set(oldinstance.related_categories.all()) self.related_service_sections.set( oldinstance.related_service_sections.all()) self.related_services.set(oldinstance.related_services.all()) self.related_hosts.set(oldinstance.related_hosts.all()) self.related_locations.set(oldinstance.related_locations.all()) def __str__(self): return ugettext('Related events')
class Bootstrap4Link(AbstractLink): """ Components > "Button" Plugin https://getbootstrap.com/docs/4.0/components/buttons/ """ url_validators = [ LocalORIntranetURLValidator(), ] external_link = models.CharField( verbose_name=_('External link'), blank=True, max_length=2040, validators=url_validators, help_text=_('Provide a link to an external source.'), ) link_type = models.CharField( verbose_name=_('Type'), choices=LINK_CHOICES, default=LINK_CHOICES[0][0], max_length=255, help_text=_('Adds either the .btn-* or .text-* classes.'), ) link_color = RGBColorField(verbose_name=_('Color'), blank=True, null=True) link_context = models.CharField( verbose_name=_('Context'), choices=COLOR_STYLE_CHOICES, blank=True, max_length=255, ) link_size = models.CharField( verbose_name=_('Size'), choices=LINK_SIZE_CHOICES, blank=True, max_length=255, ) link_alignment = models.CharField( verbose_name=_('Alignment'), choices=LINK_ALIGNMENTS, blank=True, max_length=255, ) link_outline = models.BooleanField( verbose_name=_('Outline'), default=False, help_text=_('Applies the .btn-outline class to the elements.'), ) link_block = models.BooleanField( verbose_name=_('Block'), default=False, help_text=_('Extends the button to the width of its container.'), ) modal_id = models.CharField( blank=True, default='', max_length=60, verbose_name=_('Modal Id'), help_text=_('Do not include a preceding "#" symbol.'), ) icon_left = Icon(verbose_name=_('Icon left'), ) icon_right = Icon(verbose_name=_('Icon right'), ) no_link = models.BooleanField( verbose_name=_('No Link'), default=False, ) def __str__(self): return str(self.pk) def get_link(self): if self.no_link: return '' return super(Bootstrap4Link, self).get_link() def clean(self): if not self.no_link: super(Bootstrap4Link, self).clean()