Permalink
Browse files

update cms/boxes to pycon parity

  • Loading branch information...
1 parent 1b04b7a commit 2665fd575869fa363a95958474ffd9453c500b7c @lukeman lukeman committed Jul 10, 2012
View
@@ -25,7 +25,7 @@ django_compressor==1.2a1
django-mptt==0.5.2
django-taggit==0.9.3
-django-reversion==1.5.1
+django-reversion==1.6.1
django-markitup==1.0.0
markdown==2.1.1
django-sitetree==0.6
No changes.
View
@@ -0,0 +1,6 @@
+from django.contrib import admin
+
+from symposion.boxes.models import Box
+
+
+admin.site.register(Box)
@@ -0,0 +1,20 @@
+from django.conf import settings
+
+from symposion.boxes.utils import load_path_attr
+
+
+def default_can_edit(request, *args, **kwargs):
+ """
+ This is meant to be overridden in your project per domain specific
+ requirements.
+ """
+ return request.user.is_staff or request.user.is_superuser
+
+
+def load_can_edit():
+ import_path = getattr(settings, "BOXES_CAN_EDIT_CALLABLE", None)
+
+ if import_path is None:
+ return default_can_edit
+
+ return load_path_attr(import_path)
View
@@ -0,0 +1,10 @@
+from django import forms
+
+from symposion.boxes.models import Box
+
+
+class BoxForm(forms.ModelForm):
+
+ class Meta:
+ model = Box
+ fields = ["content"]
View
@@ -0,0 +1,22 @@
+import datetime
+
+from django.db import models
+
+from django.contrib.auth.models import User
+
+from markitup.fields import MarkupField
+
+
+class Box(models.Model):
+
+ label = models.CharField(max_length=100, db_index=True)
+ content = MarkupField(blank=True)
+
+ created_by = models.ForeignKey(User, related_name="boxes")
+ last_updated_by = models.ForeignKey(User, related_name="updated_boxes")
+
+ def __unicode__(self):
+ return self.label
+
+ class Meta:
+ verbose_name_plural = "boxes"
No changes.
@@ -0,0 +1,41 @@
+from django import template
+from django.core.exceptions import ImproperlyConfigured
+from django.core.urlresolvers import reverse
+from django.utils.safestring import mark_safe
+from django.utils.encoding import smart_str
+from django.utils.translation import ugettext_lazy as _
+from django.template.defaulttags import kwarg_re
+
+from symposion.boxes.models import Box
+from symposion.boxes.forms import BoxForm
+from symposion.boxes.authorization import load_can_edit
+
+
+register = template.Library()
+
+
+@register.inclusion_tag("boxes/box.html", takes_context=True)
+def box(context, label, show_edit=True, *args, **kwargs):
+
+ request = context["request"]
+ can_edit = load_can_edit()(request, *args, **kwargs)
+
+ try:
+ box = Box.objects.get(label=label)
+ except Box.DoesNotExist:
+ box = None
+
+ if can_edit and show_edit:
+ form = BoxForm(instance=box, prefix=label)
+ form_action = reverse("box_edit", args=[label])
+ else:
+ form = None
+ form_action = None
+
+ return {
+ "request": request,
+ "label": label,
+ "box": box,
+ "form": form,
+ "form_action": form_action,
+ }
View
@@ -0,0 +1,6 @@
+from django.conf.urls.defaults import url, patterns
+
+
+urlpatterns = patterns("symposion.boxes.views",
+ url(r"^([-\w]+)/edit/$", "box_edit", name="box_edit"),
+)
View
@@ -0,0 +1,19 @@
+from django.core.exceptions import ImproperlyConfigured
+try:
+ from django.utils.importlib import import_module
+except ImportError:
+ from importlib import import_module
+
+
+def load_path_attr(path):
+ i = path.rfind(".")
+ module, attr = path[:i], path[i+1:]
+ try:
+ mod = import_module(module)
+ except ImportError, e:
+ raise ImproperlyConfigured("Error importing %s: '%s'" % (module, e))
+ try:
+ attr = getattr(mod, attr)
+ except AttributeError:
+ raise ImproperlyConfigured("Module '%s' does not define a '%s'" % (module, attr))
+ return attr
View
@@ -0,0 +1,45 @@
+from django.http import HttpResponseForbidden
+from django.shortcuts import redirect
+from django.views.decorators.http import require_POST
+
+from symposion.boxes.authorization import load_can_edit
+from symposion.boxes.forms import BoxForm
+from symposion.boxes.models import Box
+
+
+# @@@ problem with this is that the box_edit.html and box_create.html won't have domain objects in context
+def get_auth_vars(request):
+ auth_vars = {}
+ if request.method == "POST":
+ keys = [k for k in request.POST.keys() if k.startswith("boxes_auth_")]
+ for key in keys:
+ auth_vars[key.replace("boxes_auth_", "")] = request.POST.get(key)
+ auth_vars["user"] = request.user
+ return auth_vars
+
+
+@require_POST
+def box_edit(request, label):
+
+ if not load_can_edit()(request, **get_auth_vars(request)):
+ return HttpResponseForbidden()
+
+ next = request.GET.get("next")
+
+ try:
+ box = Box.objects.get(label=label)
+ except Box.DoesNotExist:
+ box = None
+
+ form = BoxForm(request.POST, instance=box, prefix=label)
+
+ if form.is_valid():
+ if box is None:
+ box = form.save(commit=False)
+ box.label = label
+ box.created_by = request.user
+ box.last_updated_by = request.user
+ box.save()
+ else:
+ form.save()
+ return redirect(next)
View
@@ -1,12 +1,6 @@
from django.contrib import admin
-from mptt.admin import MPTTModelAdmin
+from .models import Page
-from cms.models import Page
-
-class PageAdmin(MPTTModelAdmin):
- prepopulated_fields = {"slug": ("title",)}
- list_display = ("title", "published", "status")
-
-admin.site.register(Page, PageAdmin)
+admin.site.register(Page)
View
@@ -0,0 +1,16 @@
+from django import forms
+
+from markitup.widgets import MarkItUpWidget
+
+from .models import Page
+
+
+class PageForm(forms.ModelForm):
+
+ class Meta:
+ model = Page
+ fields = ["title", "body", "path"]
+ widgets = {
+ "body": MarkItUpWidget(),
+ "path": forms.HiddenInput(),
+ }
@@ -0,0 +1,9 @@
+from datetime import datetime
+
+from django.db import models
+
+class PublishedPageManager(models.Manager):
+
+ def get_query_set(self):
+ qs = super(PublishedPageManager, self).get_query_set()
+ return qs.filter(publish_date__lte=datetime.now())
View
@@ -1,65 +1,53 @@
+import re
from datetime import datetime
+from django.conf import settings
+from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _
from markitup.fields import MarkupField
from taggit.managers import TaggableManager
-from mptt.models import MPTTModel, TreeForeignKey
-from mptt.utils import drilldown_tree_for_node
-
import reversion
+from .managers import PublishedPageManager
+
-class ContentBase(models.Model):
+class Page(models.Model):
STATUS_CHOICES = (
(1, _("Draft")),
(2, _("Public")),
)
-
+
title = models.CharField(max_length=100)
- slug = models.CharField(max_length=100, blank=True, null=True)
+ path = models.CharField(max_length=100, unique=True)
body = MarkupField()
-
- tags = TaggableManager(blank=True)
-
status = models.IntegerField(choices=STATUS_CHOICES, default=2)
- published = models.DateTimeField(default=datetime.now)
+ publish_date = models.DateTimeField(default=datetime.now)
created = models.DateTimeField(editable=False, default=datetime.now)
updated = models.DateTimeField(editable=False, default=datetime.now)
-
- class Meta:
- abstract = True
-
-
-class Page(MPTTModel, ContentBase):
-
- parent = TreeForeignKey("self", null=True, blank=True, related_name="children")
- ordering = models.PositiveIntegerField(default=1)
- path = models.TextField(blank=True, editable=False)
-
+ tags = TaggableManager(blank=True)
+
+ published = PublishedPageManager()
+
def __unicode__(self):
return self.title
-
- def save(self, calculate_path=True, *args, **kwargs):
+
+ @models.permalink
+ def get_absolute_url(self):
+ return ("cms_page", [self.path])
+
+ def save(self, *args, **kwargs):
+ self.updated = datetime.now()
super(Page, self).save(*args, **kwargs)
- if calculate_path:
- self.calculate_path()
- def calculate_path(self):
- self.path = ""
- for page in drilldown_tree_for_node(self):
- if page == self:
- self.path += page.slug
- break
- else:
- self.path += "%s/" % page.slug
- self.save(calculate_path=False)
+ def clean_fields(self, exclude=None):
+ super(Page, self).clean_fields(exclude)
+ if not re.match(settings.SYMPOSION_PAGE_REGEX, self.path):
+ raise ValidationError({"path": [_("Path can only contain letters, numbers and hyphens and end with /"),]})
- class MPTTMeta:
- order_insertion_by = ["ordering", "title"]
reversion.register(Page)
View
@@ -0,0 +1,8 @@
+from django.conf.urls.defaults import url, patterns
+
+PAGE_RE = r"(([\w-]{1,})(/[\w-]{1,})*)/"
+
+urlpatterns = patterns("symposion.cms.views",
+ url(r"^(?P<path>%s)_edit/$" % PAGE_RE, "page_edit", name="cms_page_edit"),
+ url(r"^(?P<path>%s)$" % PAGE_RE, "page", name="cms_page"),
+)
View
@@ -1,15 +1,59 @@
-from django.shortcuts import render_to_response, get_object_or_404
+from django.http import Http404
+from django.shortcuts import render, redirect
from django.template import RequestContext
-from cms.models import Page
+from .models import Page
+from .forms import PageForm
-def page(request, slug):
+def can_edit(user):
+ if user.is_staff or user.is_superuser:
+ return True
+ if user.has_perm("cms.change_page"):
+ return True
+ return False
+
+
+def page(request, path):
- page = get_object_or_404(Page, path=slug)
- siblings = page.get_siblings(include_self=True)
+ editable = can_edit(request.user)
+ try:
+ page = Page.published.get(path=path)
+ except Page.DoesNotExist:
+ if editable:
+ return redirect("cms_page_edit", path=path)
+ else:
+ raise Http404
- return render_to_response("cms/page_detail.html", {
+ return render(request, "cms/page_detail.html", {
"page": page,
- "siblings": siblings,
- }, context_instance=RequestContext(request))
+ "editable": editable,
+ })
+
+
+def page_edit(request, path):
+
+ if not can_edit(request.user):
+ raise Http404
+
+ try:
+ page = Page.published.get(path=path)
+ except Page.DoesNotExist:
+ page = None
+
+ if request.method == "POST":
+ form = PageForm(request.POST, instance=page)
+ if form.is_valid():
+ page = form.save(commit=False)
+ page.path = path
+ page.save()
+ return redirect(page)
+ else:
+ print form.errors
+ else:
+ form = PageForm(instance=page, initial={"path": path})
+
+ return render(request, "cms/page_edit.html", {
+ "path": path,
+ "form": form
+ })
Oops, something went wrong.

0 comments on commit 2665fd5

Please sign in to comment.