Permalink
Browse files

stacks initial

  • Loading branch information...
1 parent c9502de commit dd8a8634bd1f304fa8584d43acef41d5990efc3e @digi604 committed Apr 29, 2013
View
1 MANIFEST.in
@@ -7,5 +7,6 @@ recursive-include cms/templates *
recursive-include cms/static *
recursive-include cms/plugins *
recursive-include menus/templates *
+recursive-include stacks/templates *
recursive-include docs *
recursive-exclude * *.pyc
View
2 docs/getting_started/tutorial.rst
@@ -67,11 +67,13 @@ This includes django CMS itself as well as its dependenices and
other highly recommended applications/libraries:
* ``'cms'``, django CMS itself
+* ``'stacks'``, for reusable content
* ``'mptt'``, utilities for implementing a modified pre-order traversal tree
* ``'menus'``, helper for model independent hierarchical website navigation
* ``'south'``, intelligent schema and data migrations
* ``'sekizai'``, for javascript and css management
+
Also add any (or all) of the following plugins, depending on your needs:
* ``'cms.plugins.file'``
View
0 stacks/__init__.py
No changes.
View
11 stacks/admin.py
@@ -0,0 +1,11 @@
+from django.contrib import admin
+from stacks.models import Stack
+from cms.admin.placeholderadmin import PlaceholderAdmin
+
+
+class StackAdmin(PlaceholderAdmin):
+ list_display = ('name', 'code',)
+ search_fields = ('name', 'code',)
+
+
+admin.site.register(Stack, StackAdmin)
View
36 stacks/cms_plugins.py
@@ -0,0 +1,36 @@
+from django.utils.safestring import mark_safe
+from cms.plugin_pool import plugin_pool
+from cms.plugin_base import CMSPluginBase
+from django.utils.translation import ugettext_lazy as _
+from cms.plugin_rendering import render_plugins
+from stacks.fields import StackSearchField
+from stacks.models import StackLink
+from cms.plugins.utils import get_plugins
+
+
+class StackPlugin(CMSPluginBase):
+ model = StackLink
+ name = _("Stack")
+ render_template = "cms/plugins/stacks.html"
+ admin_preview = False
+
+ def render(self, context, instance, placeholder):
+ # TODO: once we drop 2.3.x support we can just use the "render_plugin" templatetag
+ # instead of rendering html here.
+ plugins = get_plugins(context['request'], instance.stack.content)
+ processors = ()
+ html_content = mark_safe(u"".join(render_plugins(plugins, context, placeholder, processors)))
+ context.update({
+ 'instance': instance,
+ 'placeholder': placeholder,
+ 'content': html_content,
+ })
+ return context
+
+ def formfield_for_dbfield(self, db_field, request=None, **kwargs):
+ if db_field.name == "stack":
+ return StackSearchField(**kwargs)
+ return super(StackPlugin, self).formfield_for_dbfield(db_field, request=request, **kwargs)
+
+
+plugin_pool.register_plugin(StackPlugin)
View
14 stacks/fields.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+from django_select2.fields import AutoModelSelect2Field
+from stacks.models import Stack
+
+
+class StackSearchField(AutoModelSelect2Field):
+ search_fields = ('name__icontains', 'code__icontains',)
+ queryset = Stack.objects
+
+ def security_check(self, request, *args, **kwargs):
+ user = request.user
+ if user and not user.is_anonymous() and user.is_staff and user.has_perm('djangocms_stack.change_stack'):
+ return True
+ return False
View
51 stacks/locale/de/LC_MESSAGES/django.po
@@ -0,0 +1,51 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-12-10 11:31+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: cms_plugins.py:12
+msgid "Stack"
+msgstr ""
+
+#: models.py:10
+msgid "stack name"
+msgstr ""
+
+#: models.py:11
+msgid "Descriptive name to identify this stack. Not displayed to users."
+msgstr ""
+
+#: models.py:13
+msgid "stack code"
+msgstr ""
+
+#: models.py:14
+msgid "To render the stack in templates."
+msgstr ""
+
+#: models.py:16
+msgid "stack content"
+msgstr ""
+
+#: models.py:19 models.py:32
+msgid "stack"
+msgstr ""
+
+#: models.py:20
+msgid "stacks"
+msgstr ""
View
50 stacks/locale/en/LC_MESSAGES/django.po
@@ -0,0 +1,50 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-12-10 11:31+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: cms_plugins.py:12
+msgid "Stack"
+msgstr ""
+
+#: models.py:10
+msgid "stack name"
+msgstr ""
+
+#: models.py:11
+msgid "Descriptive name to identify this stack. Not displayed to users."
+msgstr ""
+
+#: models.py:13
+msgid "stack code"
+msgstr ""
+
+#: models.py:14
+msgid "To render the stack in templates."
+msgstr ""
+
+#: models.py:16
+msgid "stack content"
+msgstr ""
+
+#: models.py:19 models.py:32
+msgid "stack"
+msgstr ""
+
+#: models.py:20
+msgid "stacks"
+msgstr ""
View
72 stacks/migrations/0001_initial.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'Stack'
+ db.create_table('stacks_stack', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(default='', max_length=255, blank=True)),
+ ('code', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, blank=True)),
+ ('content', self.gf('django.db.models.fields.related.ForeignKey')(related_name='stacks_contents', null=True, to=orm['cms.Placeholder'])),
+ ))
+ db.send_create_signal('stacks', ['Stack'])
+
+ # Adding model 'StackLink'
+ db.create_table('cmsplugin_stacklink', (
+ ('cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['cms.CMSPlugin'], unique=True, primary_key=True)),
+ ('stack', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['stacks.Stack'])),
+ ))
+ db.send_create_signal('stacks', ['StackLink'])
+
+
+ def backwards(self, orm):
+ # Deleting model 'Stack'
+ db.delete_table('stacks_stack')
+
+ # Deleting model 'StackLink'
+ db.delete_table('cmsplugin_stacklink')
+
+
+ models = {
+ 'cms.cmsplugin': {
+ 'Meta': {'object_name': 'CMSPlugin'},
+ 'changed_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 10, 0, 0)'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+ 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
+ 'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
+ 'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+ 'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+ 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
+ },
+ 'cms.placeholder': {
+ 'Meta': {'object_name': 'Placeholder'},
+ 'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
+ },
+ 'stacks.stack': {
+ 'Meta': {'object_name': 'Stack'},
+ 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'blank': 'True'}),
+ 'content': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stacks_contents'", 'null': 'True', 'to': "orm['cms.Placeholder']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'})
+ },
+ 'stacks.stacklink': {
+ 'Meta': {'object_name': 'StackLink', 'db_table': "'cmsplugin_stacklink'", '_ormbases': ['cms.CMSPlugin']},
+ 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
+ 'stack': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['stacks.Stack']"})
+ }
+ }
+
+ complete_apps = ['stacks']
View
0 stacks/migrations/__init__.py
No changes.
View
35 stacks/models.py
@@ -0,0 +1,35 @@
+import uuid
+from django.db import models
+from cms.models.fields import PlaceholderField
+from django.utils.translation import ugettext_lazy as _
+from cms.models.pluginmodel import CMSPlugin
+
+
+class Stack(models.Model):
+ name = models.CharField(
+ verbose_name=_(u'stack name'), max_length=255, blank=True, default='',
+ help_text=_(u'Descriptive name to identify this stack. Not displayed to users.'))
+ code = models.CharField(
+ verbose_name=_(u'stack code'), max_length=255, unique=True, blank=True,
+ help_text=_(u'To render the stack in templates.'))
+ content = PlaceholderField(
+ slotname=u'stack_content', verbose_name=_(u'stack content'), related_name='stacks_contents')
+
+ class Meta:
+ verbose_name = _(u'stack')
+ verbose_name_plural = _(u'stacks')
+
+ def __unicode__(self):
+ return self.name
+
+ def clean(self):
+ # TODO: check for clashes if the random code is already taken
+ if not self.code:
+ self.code = u'stack-%s' % uuid.uuid4()
+
+
+class StackLink(CMSPlugin):
+ stack = models.ForeignKey(Stack, verbose_name=_(u'stack'))
+
+ def __unicode__(self):
+ return self.stack.name
View
1 stacks/templates/cms/plugins/stacks.html
@@ -0,0 +1 @@
+{{ content }}
View
0 stacks/templatetags/__init__.py
No changes.
View
44 stacks/templatetags/stack_tags.py
@@ -0,0 +1,44 @@
+from classytags.arguments import Argument
+from classytags.core import Tag, Options
+from django import template
+from django.utils.safestring import mark_safe
+from cms.plugin_rendering import render_plugins
+from cms.plugins.utils import get_plugins
+from stacks import models as stack_models
+from stacks.models import Stack
+
+register = template.Library()
+
+
+class StackNode(Tag):
+ name = 'stack'
+ options = Options(
+ Argument('code', required=True),
+ 'as',
+ Argument('varname', required=False, resolve=False)
+ )
+
+ def render_tag(self, context, code, varname):
+ # TODO: language override (the reason this is not implemented, is that language selection is buried way
+ # down somewhere in some method called in render_plugins. There it gets extracted from the request
+ # and a language in request.GET always overrides everything.)
+ if not code:
+ # an empty string was passed in or the variable is not available in the context
+ return ''
+ # TODO: caching?
+ if isinstance(code, Stack):
+ stack = code
+ else:
+ stack, __ = stack_models.Stack.objects.get_or_create(code=code, defaults={'name': code})
+ # TODO: once we drop 2.3.x support we can just use the "render_plugin" templatetag
+ # instead of rendering html here.
+ placeholder = stack.content
+ plugins = get_plugins(context['request'], placeholder)
+ processors = ()
+ rendered_placeholder = mark_safe("".join(render_plugins(plugins, context, placeholder, processors)))
+ if varname:
+ context[varname] = rendered_placeholder
+ rendered_placeholder = u''
+ return rendered_placeholder
+
+register.tag(StackNode)

0 comments on commit dd8a863

Please sign in to comment.