You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.6 KiB
241 lines
6.6 KiB
# -*- coding: utf-8 -*-
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
from django.db import models
|
|
from django.utils import six
|
|
from django.utils.encoding import python_2_unicode_compatible, force_text
|
|
from django.utils.functional import lazy
|
|
from django.utils.translation import ugettext_lazy as _, string_concat
|
|
|
|
from cms.models import CMSPlugin
|
|
|
|
|
|
#
|
|
# NOTE: The SegmentLimitPluginModel does NOT subclass SegmentBasePluginModel
|
|
#
|
|
@python_2_unicode_compatible
|
|
class SegmentLimitPluginModel(CMSPlugin):
|
|
|
|
#
|
|
# Need to consider how best to display this in the Plugin Change Form...
|
|
#
|
|
# 0 means "Display ALL segments that match",
|
|
# 1 means "Display first matching segment",
|
|
# 2 means "Display up to two matching segments,"
|
|
# and so on...
|
|
#
|
|
|
|
label = models.CharField(_('label'),
|
|
blank=True,
|
|
default='',
|
|
help_text=_('Optionally set a label for this limit block.'),
|
|
max_length=128,
|
|
)
|
|
|
|
max_children = models.PositiveIntegerField(_('# of matches to display'),
|
|
blank=False,
|
|
default=1,
|
|
help_text=_('Display up to how many matching segments?'),
|
|
)
|
|
|
|
@property
|
|
def configuration_string(self):
|
|
if self.max_children == 0:
|
|
return _('Show All')
|
|
elif self.max_children == 1:
|
|
return _('Show First')
|
|
else:
|
|
return string_concat(_('Show First'), ' ', self.max_children)
|
|
|
|
|
|
def __str__(self):
|
|
'''
|
|
If there is a label, show that with the configuration in brackets,
|
|
otherwise, just return the configuration string.
|
|
'''
|
|
|
|
if self.label:
|
|
conf_str = _('{label} [{config}]').format(
|
|
label=self.label,
|
|
config=force_text(self.configuration_string),
|
|
)
|
|
else:
|
|
conf_str = self.configuration_string
|
|
|
|
return force_text(conf_str)
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class SegmentBasePluginModel(CMSPlugin):
|
|
|
|
#
|
|
# Defines a common interface for segment plugins. Also note that plugin
|
|
# model's subclassing this class will automatically be (un-)registered
|
|
# (from)to the segment_pool via 'pre_delete' and 'post_save' signals. This
|
|
# is implemented in aldryn_segmentation.segment_pool.
|
|
#
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
label = models.CharField(_('label'),
|
|
blank=True,
|
|
default='',
|
|
max_length=128,
|
|
)
|
|
|
|
|
|
@property
|
|
def configuration_string(self):
|
|
'''
|
|
Return a ugettext_lazy object (or a lazy function that returns the
|
|
same) that represents the configuration for the plugin instance in a
|
|
unique, concise manner that is suitable for a toolbar menu option.
|
|
|
|
Some Examples:
|
|
Cookie:
|
|
'"key" equals "value"'
|
|
Country:
|
|
'Country is Kenya'
|
|
Auth:
|
|
'User is authenticated'
|
|
Switch:
|
|
'Always ON'
|
|
Limit:
|
|
'Show First'
|
|
|
|
In cases where the returned string is composed with placeholders, E.g.:
|
|
|
|
Cookie:
|
|
ugettext_lazy('“{key}” equals “{value}”').format(
|
|
key=self.key,
|
|
value=self.value
|
|
)
|
|
|
|
You *must* actually return a evaluated, lazy wrapper around the
|
|
gettext_lazy operation as follows:
|
|
|
|
def configuration_string(self):
|
|
wrapper():
|
|
return ugettext_lazy('“{key}” equals “{value}”').format(
|
|
key=self.key,
|
|
value=self.value
|
|
)
|
|
|
|
# NOTE: the trailing '()'
|
|
return lazy(wrapper, six.text_type)()
|
|
|
|
Otherwise, the translations won't happen.
|
|
|
|
This construction is not required for untranslated or non-
|
|
parameterized translations.
|
|
|
|
|
|
NOTE: Each subclass must override to suit.
|
|
'''
|
|
raise NotImplementedError("Please Implement this method")
|
|
|
|
|
|
def __str__(self):
|
|
'''
|
|
If there is a label, show that with the configuration in brackets,
|
|
otherwise, just return the configuration string.
|
|
'''
|
|
|
|
if self.label:
|
|
conf_str = _('{label} [{config}]').format(
|
|
label=self.label,
|
|
config=force_text(self.configuration_string),
|
|
)
|
|
else:
|
|
conf_str = self.configuration_string
|
|
|
|
return force_text(conf_str)
|
|
|
|
|
|
class FallbackSegmentPluginModel(SegmentBasePluginModel):
|
|
|
|
@property
|
|
def configuration_string(self):
|
|
return _('Always active')
|
|
|
|
|
|
class SwitchSegmentPluginModel(SegmentBasePluginModel):
|
|
|
|
on_off = models.BooleanField(_('Always on?'),
|
|
default=True,
|
|
help_text=_('Uncheck to always hide child plugins.'),
|
|
)
|
|
|
|
@property
|
|
def configuration_string(self):
|
|
if self.on_off:
|
|
return _('Always ON')
|
|
else:
|
|
return _('Always OFF')
|
|
|
|
|
|
class CookieSegmentPluginModel(SegmentBasePluginModel):
|
|
|
|
#
|
|
# Consider that we should probably support either:
|
|
# Simple wildcard '*', '?' expressions or
|
|
# RegEx expressions or
|
|
# Both.
|
|
#
|
|
# A note about the max_lengths selected: browsers can support up to 4093
|
|
# characters for a given cookie (combining both the key and the value). So
|
|
# either one can be up to 4092 chars in length. Since these are
|
|
# implemented as VarChars, this shouldn't be too wasteful and still
|
|
# support almost anything.
|
|
#
|
|
# NOTE: This forces a requirement for MySQL users to be using 5.0.3 or
|
|
# later (which is already a requirement for Django 1.5+).
|
|
#
|
|
|
|
cookie_key = models.CharField(_('name of cookie'),
|
|
blank=False,
|
|
default='',
|
|
help_text=_('Name of cookie to consider.'),
|
|
max_length=4096,
|
|
)
|
|
|
|
cookie_value = models.CharField(_('value to compare'),
|
|
blank=False,
|
|
default='',
|
|
help_text=_('Value to consider.'),
|
|
max_length=4096,
|
|
)
|
|
|
|
@property
|
|
def configuration_string(self):
|
|
|
|
def wrapper():
|
|
return _('“{key}” equals “{value}”').format(key=self.cookie_key, value=self.cookie_value)
|
|
|
|
return lazy(
|
|
wrapper,
|
|
six.text_type
|
|
)()
|
|
|
|
|
|
class AuthenticatedSegmentPluginModel(SegmentBasePluginModel):
|
|
|
|
@property
|
|
def configuration_string(self):
|
|
return _('is Authenticated')
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class Segment(models.Model):
|
|
'''
|
|
This is a hollow, unmanaged model that simply allows us to attach custom
|
|
admin views into the AdminSite.
|
|
'''
|
|
|
|
class Meta:
|
|
managed=False
|
|
|
|
def __str__(self):
|
|
return 'Segment is an empty, unmanaged model.' |