Skip to content

Instantly share code, notes, and snippets.

@mkoistinen
Last active March 29, 2016 12:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkoistinen/403a81c05b4b8f783c74 to your computer and use it in GitHub Desktop.
Save mkoistinen/403a81c05b4b8f783c74 to your computer and use it in GitHub Desktop.
highwater plugin

========= Highwater

An example of a plugin that knows if it is the draft or public version of itself, also, a plugin that maintains the same value of "high_water_mark" for each public/draft pair.


Directory structure

The files in this gist should be arranged as follows in your project::

highwater
    templates
        highwater
            plugins
                highwater_plugin.html
    __init__.py (empty file)
    cms_plugins.py
    models.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from .models import HighWaterMarkPluginModel
class DraftPublicPlugin(CMSPluginBase):
def render(self, context, instance, placeholder):
context = super(DraftPublicPlugin, self).render(
context, instance, placeholder)
instance.manage_twin(context)
return context
class HighWaterMarkPlugin(DraftPublicPlugin):
cache = False
model = HighWaterMarkPluginModel
name = _('High Water Mark')
render_template = 'highwater/plugins/highwater_plugin.html'
text_enabled = True
def render(self, context, instance, placeholder):
context = super(HighWaterMarkPlugin, self).render(
context, instance, placeholder)
context['high_water_mark'] = instance.high_water_mark
return context
plugin_pool.register_plugin(HighWaterMarkPlugin)
<div class="highwater_plugin">{{ high_water_mark }} ({% if instance.is_draft == True %}draft{% elif instance.is_draft == False %}public{% endif %} id: {{ instance.pk }})</div>
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from cms.models import CMSPlugin
class DraftPublicPluginModel(CMSPlugin):
twin = models.OneToOneField('self', default=None, null=True, editable=False, on_delete=models.SET_NULL)
source = models.ForeignKey(
'self', related_name="clones", default=None, null=True, editable=False, on_delete=models.SET_NULL)
is_draft = models.NullBooleanField(default=None, editable=False)
class Meta:
abstract = True
def manage_twin(self, context):
"""
The relationship between twins can only really be determined during a
request, since only then will we get a page object (in some cases).
"""
try:
request = context['request']
page = request.current_page
except (KeyError, AttributeError):
return
if self.is_draft is None:
self.is_draft = page.publisher_is_draft
if self.is_draft is False and self.source:
self.twin = self.source
self.twin.is_draft = True
self.twin.save()
self.save()
def copy_relations(self, old_instance):
"""
Use this as a 'hook' for when the plugin is copied. If we were copied
from another instance, make sure we remember that. Also, don't copy
is_draft.
"""
super(DraftPublicPluginModel, self).copy_relations(old_instance)
self.source = old_instance
self.is_draft = None
self.save()
@python_2_unicode_compatible
class HighWaterMarkPluginModel(DraftPublicPluginModel):
_high_water_mark = models.PositiveIntegerField(
default=None, null=True, editable=False)
@property
def high_water_mark(self):
if self.is_draft:
# This is the draft version, if it doesn't have a _high_water_mark
# yet, assign one and return it.
if not self._high_water_mark:
self._high_water_mark = (
HighWaterMarkPluginModel.objects.order_by(
'-_high_water_mark').values_list(
'_high_water_mark', flat=True)[0])
if self._high_water_mark:
self._high_water_mark += 1
else:
self._high_water_mark = 1
self.save()
return self._high_water_mark
elif self.is_draft is False and self.twin:
# This is the public version, it should have a twin and if so,
# return its _high_water_mark
return self.twin._high_water_mark
else:
return None
def __str__(self):
if self._high_water_mark:
return 'High water mark: {0}'.format(self._high_water_mark)
else:
return 'High water mark: (not yet set)'
def copy_relations(self, old_instance):
"""
Ensure copies get their high_water_mark reset
"""
super(HighWaterMarkPluginModel, self).copy_relations(old_instance)
self._high_water_mark = None
self.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment