diff --git a/README.rst b/README.rst index d2cda70..4753a81 100644 --- a/README.rst +++ b/README.rst @@ -51,7 +51,22 @@ Next, include the ``wagtail_personalisation`` and ] Make sure that ``django.contrib.sessions.middleware.SessionMiddleware`` has -been added in first. +been added in first, this is a prerequisite for this project. + + +Changing segments adapter +------------------------- +To change the segments adapter, first make a new one based on the +``BaseSegmentsAdapter`` + +.. code-block:: python + + class YourSegmentsAdapter(BaseSegmentsAdapter): + # Add your own logic here + +Add the ``PERSONALISATION_SEGMENTS_ADAPTER`` setting to your settings.py and +choose your own adapter. + Sandbox ------- diff --git a/src/wagtail_personalisation/adapters.py b/src/wagtail_personalisation/adapters.py index ee571c7..55afea3 100644 --- a/src/wagtail_personalisation/adapters.py +++ b/src/wagtail_personalisation/adapters.py @@ -1,6 +1,8 @@ from __future__ import absolute_import, unicode_literals +from django.conf import settings from django.db.models import F +from django.utils.module_loading import import_string from wagtail_personalisation.models import Segment from wagtail_personalisation.rules import AbstractBaseRule @@ -10,6 +12,15 @@ from wagtail_personalisation.utils import create_segment_dictionary class BaseSegmentsAdapter(object): """Base segments adapter.""" + def __init__(self, request): + """Prepare the request session for segment storage. + + :param request: The http request + :type request: django.http.HttpRequest + + """ + self.request = request + def setup(self): """Prepare the adapter for segment storage.""" return None @@ -64,15 +75,8 @@ class BaseSegmentsAdapter(object): class SessionSegmentsAdapter(BaseSegmentsAdapter): """Segment adapter that uses Django's session backend.""" - def setup(self, request): - """Prepare the request session for segment storage. - - :param request: The http request - :type request: django.http.HttpRequest - - """ - self.request = request - + def __init__(self, request): + super(SessionSegmentsAdapter, self).__init__(request) self.request.session.setdefault('segments', []) def get_all_segments(self): @@ -166,3 +170,18 @@ class SessionSegmentsAdapter(BaseSegmentsAdapter): self.request.session['segments'] = new_segments self.update_visit_count() + + +SEGMENT_ADAPTER_CLASS = import_string(getattr( + settings, + 'PERSONALISATION_SEGMENTS_ADAPTER', + 'wagtail_personalisation.adapters.SessionSegmentsAdapter')) + + +def get_segment_adapter(request): + """Return the Segment Adapter for the given request""" + try: + return request.segment_adapter + except AttributeError: + request.segment_adapter = SEGMENT_ADAPTER_CLASS(request) + return request.segment_adapter diff --git a/src/wagtail_personalisation/app_settings.py b/src/wagtail_personalisation/app_settings.py deleted file mode 100644 index cfcf84d..0000000 --- a/src/wagtail_personalisation/app_settings.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.conf import settings -from django.utils.module_loading import import_string - -# Create a setting for the segments adapter to allow -# overwriting of the provided adapter's functionality. -segments_adapter = import_string(getattr( - settings, - 'PERSONALISATION_SEGMENTS_ADAPTER', - 'wagtail_personalisation.adapters.SessionSegmentsAdapter'))() diff --git a/src/wagtail_personalisation/templatetags/datalayer_tags.py b/src/wagtail_personalisation/templatetags/datalayer_tags.py index f5d7a64..ccca56f 100644 --- a/src/wagtail_personalisation/templatetags/datalayer_tags.py +++ b/src/wagtail_personalisation/templatetags/datalayer_tags.py @@ -1,16 +1,18 @@ from django.template import Library -from wagtail_personalisation.app_settings import segments_adapter +from wagtail_personalisation.adapters import get_segment_adapter register = Library() -@register.inclusion_tag('wagtail_personalisation/tags/datalayer.html') -def render_datalayer(): +@register.inclusion_tag('wagtail_personalisation/tags/datalayer.html', takes_context=True) +def render_datalayer(context): """Render the sessions active segments in a data layer script tag.""" - segments = segments_adapter.get_all_segments() - segment_names = [item['encoded_name'] for item in segments] + request = context.get('request') + if request: + segments = get_segment_adapter(request).get_all_segments() + segment_names = [item['encoded_name'] for item in segments] - return { - 'segments': segment_names - } + return { + 'segments': segment_names + } diff --git a/src/wagtail_personalisation/wagtail_hooks.py b/src/wagtail_personalisation/wagtail_hooks.py index 47843c3..cb66a82 100644 --- a/src/wagtail_personalisation/wagtail_hooks.py +++ b/src/wagtail_personalisation/wagtail_hooks.py @@ -11,7 +11,7 @@ from wagtail.wagtailadmin.widgets import Button, ButtonWithDropdownFromHook from wagtail.wagtailcore import hooks from wagtail_personalisation import admin_urls -from wagtail_personalisation.app_settings import segments_adapter +from wagtail_personalisation.adapters import get_segment_adapter from wagtail_personalisation.models import PersonalisablePage, Segment from wagtail_personalisation.utils import impersonate_other_page @@ -87,8 +87,8 @@ def segment_user(page, request, serve_args, serve_kwargs): :type request: django.http.HttpRequest """ - segments_adapter.setup(request) - segments_adapter.refresh() + adapter = get_segment_adapter(request) + adapter.refresh() @hooks.register('before_serve_page') @@ -105,8 +105,9 @@ def serve_variation(page, request, serve_args, serve_kwargs): """ user_segments = [] + adapter = get_segment_adapter(request) - for segment in segments_adapter.get_all_segments(): + for segment in adapter.get_all_segments(): try: user_segment = Segment.objects.get(pk=segment['id'], status='enabled')