Commits

Steve Losh committed 439a183 Merge

Merge.

Comments (0)

Files changed (4)

         obj.save()
 
         if not form.ignore_content:
-            content_data = [(k.split('_', 1)[1], v)
-                            for k, v in form.data.items()
-                            if k.startswith('content_')]
+            # Use the authoritative list of fields, because browsers won't send along
+            # boolean fields that are unchecked (False) at all.
 
-            for title, content in content_data:
-                pc = PageContent.objects.get(page=obj, cleaned_title=title)
-                pc.content = content
+            # This is ugly, but we have to do it.
+            #
+            # fields: list of (clean_field_title, field_type) pairs
+            # fieldnames: list of clean_field_title
+            # fieldtypes: dict of clean_field_title -> field_type pairs
+
+            fields = [(clean_field_title(f[0]), f[1])
+                      for f in stemplates.get_fields_bare(obj.template)]
+            fieldnames = [f[0] for f in fields]
+            fieldtypes = dict(fields)
+
+            # content is going to be a dict of
+            # clean_field_title -> cleaned data pairs
+
+            # Default to 0, because browsers won't even send along a field for
+            # a checkbox element that's unchecked.
+            content = dict([(f, 0) for f in fieldnames])
+
+            # Now update content with the appropriate data from the form.
+            for k, v in form.data.items():
+                if k.startswith('content_'):
+                    fieldname = k.split('_', 1)[1]
+                    fieldtype = fieldtypes[fieldname]
+
+                    if fieldtype == 'bool':
+                        v = 1
+
+                    content[fieldname] = v
+
+            for k, v in content.items():
+                pc = PageContent.objects.get(page=obj, cleaned_title=k)
+                pc.content = v
                 pc.save()
 
 
         else:
             initial = {}
             for pc in page.pagecontent_set.all():
-                initial['content_' + clean_field_title(pc.title)] = pc.get_content()
+                # Ugly hack to store booleans as text.
+                if pc.typ == 'bool':
+                    try:
+                        val = True if int(pc.content) else False
+                    except ValueError:
+                        val = True
+                else:
+                    val = pc.get_content()
+
+                initial['content_' + clean_field_title(pc.title)] = val
 
             content_form = stoat_forms.get_content_form(page.template, initial=initial)
 
 
     class Media:
         css = {
-            'all': ('stoat.css',),
+            'all': ('stoat.css',) + getattr(settings, 'STOAT_ADMIN_EXTRA_CSS', ()),
         }
-        js = ('stoat.js',)
+        js = ('stoat.js',) + getattr(settings, 'STOAT_ADMIN_EXTRA_JS', ())
 admin.site.register(Page, PageAdmin)
 
 
 
 CONTENT_TYPES = (
     ('char', 'char'),
+    ('bool', 'bool'),
     ('text', 'text'),
     ('ckeditor', 'ckeditor'),
     ('img', 'img'),
     ('file', 'file'),
     ('fk', 'fk'),
     ('int', 'int'),)
-TEMPLATES = [(name, name) for name in settings.STOAT_TEMPLATES.keys()]
+TEMPLATES = sorted([(name, name) for name in settings.STOAT_TEMPLATES.keys()])
 
 
 class Page(MP_Node):
         """Return a list of child Page objects."""
         return list(self.get_children().filter(show_in_nav=True))
 
+    def nav_next_sibling(self):
+        """ Return the next sibling object, or None if it was the rightmost sibling."""
+        siblings = self.nav_siblings()
+        next_sibling = None
+        for i, sibling in enumerate(siblings):
+            if sibling == self and i < len(siblings) - 1:
+                next_sibling = siblings[i+1]
+        return next_sibling
+
+    def nav_prev_sibling(self):
+        """ Return the previous sibling object, or None if it was the leftmost sibling."""
+        siblings = self.nav_siblings()
+        prev_sibling = None
+        for i, sibling in enumerate(siblings):
+            if sibling == self and i > 0:
+                prev_sibling = siblings[i-1]
+        return prev_sibling
+
     def nav_siblings_and_children(self):
         """Return a nested list of sibling/children Page objects (including this page)."""
         siblings = self.nav_siblings()
                 return model.objects.get(id=self.content)
             except model.DoesNotExist:
                 return None
+        elif self.typ == 'bool':
+            try:
+                result = True if int(self.content) else False
+            except ValueError:
+                result = True
+            return result
         elif self.typ in ['file', 'img']:
             from filebrowser.base import FileObject
             from django.conf import settings

stoat/search_indexes.py

 import datetime
 from haystack.indexes import *
 from haystack import site
+
+from django.conf import settings
+
 from models import Page
 
+INDEX_CLASS = getattr(settings, 'STOAT_HAYSTACK_INDEX_CLASS')
+if INDEX_CLASS:
+    module_name, index_name = INDEX_CLASS.rsplit('.', 1)
+    module = __import__(module_name, fromlist=[index_name])
 
-class PageIndex(SearchIndex):
+    index = getattr(module, index_name)
+else:
+    index = SearchIndex
+
+class PageIndex(index):
     text = CharField(document=True, use_template=True)
     title = CharField(model_attr='title')
 

stoat/tests/test_navigation.py

         test_sibs = set([p.url for p in page.nav_siblings()])
         self.assertTrue(real_sibs == test_sibs)
 
+    def test_nav_next_sibling(self):
+        page = get(Page, url='/')
+        real_sibs = set(['/', '/top-one/', '/top-two/'])
+        real_next_sib = '/top-one/'
+        self.assertTrue(real_next_sib == page.nav_next_sibling().url)
+
+        page = get(Page, url='/top-two/')
+        real_next_sib = None
+        self.assertTrue(real_next_sib == page.nav_next_sibling())
+
+    def test_nav_prev_sibling(self):
+        page = get(Page, url='/')
+        real_sibs = set(['/', '/top-one/', '/top-two/'])
+        real_prev_sib = None
+        self.assertTrue(real_prev_sib == page.nav_prev_sibling())
+
+        page = get(Page, url='/top-two/')
+        real_sibs = set(['/', '/top-one/', '/top-two/'])
+        real_prev_sib = '/top-one/'
+        self.assertTrue(real_prev_sib == page.nav_prev_sibling().url)
+
     def test_nav_children(self):
         page = get(Page, url='/')
         real_kids = set([])
         real_kids = set(['/top-one/one-sub/one-sub-sub/'])
         test_kids = set([p.url for p in page.nav_children()])
         self.assertTrue(real_kids == test_kids)
+
     def test_nav_siblings_and_children(self):
         def test_siblings(saclist, urllist):
             urls = set([sib.url for sib, children in saclist])