Compare commits
9 Commits
feature/#6
...
feature/se
Author | SHA1 | Date | |
---|---|---|---|
acd273c06c | |||
4b3af020fd | |||
05afea8d68 | |||
c31415b484 | |||
4a596d62f2 | |||
3c1c0c3306 | |||
937c06cf32 | |||
d7fac2607b | |||
be672f6fde |
@ -25,7 +25,7 @@
|
|||||||
"enable_date": "2017-06-02T10:58:39.389Z",
|
"enable_date": "2017-06-02T10:58:39.389Z",
|
||||||
"disable_date": "2017-06-02T10:34:51.722Z",
|
"disable_date": "2017-06-02T10:34:51.722Z",
|
||||||
"visit_count": 0,
|
"visit_count": 0,
|
||||||
"status": "enabled",
|
"enabled": true,
|
||||||
"persistent": false,
|
"persistent": false,
|
||||||
"match_any": false
|
"match_any": false
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@
|
|||||||
"enable_date": "2017-06-02T10:57:44.497Z",
|
"enable_date": "2017-06-02T10:57:44.497Z",
|
||||||
"disable_date": "2017-06-02T10:57:39.984Z",
|
"disable_date": "2017-06-02T10:57:39.984Z",
|
||||||
"visit_count": 1,
|
"visit_count": 1,
|
||||||
"status": "enabled",
|
"enabled": true,
|
||||||
"persistent": false,
|
"persistent": false,
|
||||||
"match_any": false
|
"match_any": false
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('wagtailcore', '0001_initial'),
|
('wagtailcore', '0033_remove_golive_expiry_help_text'),
|
||||||
('wagtail_personalisation', '0011_personalisablepagemetadata'),
|
('wagtail_personalisation', '0011_personalisablepagemetadata'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Generated by Django 1.11.1 on 2017-05-31 16:15
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import wagtail.wagtailcore.blocks
|
|
||||||
import wagtail.wagtailcore.fields
|
|
||||||
import wagtail.wagtailimages.blocks
|
|
||||||
import wagtail_personalisation.blocks
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('wagtailcore', '0001_initial'),
|
|
||||||
('home', '0003_homepage_text_content'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='PersonalisedFieldsPage',
|
|
||||||
fields=[
|
|
||||||
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')),
|
|
||||||
('body', wagtail.wagtailcore.fields.StreamField((('personalised_block', wagtail.wagtailcore.blocks.StructBlock((('segment', wagtail.wagtailcore.blocks.ChoiceBlock(choices=wagtail_personalisation.blocks.list_segment_choices, help_text='Only show this content block for users in this segment', label='Personalisation segment', required=False)), ('heading', wagtail.wagtailcore.blocks.CharBlock()), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock())))), ('personalised_block_template', wagtail.wagtailcore.blocks.StructBlock((('segment', wagtail.wagtailcore.blocks.ChoiceBlock(choices=wagtail_personalisation.blocks.list_segment_choices, help_text='Only show this content block for users in this segment', label='Personalisation segment', required=False)), ('heading', wagtail.wagtailcore.blocks.CharBlock()), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock())), label='Block with template', template='blocks/personalised_block_template.html')), ('personalised_rich_text_block', wagtail.wagtailcore.blocks.StructBlock((('segment', wagtail.wagtailcore.blocks.ChoiceBlock(choices=wagtail_personalisation.blocks.list_segment_choices, help_text='Only show this content block for users in this segment', label='Personalisation segment', required=False)), ('rich_text', wagtail.wagtailcore.blocks.RichTextBlock(label='Rich Text'))))), ('personalised_image', wagtail.wagtailcore.blocks.StructBlock((('segment', wagtail.wagtailcore.blocks.ChoiceBlock(choices=wagtail_personalisation.blocks.list_segment_choices, help_text='Only show this content block for users in this segment', label='Personalisation segment', required=False)), ('image', wagtail.wagtailimages.blocks.ImageChooserBlock(label='Image'))))), ('personalised_char', wagtail.wagtailcore.blocks.StructBlock((('segment', wagtail.wagtailcore.blocks.ChoiceBlock(choices=wagtail_personalisation.blocks.list_segment_choices, help_text='Only show this content block for users in this segment', label='Personalisation segment', required=False)), ('char', wagtail.wagtailcore.blocks.CharBlock(label='Text'))))), ('personalised_text', wagtail.wagtailcore.blocks.StructBlock((('segment', wagtail.wagtailcore.blocks.ChoiceBlock(choices=wagtail_personalisation.blocks.list_segment_choices, help_text='Only show this content block for users in this segment', label='Personalisation segment', required=False)), ('text', wagtail.wagtailcore.blocks.TextBlock(label='Mutli-line Text')))))))),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
bases=('wagtailcore.page',),
|
|
||||||
),
|
|
||||||
]
|
|
@ -5,11 +5,8 @@ from wagtail.core import blocks
|
|||||||
from wagtail.core.fields import RichTextField, StreamField
|
from wagtail.core.fields import RichTextField, StreamField
|
||||||
from wagtail.core.models import Page
|
from wagtail.core.models import Page
|
||||||
|
|
||||||
from wagtail_personalisation.blocks import (
|
|
||||||
PersonalisedCharBlock, PersonalisedImageChooserBlock,
|
|
||||||
PersonalisedRichTextBlock, PersonalisedStructBlock,
|
|
||||||
PersonalisedTextBlock)
|
|
||||||
from wagtail_personalisation.models import PersonalisablePageMixin
|
from wagtail_personalisation.models import PersonalisablePageMixin
|
||||||
|
from wagtail_personalisation.blocks import PersonalisedStructBlock
|
||||||
|
|
||||||
|
|
||||||
class HomePage(PersonalisablePageMixin, Page):
|
class HomePage(PersonalisablePageMixin, Page):
|
||||||
@ -24,24 +21,3 @@ class HomePage(PersonalisablePageMixin, Page):
|
|||||||
RichTextFieldPanel('intro'),
|
RichTextFieldPanel('intro'),
|
||||||
StreamFieldPanel('body'),
|
StreamFieldPanel('body'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class PersonalisedFieldsPage(Page):
|
|
||||||
body = StreamField([
|
|
||||||
('personalised_block', PersonalisedStructBlock([
|
|
||||||
('heading', blocks.CharBlock()),
|
|
||||||
('paragraph', blocks.RichTextBlock())
|
|
||||||
], render_fields=['heading', 'paragraph'])),
|
|
||||||
('personalised_block_template', PersonalisedStructBlock([
|
|
||||||
('heading', blocks.CharBlock()),
|
|
||||||
('paragraph', blocks.RichTextBlock())
|
|
||||||
], template='blocks/personalised_block_template.html', label=_('Block with template'))),
|
|
||||||
('personalised_rich_text_block', PersonalisedRichTextBlock()),
|
|
||||||
('personalised_image', PersonalisedImageChooserBlock()),
|
|
||||||
('personalised_char', PersonalisedCharBlock()),
|
|
||||||
('personalised_text', PersonalisedTextBlock()),
|
|
||||||
])
|
|
||||||
|
|
||||||
content_panels = Page.content_panels + [
|
|
||||||
StreamFieldPanel('body')
|
|
||||||
]
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
{% load wagtailcore_tags %}
|
|
||||||
|
|
||||||
<div class="personalisation-block-template" style="background-color: cornsilk;">
|
|
||||||
<p>This is a block with <strong>template</strong>.</p>
|
|
||||||
<h2>Heading: {{ value.heading }}</h2>
|
|
||||||
<div>
|
|
||||||
{{ value.paragraph|richtext }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,15 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% load wagtailcore_tags %}
|
|
||||||
|
|
||||||
{% block body_class %}template-homepage{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>{{ page.title }}</h1>
|
|
||||||
{% for block in page.body %}
|
|
||||||
<section class="section-{{ block.block_type }}">
|
|
||||||
<p><em>Section for {{ block.block_type }}.</em></p>
|
|
||||||
{% include_block block %}
|
|
||||||
</section>
|
|
||||||
<hr>
|
|
||||||
{% endfor %}
|
|
||||||
{% endblock %}
|
|
@ -1,85 +1,25 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.utils.encoding import force_text
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from wagtail.core import blocks
|
from wagtail.core import blocks
|
||||||
from wagtail.images.blocks import ImageChooserBlock
|
|
||||||
|
|
||||||
from wagtail_personalisation.adapters import get_segment_adapter
|
from wagtail_personalisation.adapters import get_segment_adapter
|
||||||
from wagtail_personalisation.models import Segment
|
from wagtail_personalisation.models import Segment
|
||||||
|
|
||||||
|
|
||||||
def list_segment_choices():
|
def list_segment_choices():
|
||||||
"""Get a list of segment choices visible in the admin site when editing
|
|
||||||
BasePersonalisedStructBlock and its derived classes."""
|
|
||||||
yield (-1, _('Visible to everyone'))
|
|
||||||
|
|
||||||
for pk, name in Segment.objects.values_list('pk', 'name'):
|
for pk, name in Segment.objects.values_list('pk', 'name'):
|
||||||
yield pk, name
|
yield pk, name
|
||||||
|
|
||||||
|
|
||||||
class BasePersonalisedStructBlock(blocks.StructBlock):
|
class PersonalisedStructBlock(blocks.StructBlock):
|
||||||
"""Base class for personalised struct blocks."""
|
"""Struct block that allows personalisation per block."""
|
||||||
|
|
||||||
segment = blocks.ChoiceBlock(
|
segment = blocks.ChoiceBlock(
|
||||||
choices=list_segment_choices,
|
choices=list_segment_choices,
|
||||||
required=False, label=_("Personalisation segment"),
|
required=False, label=_("Personalisation segment"),
|
||||||
help_text=_("Only show this content block for users in this segment"))
|
help_text=_("Only show this content block for users in this segment"))
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
"""Instantiate personalised struct block.
|
|
||||||
|
|
||||||
The arguments are the same as for the blocks.StructBlock constructor and
|
|
||||||
one addtional one.
|
|
||||||
|
|
||||||
Keyword Arguments:
|
|
||||||
render_fields: List with field names to be rendered or None to use
|
|
||||||
the default block rendering. Please set to None if using block
|
|
||||||
with template since then it's the template that takes care
|
|
||||||
of what fields are rendered.
|
|
||||||
"""
|
|
||||||
render_fields = kwargs.pop('render_fields',
|
|
||||||
self._meta_class.render_fields)
|
|
||||||
super(BasePersonalisedStructBlock, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
# Check "render_fields" are either a list or None.
|
|
||||||
if isinstance(render_fields, tuple):
|
|
||||||
render_fields = list(render_fields)
|
|
||||||
|
|
||||||
if render_fields is not None \
|
|
||||||
and not isinstance(render_fields, list):
|
|
||||||
raise ValueError('"render_fields" has to be a list or None.')
|
|
||||||
elif isinstance(render_fields, list) \
|
|
||||||
and not set(render_fields).issubset(self.child_blocks):
|
|
||||||
raise ValueError('"render_fields" has to contain name(s) of the '
|
|
||||||
'specified blocks.')
|
|
||||||
else:
|
|
||||||
setattr(self.meta, 'render_fields', render_fields)
|
|
||||||
|
|
||||||
# Template can be used only when "render_fields" is set to None.
|
|
||||||
if self.meta.render_fields is not None \
|
|
||||||
and getattr(self.meta, 'template', None):
|
|
||||||
raise ValueError('"render_fields" has to be set to None when using '
|
|
||||||
'template.')
|
|
||||||
|
|
||||||
def is_visible(self, value, request):
|
|
||||||
"""Check whether user should see the block based on their segments.
|
|
||||||
|
|
||||||
:param value: The value from the block.
|
|
||||||
:type value: dict
|
|
||||||
:returns: True if user should see the block.
|
|
||||||
:rtype: bool
|
|
||||||
|
|
||||||
"""
|
|
||||||
if int(value['segment']) == -1:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if value['segment']:
|
|
||||||
for segment in get_segment_adapter(request).get_segments():
|
|
||||||
if segment.id == int(value['segment']):
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def render(self, value, context=None):
|
def render(self, value, context=None):
|
||||||
"""Only render this content block for users in this segment.
|
"""Only render this content block for users in this segment.
|
||||||
|
|
||||||
@ -91,80 +31,14 @@ class BasePersonalisedStructBlock(blocks.StructBlock):
|
|||||||
:rtype: blocks.StructBlock or empty str
|
:rtype: blocks.StructBlock or empty str
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not self.is_visible(value, context['request']):
|
request = context['request']
|
||||||
return ""
|
adapter = get_segment_adapter(request)
|
||||||
|
user_segments = adapter.get_segments()
|
||||||
|
|
||||||
if self.meta.render_fields is None:
|
if value['segment']:
|
||||||
return super(BasePersonalisedStructBlock, self).render(
|
for segment in user_segments:
|
||||||
|
if segment.id == int(value['segment']):
|
||||||
|
return super(PersonalisedStructBlock, self).render(
|
||||||
value, context)
|
value, context)
|
||||||
|
|
||||||
if isinstance(self.meta.render_fields, list):
|
return ""
|
||||||
render_value = ''
|
|
||||||
for field_name in self.meta.render_fields:
|
|
||||||
if hasattr(value.bound_blocks[field_name], 'render_as_block'):
|
|
||||||
block_value = value.bound_blocks[field_name].render_as_block(context=context)
|
|
||||||
else:
|
|
||||||
block_value = force_text(value[field_name])
|
|
||||||
|
|
||||||
if block_value != 'None':
|
|
||||||
render_value += block_value
|
|
||||||
|
|
||||||
return render_value
|
|
||||||
|
|
||||||
raise RuntimeError('"render_fields" is neither "None" or "list" '
|
|
||||||
'during rendering.')
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
"""
|
|
||||||
Setting render field will define which field gets rendered.
|
|
||||||
Please use a name of the field. If none, it will render the whole block.
|
|
||||||
"""
|
|
||||||
render_fields = None
|
|
||||||
|
|
||||||
|
|
||||||
class PersonalisedStructBlock(BasePersonalisedStructBlock):
|
|
||||||
"""Struct block that allows personalisation per block."""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
label = _('Personalised Block')
|
|
||||||
render_fields = None
|
|
||||||
|
|
||||||
|
|
||||||
class PersonalisedRichTextBlock(BasePersonalisedStructBlock):
|
|
||||||
"""Rich text block that allows personalisation."""
|
|
||||||
rich_text = blocks.RichTextBlock(label=_('Rich Text'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
icon = blocks.RichTextBlock._meta_class.icon
|
|
||||||
label = _('Personalised Rich Text')
|
|
||||||
render_fields = ['rich_text']
|
|
||||||
|
|
||||||
|
|
||||||
class PersonalisedTextBlock(BasePersonalisedStructBlock):
|
|
||||||
"""Text block that allows personalisation."""
|
|
||||||
text = blocks.TextBlock(label=_('Mutli-line Text'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
icon = blocks.TextBlock._meta_class.icon
|
|
||||||
label = _('Personalised Multi-line Text')
|
|
||||||
render_fields = ['text']
|
|
||||||
|
|
||||||
|
|
||||||
class PersonalisedCharBlock(BasePersonalisedStructBlock):
|
|
||||||
"""Char block that allows personalisation."""
|
|
||||||
char = blocks.CharBlock(label=_('Text'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
icon = blocks.CharBlock._meta_class.icon
|
|
||||||
label = _('Personalised Single-line Text')
|
|
||||||
render_fields = ['char']
|
|
||||||
|
|
||||||
|
|
||||||
class PersonalisedImageChooserBlock(BasePersonalisedStructBlock):
|
|
||||||
"""Image chooser block that allows personalisation."""
|
|
||||||
image = ImageChooserBlock(label=_('Image'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
icon = ImageChooserBlock._meta_class.icon
|
|
||||||
label = _('Personalised Image')
|
|
||||||
render_fields = ['image']
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11.2 on 2017-08-10 13:48
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def forward(apps, schema_editor):
|
||||||
|
Segment = apps.get_model('wagtail_personalisation', 'Segment')
|
||||||
|
|
||||||
|
for segment in Segment.objects.all():
|
||||||
|
segment.enabled = segment.status == 'enabled'
|
||||||
|
segment.save()
|
||||||
|
|
||||||
|
|
||||||
|
def backward(apps, schema_editor):
|
||||||
|
Segment = apps.get_model('wagtail_personalisation', 'Segment')
|
||||||
|
|
||||||
|
for segment in Segment.objects.all():
|
||||||
|
if segment.enabled:
|
||||||
|
segment.status = 'enabled'
|
||||||
|
else:
|
||||||
|
segment.status = 'disabled'
|
||||||
|
|
||||||
|
segment.save()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wagtail_personalisation', '0023_personalisablepagemetadata_variant_cascade'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='segment',
|
||||||
|
name='enabled',
|
||||||
|
field=models.BooleanField(default=True, help_text='Should the segment be active?'),
|
||||||
|
),
|
||||||
|
migrations.RunPython(forward, reverse_code=backward),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='segment',
|
||||||
|
name='status',
|
||||||
|
),
|
||||||
|
]
|
@ -22,20 +22,12 @@ from .forms import SegmentAdminForm
|
|||||||
|
|
||||||
class SegmentQuerySet(models.QuerySet):
|
class SegmentQuerySet(models.QuerySet):
|
||||||
def enabled(self):
|
def enabled(self):
|
||||||
return self.filter(status=self.model.STATUS_ENABLED)
|
return self.filter(enabled=True)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Segment(ClusterableModel):
|
class Segment(ClusterableModel):
|
||||||
"""The segment model."""
|
"""The segment model."""
|
||||||
STATUS_ENABLED = 'enabled'
|
|
||||||
STATUS_DISABLED = 'disabled'
|
|
||||||
|
|
||||||
STATUS_CHOICES = (
|
|
||||||
(STATUS_ENABLED, _('Enabled')),
|
|
||||||
(STATUS_DISABLED, _('Disabled')),
|
|
||||||
)
|
|
||||||
|
|
||||||
TYPE_DYNAMIC = 'dynamic'
|
TYPE_DYNAMIC = 'dynamic'
|
||||||
TYPE_STATIC = 'static'
|
TYPE_STATIC = 'static'
|
||||||
|
|
||||||
@ -50,8 +42,8 @@ class Segment(ClusterableModel):
|
|||||||
enable_date = models.DateTimeField(null=True, editable=False)
|
enable_date = models.DateTimeField(null=True, editable=False)
|
||||||
disable_date = models.DateTimeField(null=True, editable=False)
|
disable_date = models.DateTimeField(null=True, editable=False)
|
||||||
visit_count = models.PositiveIntegerField(default=0, editable=False)
|
visit_count = models.PositiveIntegerField(default=0, editable=False)
|
||||||
status = models.CharField(
|
enabled = models.BooleanField(
|
||||||
max_length=20, choices=STATUS_CHOICES, default=STATUS_ENABLED)
|
default=True, help_text=_("Should the segment be active?"))
|
||||||
persistent = models.BooleanField(
|
persistent = models.BooleanField(
|
||||||
default=False, help_text=_("Should the segment persist between visits?"))
|
default=False, help_text=_("Should the segment persist between visits?"))
|
||||||
match_any = models.BooleanField(
|
match_any = models.BooleanField(
|
||||||
@ -111,7 +103,7 @@ class Segment(ClusterableModel):
|
|||||||
MultiFieldPanel([
|
MultiFieldPanel([
|
||||||
FieldPanel('name', classname="title"),
|
FieldPanel('name', classname="title"),
|
||||||
FieldRowPanel([
|
FieldRowPanel([
|
||||||
FieldPanel('status'),
|
FieldPanel('enabled'),
|
||||||
FieldPanel('persistent'),
|
FieldPanel('persistent'),
|
||||||
]),
|
]),
|
||||||
FieldPanel('match_any'),
|
FieldPanel('match_any'),
|
||||||
@ -178,9 +170,7 @@ class Segment(ClusterableModel):
|
|||||||
return segment_rules
|
return segment_rules
|
||||||
|
|
||||||
def toggle(self, save=True):
|
def toggle(self, save=True):
|
||||||
self.status = (
|
self.enabled = not self.enabled
|
||||||
self.STATUS_ENABLED if self.status == self.STATUS_DISABLED
|
|
||||||
else self.STATUS_DISABLED)
|
|
||||||
if save:
|
if save:
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
@ -7,16 +7,16 @@ from wagtail_personalisation.models import Segment
|
|||||||
def check_status_change(sender, instance, *args, **kwargs):
|
def check_status_change(sender, instance, *args, **kwargs):
|
||||||
"""Check if the status has changed. Alter dates accordingly."""
|
"""Check if the status has changed. Alter dates accordingly."""
|
||||||
try:
|
try:
|
||||||
original_status = sender.objects.get(pk=instance.id).status
|
original_status = sender.objects.get(pk=instance.id).enabled
|
||||||
except sender.DoesNotExist:
|
except sender.DoesNotExist:
|
||||||
original_status = ""
|
original_status = None
|
||||||
|
|
||||||
if original_status != instance.status:
|
if original_status != instance.enabled:
|
||||||
if instance.status == instance.STATUS_ENABLED:
|
if instance.enabled is True:
|
||||||
instance.enable_date = timezone.now()
|
instance.enable_date = timezone.now()
|
||||||
instance.visit_count = 0
|
instance.visit_count = 0
|
||||||
return instance
|
return instance
|
||||||
if instance.status == instance.STATUS_DISABLED:
|
if instance.enabled is False:
|
||||||
instance.disable_date = timezone.now()
|
instance.disable_date = timezone.now()
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<div class="nice-padding block_container">
|
<div class="nice-padding block_container">
|
||||||
{% if all_count %}
|
{% if all_count %}
|
||||||
{% for segment in object_list %}
|
{% for segment in object_list %}
|
||||||
<div class="block block--{{ segment.status }}" onclick="location.href = '{% url 'wagtail_personalisation_segment_modeladmin_edit' segment.pk %}'">
|
<div class="block block--{{ segment.enabled|yesno:"enabled,disabled" }}" onclick="location.href = '{% url 'wagtail_personalisation_segment_modeladmin_edit' segment.pk %}'">
|
||||||
<h2>{{ segment }}</h2>
|
<h2>{{ segment }}</h2>
|
||||||
|
|
||||||
<div class="inspect_container">
|
<div class="inspect_container">
|
||||||
@ -98,10 +98,10 @@
|
|||||||
|
|
||||||
{% if user_can_create %}
|
{% if user_can_create %}
|
||||||
<ul class="block_actions">
|
<ul class="block_actions">
|
||||||
{% if segment.status == segment.STATUS_DISABLED %}
|
{% if segment.enabled %}
|
||||||
<li><a href="{% url 'segment:toggle' segment.pk %}" title="{% trans "Enable this segment" %}">enable</a></li>
|
|
||||||
{% elif segment.status == segment.STATUS_ENABLED %}
|
|
||||||
<li><a href="{% url 'segment:toggle' segment.pk %}" title="{% trans "Disable this segment" %}">disable</a></li>
|
<li><a href="{% url 'segment:toggle' segment.pk %}" title="{% trans "Disable this segment" %}">disable</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="{% url 'segment:toggle' segment.pk %}" title="{% trans "Enable this segment" %}">enable</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="{% url 'wagtail_personalisation_segment_modeladmin_edit' segment.pk %}" title="{% trans "Configure this segment" %}">configure this</a></li>
|
<li><a href="{% url 'wagtail_personalisation_segment_modeladmin_edit' segment.pk %}" title="{% trans "Configure this segment" %}">configure this</a></li>
|
||||||
{% if segment.is_static %}
|
{% if segment.is_static %}
|
||||||
|
@ -83,7 +83,7 @@ class SegmentModelAdmin(ModelAdmin):
|
|||||||
delete_view_class = SegmentModelDeleteView
|
delete_view_class = SegmentModelDeleteView
|
||||||
menu_icon = 'fa-snowflake-o'
|
menu_icon = 'fa-snowflake-o'
|
||||||
add_to_settings_menu = False
|
add_to_settings_menu = False
|
||||||
list_display = ('name', 'persistent', 'match_any', 'status',
|
list_display = ('name', 'persistent', 'match_any', 'enabled',
|
||||||
'page_count', 'variant_count', 'statistics')
|
'page_count', 'variant_count', 'statistics')
|
||||||
index_view_extra_js = ['js/commons.js', 'js/index.js']
|
index_view_extra_js = ['js/commons.js', 'js/index.js']
|
||||||
index_view_extra_css = ['css/index.css']
|
index_view_extra_css = ['css/index.css']
|
||||||
|
@ -7,7 +7,7 @@ from wagtail_personalisation import models
|
|||||||
|
|
||||||
class SegmentFactory(factory.DjangoModelFactory):
|
class SegmentFactory(factory.DjangoModelFactory):
|
||||||
name = 'TestSegment'
|
name = 'TestSegment'
|
||||||
status = models.Segment.STATUS_ENABLED
|
enabled = True
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Segment
|
model = models.Segment
|
||||||
|
@ -64,7 +64,7 @@ def test_refresh_removes_disabled(rf):
|
|||||||
adapter.set_segments([segment_1, segment_2])
|
adapter.set_segments([segment_1, segment_2])
|
||||||
|
|
||||||
adapter = adapters.SessionSegmentsAdapter(request)
|
adapter = adapters.SessionSegmentsAdapter(request)
|
||||||
segment_1.status = segment_1.STATUS_DISABLED
|
segment_1.enabled = False
|
||||||
segment_1.save()
|
segment_1.save()
|
||||||
adapter.refresh()
|
adapter.refresh()
|
||||||
|
|
||||||
|
@ -15,14 +15,14 @@ from wagtail_personalisation.rules import TimeRule
|
|||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_segment_create():
|
def test_segment_create():
|
||||||
factoried_segment = SegmentFactory()
|
factoried_segment = SegmentFactory()
|
||||||
segment = Segment(name='TestSegment', status='enabled')
|
segment = Segment(name='TestSegment', enabled=True)
|
||||||
TimeRule(
|
TimeRule(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=segment)
|
segment=segment)
|
||||||
|
|
||||||
assert factoried_segment.name == segment.name
|
assert factoried_segment.name == segment.name
|
||||||
assert factoried_segment.status == segment.status
|
assert factoried_segment.enabled == segment.enabled
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
@ -12,7 +12,7 @@ from wagtail_personalisation.rules import TimeRule, VisitCountRule
|
|||||||
|
|
||||||
|
|
||||||
def form_with_data(segment, *rules):
|
def form_with_data(segment, *rules):
|
||||||
model_fields = ['type', 'status', 'count', 'name', 'match_any', 'randomisation_percent']
|
model_fields = ['type', 'enabled', 'count', 'name', 'match_any', 'randomisation_percent']
|
||||||
|
|
||||||
class TestSegmentAdminForm(SegmentAdminForm):
|
class TestSegmentAdminForm(SegmentAdminForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
Reference in New Issue
Block a user