def get_form(self, request, obj=None, **kwargs): font_choices = IconFont.objects.values_list('id', 'identifier') glossary_fields = ( PartialFormField( 'icon_font', widgets.Select(choices=font_choices), label=_("Font"), ), PartialFormField( 'content', widgets.HiddenInput(), label=_("Select Icon"), ), PartialFormField( 'font-size', widgets.Select(choices=self.SIZE_CHOICES), label=_("Icon Size"), ), PartialFormField( 'text-align', widgets.RadioSelect(choices=(('', _("Do not align")), ('text-left', _("Left")), ('text-center', _("Center")), ('text-right', _("Right")))), label=_("Text Align"), initial='', help_text=_("Align the icon inside the parent column.")), ) kwargs.update(glossary_fields=glossary_fields) form = super(FontIconPlugin, self).get_form(request, obj=obj, **kwargs) return form
class BootstrapAccordionPanelPlugin(TransparentMixin, BootstrapPluginBase): name = _("Accordion Panel") default_css_class = 'panel-body' parent_classes = ('BootstrapAccordionPlugin',) require_parent = True alien_child_classes = True glossary_fields = ( PartialFormField('panel_type', PanelTypeRenderer.get_widget(), label=_("Panel type"), help_text=_("Display Panel using this style.") ), PartialFormField('heading_size', widgets.Select(choices=panel_heading_sizes), initial='', label=_("Heading Size") ), PartialFormField('panel_title', widgets.TextInput(attrs={'size': 80}), label=_("Panel Title") ), ) class Media: css = {'all': ('cascade/css/admin/bootstrap.min.css', 'cascade/css/admin/bootstrap-theme.min.css',)} @classmethod def get_identifier(cls, obj): identifier = super(BootstrapAccordionPanelPlugin, cls).get_identifier(obj) panel_title = HTMLParser().unescape(obj.glossary.get('panel_title', '')) panel_title = Truncator(panel_title).words(3, truncate=' ...') return format_html('{0}{1}', identifier, panel_title)
class RevealSectionPlugin(CascadePluginBase): name = _("Section") module = 'Reveal' render_template = 'reveal/section.html' require_parent = True parent_classes = ('RevealSectionPlugin',) allow_children = True child_classes = None alien_child_classes = True model_mixins = (ImagePropertyMixin,) form = ImageForm raw_id_fields = ('image_file',) glossary_fields = ( PartialFormField('hide', widgets.CheckboxInput(), label=_("Hide this slide") ), PartialFormField('crop', widgets.CheckboxInput(), label=_("Crop image") ), ) @classmethod def get_identifier(cls, instance): identifier = super(RevealSectionPlugin, cls).get_identifier(instance) identifier = "{} {}".format(identifier, instance.get_position_in_placeholder()) if instance.glossary.get('hide'): return format_html('{} hidden', identifier) return identifier
def __init__(self, model=None, admin_site=None): glossary_fields = ( PartialFormField('grid', widgets.Select(choices=self.GRID_CHOICES), label=_('Column Grid'), initial='grid_4', help_text=_("Grid in column units.")), PartialFormField( 'prefix', widgets.Select(choices=self.PREFIX_CHOICES), label=_('Prefix'), ), PartialFormField( 'suffix', widgets.Select(choices=self.SUFFIX_CHOICES), label=_('Suffix'), ), PartialFormField( 'options', widgets.CheckboxSelectMultiple(choices=self.OPTION_CHOICES), label=_('Options'), ), PartialFormField('inline_styles', MultipleCascadingSizeWidget( ['min-height', 'margin-top', 'margin-bottom']), label=_('Inline Styles'), help_text=_('Minimum height for this column.')), ) super(Grid960BasePlugin, self).__init__(model, admin_site, glossary_fields=glossary_fields)
class LinkPluginBase(CascadePluginBase): text_enabled = True allow_children = False parent_classes = [] require_parent = False glossary_fields = ( PartialFormField('target', widgets.RadioSelect(choices=( ('', _("Same Window")), ('_blank', _("New Window")), ('_parent', _("Parent Window")), ('_top', _("Topmost Frame")), )), initial='', label=_("Link Target"), help_text=_("Open Link in other target.")), PartialFormField('title', widgets.TextInput(), label=_("Title"), help_text=_("Link's Title")), ) html_tag_attributes = {'title': 'title', 'target': 'target'} # map field from glossary to these form fields glossary_field_map = { 'link': ( 'link_type', 'cms_page', 'ext_url', 'mail_to', ) } @classmethod def get_link(cls, obj): link = obj.glossary.get('link', {}) linktype = link.get('type') if linktype == 'exturl': return '{url}'.format(**link) if linktype == 'email': return 'mailto:{email}'.format(**link) # otherwise try to resolve by model if 'model' in link and 'pk' in link: if not hasattr(obj, '_link_model'): Model = get_model(*link['model'].split('.')) try: obj._link_model = Model.objects.get(pk=link['pk']) except Model.DoesNotExist: obj._link_model = None if obj._link_model: return obj._link_model.get_absolute_url() def get_ring_bases(self): bases = super(LinkPluginBase, self).get_ring_bases() bases.append('LinkPluginBase') return bases def get_form(self, request, obj=None, **kwargs): kwargs.setdefault('form', LinkForm.get_form_class()) return super(LinkPluginBase, self).get_form(request, obj, **kwargs)
class BootstrapButtonPlugin(LinkPluginBase): module = 'Bootstrap' name = _("Button") form = TextLinkForm model_mixins = (LinkElementMixin,) parent_classes = ['BootstrapColumnPlugin'] render_template = 'cascade/bootstrap3/button.html' allow_children = False text_enabled = True tag_type = None default_css_class = 'btn' default_css_attributes = ('button-type', 'button-size', 'button-options', 'quick-float',) fields = ('link_content', ('link_type', 'cms_page', 'ext_url', 'mail_to'), 'glossary',) glossary_fields = ( PartialFormField('button-type', widgets.RadioSelect(choices=((k, v) for k, v in ButtonTypeRenderer.BUTTON_TYPES.items()), renderer=ButtonTypeRenderer), label=_('Button Type'), initial='btn-default', help_text=_("Display Link using this Button Style") ), PartialFormField('button-size', widgets.RadioSelect(choices=((k, v) for k, v in ButtonSizeRenderer.BUTTON_SIZES.items()), renderer=ButtonSizeRenderer), label=_('Button Size'), initial='', help_text=_("Display Link using this Button Size") ), PartialFormField('button-options', widgets.CheckboxSelectMultiple(choices=(('btn-block', _('Block level')), ('disabled', _('Disabled')),)), label=_('Button Options'), ), PartialFormField('quick-float', widgets.RadioSelect(choices=(('', _("Do not float")), ('pull-left', _("Pull left")), ('pull-right', _("Pull right")),)), label=_('Quick Float'), initial='', help_text=_("Float the button to the left or right.") ), ) + LinkPluginBase.glossary_fields + ( PartialFormField('inline_styles', MultipleCascadingSizeWidget(['margin-top', 'margin-right', 'margin-bottom', 'margin-left'], allowed_units=['px', 'em'], required=False), label=_('Margins'), help_text=_('Margins for this button wrapper.') ), ) class Media: css = {'all': ('cascade/css/admin/bootstrap.min.css', 'cascade/css/admin/bootstrap-theme.min.css',)} @classmethod def get_identifier(cls, obj): identifier = super(BootstrapButtonPlugin, cls).get_identifier(obj) content = obj.glossary.get('link_content') if not content: try: content = force_text(ButtonTypeRenderer.BUTTON_TYPES[obj.glossary['button-type']]) except KeyError: content = _("Empty") return format_html('{0}{1}', identifier, content)
class HeadingPlugin(CascadePluginBase): name = _("Heading") parent_classes = None allow_children = False TAG_CHOICES = tuple((k, _("Heading {}").format(k)) for k in range(1, 7)) glossary_fields = ( PartialFormField('head_size', widgets.Select(choices=TAG_CHOICES)), PartialFormField('content', widgets.TextInput(attrs={}), _("Heading content")), ) render_template = 'cascade/generic/heading.html' class Media: css = {'all': ('cascade/css/admin/partialfields.css', )} @classmethod def get_identifier(cls, instance): head_size = instance.glossary.get('head_size') content = instance.glossary.get('content') if head_size: return format_html('<strong>{0}</strong>: {1}', head_size, content) return content def render(self, context, instance, placeholder): context = super(HeadingPlugin, self).render(context, instance, placeholder) context['glossary'] = instance.glossary return context
class RevealImagePlugin(CascadePluginBase): name = _("Image") module = 'Reveal' model_mixins = (ImagePropertyMixin,) render_template = 'reveal/image.html' require_parent = True parent_classes = ('RevealSectionPlugin', 'SimpleWrapperPlugin',) allow_children = False raw_id_fields = ('image_file',) text_enabled = True admin_preview = False form = ImageForm glossary_fields = ( PartialFormField('image-width', CascadingSizeWidget(allowed_units=['px', '%'], required=False), label=_("Image Width"), help_text=_("Set a fixed image width in pixels."), ), PartialFormField('image-height', CascadingSizeWidget(allowed_units=['px', '%'], required=False), label=_("Image Height"), help_text=_("Set a fixed height in pixels, or percent relative to the image width."), ), ) def render(self, context, instance, placeholder): glossary = dict(instance.get_complete_glossary()) # extra_styles = tags.pop('extra_styles') inline_styles = instance.glossary.get('inline_styles', {}) # inline_styles.update(extra_styles) # instance.glossary['inline_styles'] = inline_styles size = (960, 600) src = {'size': size, 'crop': False} context.update(dict(instance=instance, src=src, placeholder=placeholder)) return context
class HeadingPlugin(CascadePluginBase): name = _("Heading") parent_classes = None allow_children = False TAG_TYPES = tuple( ('h{}'.format(k), _("Heading {}").format(k)) for k in range(1, 7)) glossary_fields = ( PartialFormField('tag_type', widgets.Select(choices=TAG_TYPES)), PartialFormField( 'content', widgets.TextInput(attrs={ 'style': 'width: 350px; font-weight: bold; font-size: 125%;' }), _("Heading content")), ) render_template = 'cascade/generic/heading.html' class Media: css = {'all': ('cascade/css/admin/partialfields.css', )} @classmethod def get_identifier(cls, instance): identifier = super(HeadingPlugin, cls).get_identifier(instance) tag_type = instance.glossary.get('tag_type') content = instance.glossary.get('content') if tag_type: return format_html('<code>{0}</code>: {1} {2}', tag_type, content, identifier) return content
class BootstrapPanelPlugin(TransparentMixin, BootstrapPluginBase): """ Use this plugin to display a panel with optional panel-header and panel-footer. """ name = _("Panel") default_css_class = 'panel' require_parent = False parent_classes = ('BootstrapColumnPlugin', ) allow_children = True child_classes = None render_template = 'cascade/bootstrap3/panel.html' glossary_fields = ( PartialFormField('panel_type', PanelTypeRenderer.get_widget(), label=_("Panel type"), help_text=_("Display Panel using this style.")), PartialFormField('heading_size', widgets.Select(choices=panel_heading_sizes), initial='', label=_("Heading Size")), PartialFormField('heading', widgets.TextInput(attrs={'size': 80}), label=_("Panel Heading")), PartialFormField('footer', widgets.TextInput(attrs={'size': 80}), label=_("Panel Footer")), ) html_parser = HTMLParser() class Media: css = { 'all': ( 'cascade/css/admin/bootstrap.min.css', 'cascade/css/admin/bootstrap-theme.min.css', ) } def render(self, context, instance, placeholder): heading = self.html_parser.unescape( instance.glossary.get('heading', '')) footer = self.html_parser.unescape(instance.glossary.get('footer', '')) context.update({ 'instance': instance, 'panel_type': instance.glossary.get('panel_type', 'panel-default'), 'panel_heading': heading, 'heading_size': instance.glossary.get('heading_size', ''), 'panel_footer': footer, 'placeholder': placeholder, }) return super(BootstrapPanelPlugin, self).render(context, instance, placeholder)
def get_form(self, request, obj=None, **kwargs): from cmsplugin_cascade.models import PluginExtraFields glossary_fields = list(kwargs.pop('glossary_fields', self.glossary_fields)) try: site = get_current_site(request) extra_fields = PluginExtraFields.objects.get(plugin_type=self.__class__.__name__, site=site) except ObjectDoesNotExist: pass else: # add a text input field to let the user name an ID tag for this HTML element if extra_fields.allow_id_tag: glossary_fields.append(PartialFormField('extra_element_id', widgets.TextInput(), label=_("Named Element ID"), )) # add a select box to let the user choose one or more CSS classes class_names = extra_fields.css_classes.get('class_names', '').replace(' ', '') if class_names: choices = [(clsname, clsname) for clsname in class_names.split(',')] if extra_fields.css_classes.get('multiple'): widget = widgets.CheckboxSelectMultiple(choices=choices) else: widget = widgets.Select(choices=((None, _("Select CSS")),) + tuple(choices)) glossary_fields.append(PartialFormField('extra_css_classes', widget, label=_("Customized CSS Classes"), help_text=_("Customized CSS classes to be added to this element.") )) # add input fields to let the user enter styling information for style, choices_tuples in settings.CMSPLUGIN_CASCADE['extra_inline_styles'].items(): inline_styles = extra_fields.inline_styles.get('extra_fields:{0}'.format(style)) if not inline_styles: continue Widget = choices_tuples[1] if issubclass(Widget, MultipleCascadingSizeWidget): key = 'extra_inline_styles:{0}'.format(style) allowed_units = extra_fields.inline_styles.get('extra_units:{0}'.format(style)).split(',') widget = Widget(inline_styles, allowed_units=allowed_units, required=False) glossary_fields.append(PartialFormField(key, widget, label=style)) else: for inline_style in inline_styles: key = 'extra_inline_styles:{0}'.format(inline_style) label = '{0}: {1}'.format(style, inline_style) glossary_fields.append(PartialFormField(key, Widget(), label=label)) kwargs.update(glossary_fields=glossary_fields) return super(ExtraFieldsMixin, self).get_form(request, obj, **kwargs)
class BootstrapTabSetPlugin(TransparentMixin, BootstrapPluginBase): name = _("Tab Set") form = TabForm parent_classes = ( 'BootstrapRowPlugin', 'BootstrapColumnPlugin', ) require_parent = True allow_children = True child_classes = None render_template = 'cascade/bootstrap3/{}/tabset.html' glossary_fields = (PartialFormField('justified', widgets.CheckboxInput(), label=_("Justified tabs")), ) @classmethod def get_identifier(cls, instance): identifier = super(BootstrapTabSetPlugin, cls).get_identifier(instance) num_cols = instance.get_children().count() content = ungettext_lazy('with {} tab', 'with {} tabs', num_cols).format(num_cols) return format_html('{0}{1}', identifier, content) def save_model(self, request, obj, form, change): wanted_children = int(form.cleaned_data.get('num_children')) super(BootstrapTabSetPlugin, self).save_model(request, obj, form, change) self.extend_children(obj, wanted_children, BootstrapTabPanePlugin)
class SimpleWrapperPlugin(TransparentMixin, CascadePluginBase): name = _("Simple Wrapper") parent_classes = None require_parent = False allow_children = True alien_child_classes = True TAG_CHOICES = tuple((cls, _("<{}> – Element").format(cls)) for cls in ( 'div', 'span', 'section', 'article', )) + (('naked', _("Naked Wrapper")), ) glossary_fields = (PartialFormField( 'tag_type', widgets.Select(choices=TAG_CHOICES), label=_("HTML element tag"), help_text=_('Choose a tag type for this HTML element.')), ) @classmethod def get_identifier(cls, instance): identifier = super(SimpleWrapperPlugin, cls).get_identifier(instance) tag_name = dict(cls.TAG_CHOICES).get(instance.glossary.get('tag_type')) if tag_name: return format_html('{0}{1}', identifier, tag_name) return identifier def get_render_template(self, context, instance, placeholder): if instance.glossary.get('tag_type') == 'naked': return 'cascade/generic/naked.html' return 'cascade/generic/wrapper.html'
class CheckoutAddressPluginBase(DialogFormPluginBase): glossary_fields = DialogFormPluginBase.glossary_fields + (PartialFormField( 'multi_addr', widgets.CheckboxInput(), label=_("Multiple Addresses"), initial=False, help_text=_( "Shall the customer be allowed to edit multiple addresses."), ), ) def get_form_data(self, context, instance, placeholder): form_data = super(CheckoutAddressPluginBase, self).get_form_data(context, instance, placeholder) AddressModel = self.FormClass.get_model() assert form_data[ 'cart'] is not None, "Can not proceed to checkout without cart" address = self.get_address(form_data['cart']) form_data.update(instance=address) if instance.glossary.get('multi_addr'): addresses = AddressModel.objects.filter( customer=context['request'].customer).order_by('priority') form_entities = [ dict(value=str(addr.priority), label="{}. {}".format(number, addr.as_text().replace('\n', ' – '))) for number, addr in enumerate(addresses, 1) ] form_data.update(multi_addr=True, form_entities=form_entities) else: form_data.update(multi_addr=False) return form_data
def get_form(self, request, obj=None, **kwargs): if obj: caption = self.html_parser.unescape(obj.glossary.get( 'caption', '')) obj.glossary.update(caption=caption) parent_obj = self.get_parent_instance(request) if not (parent_obj and issubclass(parent_obj.plugin_class, BootstrapPluginBase)): raise ImproperlyConfigured( "A CarouselSlidePlugin requires a valid parent") # define glossary fields on the fly, because the TextEditorWidget requires the plugin_pk text_editor_widget = TextEditorWidget( installed_plugins=[TextLinkPlugin], pk=parent_obj.pk, placeholder=parent_obj.placeholder, plugin_language=parent_obj.language) kwargs['glossary_fields'] = (PartialFormField( 'caption', text_editor_widget, label=_("Slide Caption"), help_text=_("Caption text to be laid over the backgroud image."), ), ) return super(CarouselSlidePlugin, self).get_form(request, obj, **kwargs)
class BreadcrumbPlugin(ShopPluginBase): name = _("Breadcrumb") CHOICES = ( ('default', _("Default Breadcrumb")), ('soft-root', _("“Soft-Root” Breadcrumb")), ('catalog', _("With Catalog Count")), ('empty', _("Empty Breadcrumb")), ) glossary_fields = (PartialFormField( 'render_type', widgets.RadioSelect(choices=CHOICES), label=_("Render as"), initial='default', help_text=_("Render an alternative Breadcrumb"), ), ) parent_classes = () allow_children = None def get_render_template(self, context, instance, placeholder): render_type = instance.glossary.get('render_type') try: return select_template([ '{}/breadcrumb/{}.html'.format(shop_settings.APP_LABEL, render_type), 'shop/breadcrumb/{}.html'.format(render_type), ]) except TemplateDoesNotExist: return Template('<!-- empty breadcrumb -->')
def __init__(self, model=None, admin_site=None): glossary_fields = (PartialFormField( 'options', widgets.CheckboxSelectMultiple(choices=(('clearfix', _('Clearfix')), )), label=_('Options'), ), ) super(Container960BasePlugin, self).__init__(model, admin_site, glossary_fields)
def get_form(self, request, obj=None, **kwargs): glossary_fields = list(kwargs.pop('glossary_fields', self.glossary_fields)) glossary_fields.append(PartialFormField('element_id', widgets.TextInput(), label=_("Element ID"), help_text=_("A unique identifier for this element.") )) kwargs.update(form=SectionForm, glossary_fields=glossary_fields) return super(SectionMixin, self).get_form(request, obj, **kwargs)
def get_form(self, request, obj=None, **kwargs): if obj: html_content = self.html_parser.unescape(obj.glossary.get('html_content', '')) obj.glossary.update(html_content=html_content) text_editor_widget = TextEditorWidget(installed_plugins=[TextLinkPlugin], pk=obj.pk, placeholder=obj.placeholder, plugin_language=obj.language) kwargs['glossary_fields'] = ( PartialFormField('html_content', text_editor_widget, label=_("HTML content")), ) return super(AcceptConditionFormPlugin, self).get_form(request, obj, **kwargs)
def __init__(self, model, admin_site): super(PluginExtraFieldsAdmin, self).__init__(model, admin_site) self.style_fields = [] for style, choices_tuples in CASCADE_EXTRA_INLINE_STYLES.items(): extra_field = PartialFormField('extra_fields:{0}'.format(style), widgets.CheckboxSelectMultiple(choices=((c, c) for c in choices_tuples[0])), label=_("Customized {0} Fields:").format(style), ) Widget = choices_tuples[1] if issubclass(Widget, MultipleCascadingSizeWidget): self.style_fields.append(( extra_field, PartialFormField('extra_units:{0}'.format(style), widgets.Select(choices=self.DISTANCE_UNITS), label=_("Units for {0} Fields:").format(style), initial=self.DISTANCE_UNITS[0][0], ), )) else: self.style_fields.append(extra_field)
def get_form(self, request, obj=None, **kwargs): if obj: notes = self.html_parser.unescape(obj.glossary.get('notes', '')) obj.glossary.update(notes=notes) # define glossary fields on the fly, because the TextEditorWidget requires the plugin_pk text_editor_widget = TextEditorWidget(installed_plugins=[], pk=self.parent.pk, placeholder=self.parent.placeholder, plugin_language=self.parent.language) kwargs['glossary_fields'] = ( PartialFormField('notes', text_editor_widget, label=_("Speaker Notes")), ) return super(RevealSpeakerNotePlugin, self).get_form(request, obj, **kwargs)
class BootstrapAccordionPlugin(TransparentMixin, BootstrapPluginBase): name = _("Accordion") form = AccordionForm default_css_class = 'panel-group' require_parent = True parent_classes = ('BootstrapColumnPlugin', ) allow_children = True child_classes = None render_template = 'cascade/bootstrap3/{}/accordion.html' fields = ( 'num_children', 'glossary', ) glossary_fields = ( PartialFormField('close_others', widgets.CheckboxInput(), label=_("Close others"), initial=True, help_text=_("Open only one panel at a time.")), PartialFormField('first_is_open', widgets.CheckboxInput(), label=_("First panel open"), initial=True, help_text=_("Start with the first panel open.")), ) @classmethod def get_identifier(cls, obj): identifier = super(BootstrapAccordionPlugin, cls).get_identifier(obj) num_cols = obj.get_children().count() content = ungettext_lazy('with {0} panel', 'with {0} panels', num_cols).format(num_cols) return format_html('{0}{1}', identifier, content) def save_model(self, request, obj, form, change): wanted_children = int(form.cleaned_data.get('num_children')) super(BootstrapAccordionPlugin, self).save_model(request, obj, form, change) self.extend_children(obj, wanted_children, BootstrapAccordionPanelPlugin)
def get_form(self, request, obj=None, **kwargs): glossary_fields = list( kwargs.pop('glossary_fields', self.glossary_fields)) glossary_fields.append( PartialFormField( 'render_template', widgets.Select(choices=self.get_template_choices()), label=_("Render template"), help_text=_( "Use alternative template for rendering this plugin."))) kwargs.update(glossary_fields=glossary_fields) return super(RenderTemplateMixin, self).get_form(request, obj, **kwargs)
class CarouselSlidePlugin(BootstrapPluginBase): name = _("Slide") model_mixins = (ImagePropertyMixin,) form = ImageForm default_css_class = 'img-responsive' parent_classes = ['CarouselPlugin'] raw_id_fields = ('image_file',) fields = ('image_file', 'glossary',) render_template = os.path.join(CASCADE_TEMPLATE_DIR, 'carousel-slide.html') glossary_fields = ( PartialFormField('caption', TextEditorWidget(), label=_("Slide Caption"), help_text=_("Caption text to be laid over the backgroud image."), ), ) def get_form(self, request, obj=None, **kwargs): caption = HTMLParser().unescape(obj.glossary.get('caption', '')) obj.glossary.update(caption=caption) return super(CarouselSlidePlugin, self).get_form(request, obj, **kwargs) def render(self, context, instance, placeholder): # image shall be rendered in a responsive context using the ``<picture>`` element elements = utils.get_picture_elements(context, instance) caption = HTMLParser().unescape(instance.glossary.get('caption', '')) context.update({ 'is_responsive': True, 'instance': instance, 'caption': caption, 'placeholder': placeholder, 'elements': elements, }) return super(CarouselSlidePlugin, self).render(context, instance, placeholder) @classmethod def sanitize_model(cls, obj): sanitized = super(CarouselSlidePlugin, cls).sanitize_model(obj) complete_glossary = obj.get_complete_glossary() obj.glossary.update({'resize-options': complete_glossary.get('resize-options', [])}) return sanitized @classmethod def get_identifier(cls, obj): identifier = super(CarouselSlidePlugin, cls).get_identifier(obj) try: content = force_text(obj.image) except AttributeError: content = _("No Slide") return format_html('{0}{1}', identifier, content)
class LinkPluginBase(CascadePluginBase): glossary_fields = (PartialFormField( 'target', widgets.RadioSelect(choices=( ('', _("Same Window")), ('_blank', _("New Window")), ('_parent', _("Parent Window")), ('_top', _("Topmost Frame")), )), initial='', label=_('Link Target'), help_text=_("Open Link in other target.")), ) html_tag_attributes = {'target': 'target'} # map field from glossary to these form fields glossary_field_map = { 'link': ( 'link_type', 'cms_page', 'ext_url', 'mail_to', ) } class Media: js = resolve_dependencies('cascade/js/admin/linkplugin.js') @classmethod def get_link(cls, obj): link = obj.glossary.get('link', {}) linktype = link.get('type') if linktype == 'exturl': return '{url}'.format(**link) if linktype == 'email': return 'mailto:{email}'.format(**link) # otherwise try to resolve by model if 'model' in link and 'pk' in link: if not hasattr(obj, '_link_model'): Model = get_model(*link['model'].split('.')) try: obj._link_model = Model.objects.get(pk=link['pk']) except ObjectDoesNotExist: obj._link_model = None if obj._link_model: return obj._link_model.get_absolute_url() def get_ring_bases(self): bases = super(LinkPluginBase, self).get_ring_bases() bases.append('LinkPluginBase') return bases
class BillingAddressFormPlugin(CheckoutAddressPluginBase): name = _("Billing Address Form") form_class = 'shop.forms.checkout.BillingAddressForm' template_leaf_name = 'billing-address-{}.html' glossary_fields = CheckoutAddressPluginBase.glossary_fields + ( PartialFormField('allow_use_shipping', widgets.CheckboxInput(), label=_("Use shipping address"), initial=True, help_text=_("Allow the customer to use the shipping address for billing."), ), ) def get_address(self, cart): # if billing address is None, we use the shipping address return cart.billing_address
class PanelPlugin(BootstrapPluginBase): name = _("Panel") default_css_class = 'panel-body' parent_classes = ('PanelGroupPlugin', ) require_parent = True alien_child_classes = True glossary_fields = (PartialFormField('panel_title', widgets.TextInput(attrs={'size': 150}), label=_("Panel Title")), ) @classmethod def get_identifier(cls, obj): identifier = super(PanelPlugin, cls).get_identifier(obj) content = obj.glossary.get('panel_title', '') if content: content = unicode(Truncator(content).words(3, truncate=' ...')) return format_html('{0}{1}', identifier, content)
class BootstrapTabPanePlugin(TransparentMixin, BootstrapPluginBase): name = _("Tab Pane") parent_classes = ('BootstrapTabSetPlugin', ) require_parent = True allow_children = True alien_child_classes = True glossary_fields = (PartialFormField('tab_title', widgets.TextInput(attrs={'size': 150}), label=_("Tab Title")), ) @classmethod def get_identifier(cls, obj): identifier = super(BootstrapTabPanePlugin, cls).get_identifier(obj) content = obj.glossary.get('tab_title', '') if content: content = Truncator(content).words(3, truncate=' ...') return format_html('{0}{1}', identifier, content)
class SimpleWrapperPlugin(BootstrapPluginBase): name = _("Simple Wrapper") parent_classes = ('BootstrapColumnPlugin',) alien_child_classes = True TAG_CHOICES = tuple((cls, cls.title()) for cls in ('div', 'span', 'section', 'article',)) glossary_fields = ( PartialFormField('element_tag', widgets.Select(choices=TAG_CHOICES), label=_("HTML element tag"), help_text=_('Choose a tag type for this HTML element.') ), ) @classmethod def get_identifier(cls, obj): identifier = super(SimpleWrapperPlugin, cls).get_identifier(obj) tag = obj.glossary.get('element_tag', cls.TAG_CHOICES[0][1]) return format_html('{0}{1}', identifier, tag.title())
def get_form(self, request, obj=None, **kwargs): if obj: caption = self.html_parser.unescape(obj.glossary.get( 'caption', '')) obj.glossary.update(caption=caption) # define glossary fields on the fly, because the TextEditorWidget requires the plugin_pk text_editor_widget = TextEditorWidget( installed_plugins=[TextLinkPlugin], pk=self.parent.pk, placeholder=self.parent.placeholder, plugin_language=self.parent.language) kwargs['glossary_fields'] = (PartialFormField( 'caption', text_editor_widget, label=_("Slide Caption"), help_text=_("Caption text to be laid over the backgroud image."), ), ) return super(CarouselSlidePlugin, self).get_form(request, obj, **kwargs)