Luke Plant avatar Luke Plant committed 3585aa1

Moved MenuLink and HtmlChunk to separate 'sitecontent' app

Comments (0)

Files changed (19)

cciw/cciwmain/admin.py

-from cciw.cciwmain.models import Site, Person, Camp, MenuLink, HtmlChunk
+from cciw.cciwmain.models import Site, Person, Camp
 from django.contrib import admin
 
 class SiteAdmin(admin.ModelAdmin):
     filter_horizontal = ('leaders', 'admins')
     date_hierarchy = 'start_date'
 
-class MenuLinkAdmin(admin.ModelAdmin):
-    list_display = ('title', 'url', 'listorder','visible','parent_item')
-
-class HtmlChunkAdmin(admin.ModelAdmin):
-    list_display = ('name', 'page_title', 'menu_link')
-
 admin.site.register(Site, SiteAdmin)
 admin.site.register(Person, PersonAdmin)
 admin.site.register(Camp, CampAdmin)
-admin.site.register(MenuLink, MenuLinkAdmin)
-admin.site.register(HtmlChunk, HtmlChunkAdmin)
-
-from django.contrib.auth import admin

cciw/cciwmain/common.py

         # instances.
         return context
 
-    from cciw.cciwmain.models import MenuLink
+    from cciw.sitecontent.models import MenuLink
     thisyear = get_thisyear()
     context['thisyear'] = thisyear
     assert type(request.path) is unicode

cciw/cciwmain/fixtures/basic.json

             "url": "/", 
             "listorder": 0
         }, 
-        "model": "cciwmain.menulink", 
+        "model": "sitecontent.menulink", 
         "pk": "1"
     }, 
     {

cciw/cciwmain/fixtures/contact.json

             "html": "\n<p>If you have an enquiry to make to the CCIW directors,\nplease use the form below and your message will be forwarded \nto the relevant person, who will reply by e-mail.</p>\n", 
             "page_title": ""
         }, 
-        "model": "cciwmain.htmlchunk", 
+        "model": "sitecontent.htmlchunk", 
         "pk": "feedback_intro"
     }, 
     {
             "html": "", 
             "page_title": ""
         }, 
-        "model": "cciwmain.htmlchunk", 
+        "model": "sitecontent.htmlchunk", 
         "pk": "feedback_outro"
     }
 ]

cciw/cciwmain/fixtures/htmlchunks.json

             "url": "/", 
             "listorder": 0
         }, 
-        "model": "cciwmain.menulink", 
+        "model": "sitecontent.menulink", 
         "pk": 1
     }, 
     {
             "html": "<p>CCIW is a charitable company that runs outdoor camps on a number of sites in Wales.\r\n The camps provide great outdoor fun with God and the Bible at the centre of each day.</p>\r\n<p>The detailed format of the day varies from camp to camp, but all of them \r\ninclude a morning service as a camp, activities in the afternoon and \r\nbible studies in the evening in tent groups.  The kind of activities we do \r\ninclude canoeing, raft-building, swimming, walking, rock-climbing, and gorge-walking, \r\nas well as football, rounders and other camp site games.  Below is \r\na list of other pages to find out more about the camps.</p>\r\n\r\n<h2>Contents:</h2>\r\n<ul>\r\n<li><a href=\"/news/\">News</a><br/>\r\nThe latest news, particularly about what is available on the website,\r\n is here, with the opportunity to add your own comments.\r\n\r\n<p>See also:</p>\r\n<ul><li><a href=\"/posts/\">Recent message board posts</a></li>\r\n<li><a href=\"/topics/\">Recently started topics</a></li>\r\n</ul>\r\n<br/><br/>\r\n</li>\r\n<li><a href=\"/thisyear/\">Camps {{thisyear}}</a><br/>\r\nInformation for camps in {{thisyear}}, including dates, leadership teams,\r\n and how to book.<br/><br/>\r\n</li>\r\n\r\n<li><a href=\"/camps/\">Camp forums and photos</a><br/>\r\nHere you can find photos and messages boards from the CCIW camps that have run in the past.\r\nHopefully these will give you an idea of what we do, or help you stay in contact with\r\nfriends you met on camp. <br/><br/>\r\nThe leaders and committee members have also lead and organised camps with churches and\r\nother organisations (particularly <a href=\"http://www.emw.org.uk/\">The Evangelical Movement of Wales</a>) for many years, and some photos of these camps\r\ncan be found here. <br/><br/>\r\n</li>\r\n\r\n<li><a href=\"/sites/\">Camp sites</a><br/>\r\nInformation on the different sites we run camps at.<br/><br/>\r\n</li>\r\n\r\n\r\n<li><a href=\"/members/\">Members</a><br/>\r\nList of currently signed up members to the website.  Look for your friends here!<br/><br/>\r\n</li>\r\n\r\n<li><a href=\"/info/\">About CCIW</a><br/>\r\nCompany information, including the doctrinal basis of CCIW, legal information, and the names and addresses of the directors. \r\n<br/>\r\n<br/></li>\r\n\r\n\r\n<li><a href=\"/website/\">About website</a><br/>\r\nInformation about the website, including message boards about the different features.<br/><br/>\r\n</li>\r\n\r\n<li><a href=\"/contact/\">Contact us</a><br/>\r\nAny comments about camp, suggestions, or other reasons to get in contact with us - leave us a message.<br/>\r\n<br/>\r\n</li>\r\n\r\n</ul>\r\n<br/>\r\n<p>CCIW is a limited company (reg. No. 3900844), and a Registered Charity (No:1079713)</p>", 
             "page_title": "Christian Camps in Wales"
         }, 
-        "model": "cciwmain.htmlchunk", 
+        "model": "sitecontent.htmlchunk", 
         "pk": "home_page"
     }
 ]

cciw/cciwmain/fixtures/users.json

             "last_login": "2007-12-17 18:49:13", 
             "groups": [], 
             "user_permissions": [
-                ["add_htmlchunk", "cciwmain", "htmlchunk"],
-                ["change_htmlchunk", "cciwmain", "htmlchunk"],
-                ["delete_htmlchunk", "cciwmain", "htmlchunk"]
+                ["add_htmlchunk", "sitecontent", "htmlchunk"],
+                ["change_htmlchunk", "sitecontent", "htmlchunk"],
+                ["delete_htmlchunk", "sitecontent", "htmlchunk"]
             ], 
             "password": "sha1$72713$4d655a356d9dfde29f74d04e8c40a6e412d26d0a", 
             "email": "editor@somewhere.com", 

cciw/cciwmain/migrations/0008_move_models_to_sitecontent_app.py

+# encoding: 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):
+        pass
+
+    def backwards(self, orm):
+        pass
+
+    depends_on = [
+        ('sitecontent', '0001_initial'),
+        ]
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'unique': 'True'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
+        },
+        'cciwmain.camp': {
+            'Meta': {'ordering': "['-year', 'number']", 'unique_together': "(('year', 'number'),)", 'object_name': 'Camp'},
+            'admins': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'camps_as_admin'", 'blank': 'True', 'null': 'True', 'to': "orm['auth.User']"}),
+            'age': ('django.db.models.fields.CharField', [], {'max_length': '3'}),
+            'chaplain': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'camps_as_chaplain'", 'blank': 'True', 'null': 'True', 'to': "orm['cciwmain.Person']"}),
+            'end_date': ('django.db.models.fields.DateField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'leaders': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'camps_as_leader'", 'blank': 'True', 'null': 'True', 'to': "orm['cciwmain.Person']"}),
+            'number': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
+            'officers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'through': "orm['officers.Invitation']", 'symmetrical': 'False'}),
+            'online_applications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'previous_camp': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'next_camps'", 'blank': 'True', 'null': 'True', 'to': "orm['cciwmain.Camp']"}),
+            'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cciwmain.Site']"}),
+            'start_date': ('django.db.models.fields.DateField', [], {}),
+            'year': ('django.db.models.fields.PositiveSmallIntegerField', [], {})
+        },
+        'cciwmain.person': {
+            'Meta': {'ordering': "('name',)", 'object_name': 'Person'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'info': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+            'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'cciwmain.site': {
+            'Meta': {'object_name': 'Site'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'info': ('django.db.models.fields.TextField', [], {}),
+            'long_name': ('django.db.models.fields.CharField', [], {'max_length': "'50'"}),
+            'short_name': ('django.db.models.fields.CharField', [], {'max_length': "'25'", 'unique': 'True'}),
+            'slug_name': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': "'25'", 'unique': 'True', 'blank': 'True'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'officers.invitation': {
+            'Meta': {'ordering': "('-camp__year', 'officer__first_name', 'officer__last_name')", 'unique_together': "(('officer', 'camp'),)", 'object_name': 'Invitation'},
+            'camp': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cciwmain.Camp']"}),
+            'date_added': ('django.db.models.fields.DateField', [], {'default': 'datetime.date.today'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'notes': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'officer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['cciwmain']

cciw/cciwmain/models.py

 import datetime
 
-from django.contrib.admin.views.main import quote
 from django.contrib.auth.models import User
 from django.db import models
 from django.utils.safestring import mark_safe
 
 from cciw.cciwmain import signals
-from cciw.cciwmain.common import standard_subs
-import cciw.middleware.threadlocals as threadlocals
 
 
 class Site(models.Model):
         unique_together = (('year', 'number'),)
 
 
-class MenuLink(models.Model):
-    title = models.CharField("title", max_length=50)
-    url = models.CharField("URL", max_length=100)
-    extra_title = models.CharField("Disambiguation title", max_length=100, blank=True)
-    listorder = models.SmallIntegerField("order in list")
-    visible = models.BooleanField("Visible", default=True)
-    parent_item = models.ForeignKey("self", null=True, blank=True,
-        verbose_name="Parent item (none = top level)",
-        related_name="child_links")
-
-    def __unicode__(self):
-        return  u"%s [%s]" % (self.url, standard_subs(self.title))
-
-    def get_visible_children(self, request):
-        """Gets a list of child menu links that should be visible given the current url"""
-        if request.path == self.url:
-            return self.child_links
-        else:
-            return []
-
-    class Meta:
-        # put top level items at top of list, others into groups, for the admin
-        ordering = ('-parent_item__id', 'listorder')
-
-
-class HtmlChunk(models.Model):
-    name = models.SlugField("name", primary_key=True, db_index=True)
-    html = models.TextField("HTML")
-    menu_link = models.ForeignKey(MenuLink, verbose_name="Associated URL",
-        null=True, blank=True)
-    page_title = models.CharField("page title (for chunks that are pages)", max_length=100,
-        blank=True)
-
-    def __unicode__(self):
-        return self.name
-
-    def render(self, request):
-        """Render the HTML chunk as HTML, with replacements
-        made and any member specific adjustments."""
-        html = standard_subs(self.html)
-        user = threadlocals.get_current_user()
-        if user and not user.is_anonymous() and user.is_staff \
-            and user.has_perm('cciwmain.change_htmlchunk'):
-            html += (u"""<div class="editChunkLink">&laquo;
-                        <a href="/admin/cciwmain/htmlchunk/%s/">Edit %s</a> &raquo;
-                        </div>""" % (quote(self.name), self.name))
-        return mark_safe(html)
-
-    class Meta:
-        verbose_name = "HTML chunk"
 
 
 import cciw.cciwmain.hooks

cciw/cciwmain/templatetags/standardpage.py

 from django.utils.http import urlquote, urlencode
 from django import template
-from cciw.cciwmain.models import HtmlChunk
+from cciw.sitecontent.models import HtmlChunk
 from cciw.forums.models import Member, Post, Topic, Photo
 from cciw.cciwmain.common import standard_subs, get_current_domain
 from cciw.cciwmain.utils import obfuscate_email

cciw/cciwmain/views/camps.py

 from django.http import HttpResponse, Http404, HttpResponseRedirect
 from django.conf import settings
 
-from cciw.cciwmain.models import Camp, HtmlChunk
+from cciw.cciwmain.models import Camp
 from cciw.forums.models import Forum, Gallery, Photo
 from cciw.forums.views import forums as forums_views
 from cciw.cciwmain.common import create_breadcrumb, get_thisyear, standard_subs
 from cciw.cciwmain.decorators import member_required
 from cciw.cciwmain.templatetags import bbcode
+from cciw.sitecontent.models import HtmlChunk
 import cciw.cciwmain.utils as utils
 
 

cciw/cciwmain/views/htmlchunk.py

 from django.http import Http404
 
 from cciw.cciwmain.common import *
-from cciw.cciwmain.models import HtmlChunk, MenuLink
+from cciw.sitecontent.models import MenuLink
 
 def find(request):
     try:

cciw/officers/fixtures/officers_users.json

                 ], 
                 [
                     "add_htmlchunk", 
-                    "cciwmain", 
+                    "sitecontent", 
                     "htmlchunk"
                 ], 
                 [
                     "change_htmlchunk", 
-                    "cciwmain", 
+                    "sitecontent", 
                     "htmlchunk"
                 ], 
                 [
                     "delete_htmlchunk", 
-                    "cciwmain", 
+                    "sitecontent", 
                     "htmlchunk"
                 ], 
                 [
                     "add_menulink", 
-                    "cciwmain", 
+                    "sitecontent", 
                     "menulink"
                 ], 
                 [
                     "change_menulink", 
-                    "cciwmain", 
+                    "sitecontent", 
                     "menulink"
                 ], 
                 [
                     "delete_menulink", 
-                    "cciwmain", 
+                    "sitecontent", 
                     "menulink"
                 ], 
                 [
     'django.contrib.sessions',
     'django.contrib.sites',
     'cciw.cciwmain',
+    'cciw.sitecontent',
     'cciw.forums',
     'cciw.officers',
     'cciw.utils',
Add a comment to this file

cciw/sitecontent/__init__.py

Empty file added.

cciw/sitecontent/admin.py

+from cciw.sitecontent.models import MenuLink, HtmlChunk
+from django.contrib import admin
+
+class MenuLinkAdmin(admin.ModelAdmin):
+    list_display = ('title', 'url', 'listorder','visible','parent_item')
+
+class HtmlChunkAdmin(admin.ModelAdmin):
+    list_display = ('name', 'page_title', 'menu_link')
+
+admin.site.register(MenuLink, MenuLinkAdmin)
+admin.site.register(HtmlChunk, HtmlChunkAdmin)

cciw/sitecontent/migrations/0001_initial.py

+# encoding: 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):
+
+        db.rename_table('cciwmain_menulink', 'sitecontent_menulink')
+        db.rename_table('cciwmain_htmlchunk', 'sitecontent_htmlchunk')
+
+
+    def backwards(self, orm):
+
+        db.rename_table('sitecontent_menulink', 'cciwmain_menulink')
+        db.rename_table('sitecontent_htmlchunk', 'cciwmain_htmlchunk')
+
+    models = {
+        'sitecontent.htmlchunk': {
+            'Meta': {'object_name': 'HtmlChunk'},
+            'html': ('django.db.models.fields.TextField', [], {}),
+            'menu_link': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sitecontent.MenuLink']", 'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'}),
+            'page_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
+        },
+        'sitecontent.menulink': {
+            'Meta': {'ordering': "('-parent_item__id', 'listorder')", 'object_name': 'MenuLink'},
+            'extra_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'listorder': ('django.db.models.fields.SmallIntegerField', [], {}),
+            'parent_item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'child_links'", 'blank': 'True', 'null': 'True', 'to': "orm['sitecontent.MenuLink']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'url': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+        }
+    }
+
+    complete_apps = ['sitecontent']

cciw/sitecontent/migrations/0002_content_types.py

+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+    tables = ['htmlchunk', 'menulink']
+
+    def forwards(self, orm):
+        for table in self.tables:
+            orm['contenttypes.ContentType'].objects.filter(app_label='cciwmain',
+                                                           model=table).update(app_label='sitecontent')
+
+    def backwards(self, orm):
+        for table in self.tables:
+            orm['contenttypes.ContentType'].objects.filter(app_label='sitecontent',
+                                                           model=table).update(app_label='cciwmain')
+
+
+    models = {
+        'sitecontent.htmlchunk': {
+            'Meta': {'object_name': 'HtmlChunk'},
+            'html': ('django.db.models.fields.TextField', [], {}),
+            'menu_link': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sitecontent.MenuLink']", 'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'}),
+            'page_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
+        },
+        'sitecontent.menulink': {
+            'Meta': {'ordering': "('-parent_item__id', 'listorder')", 'object_name': 'MenuLink'},
+            'extra_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'listorder': ('django.db.models.fields.SmallIntegerField', [], {}),
+            'parent_item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'child_links'", 'blank': 'True', 'null': 'True', 'to': "orm['sitecontent.MenuLink']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'url': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+    }
+
+    complete_apps = ['sitecontent']
Add a comment to this file

cciw/sitecontent/migrations/__init__.py

Empty file added.

cciw/sitecontent/models.py

+from django.core.urlresolvers import reverse
+from django.db import models
+from django.utils.safestring import mark_safe
+
+from cciw.cciwmain.common import standard_subs
+import cciw.middleware.threadlocals as threadlocals
+
+
+class MenuLink(models.Model):
+    title = models.CharField("title", max_length=50)
+    url = models.CharField("URL", max_length=100)
+    extra_title = models.CharField("Disambiguation title", max_length=100, blank=True)
+    listorder = models.SmallIntegerField("order in list")
+    visible = models.BooleanField("Visible", default=True)
+    parent_item = models.ForeignKey("self", null=True, blank=True,
+        verbose_name="Parent item (none = top level)",
+        related_name="child_links")
+
+    def __unicode__(self):
+        return  u"%s [%s]" % (self.url, standard_subs(self.title))
+
+    def get_visible_children(self, request):
+        """Gets a list of child menu links that should be visible given the current url"""
+        if request.path == self.url:
+            return self.child_links
+        else:
+            return []
+
+    class Meta:
+        # put top level items at top of list, others into groups, for the admin
+        ordering = ('-parent_item__id', 'listorder')
+
+
+class HtmlChunk(models.Model):
+    name = models.SlugField("name", primary_key=True, db_index=True)
+    html = models.TextField("HTML")
+    menu_link = models.ForeignKey(MenuLink, verbose_name="Associated URL",
+        null=True, blank=True)
+    page_title = models.CharField("page title (for chunks that are pages)", max_length=100,
+        blank=True)
+
+    def __unicode__(self):
+        return self.name
+
+    def render(self, request):
+        """Render the HTML chunk as HTML, with replacements
+        made and any member specific adjustments."""
+        html = standard_subs(self.html)
+        user = threadlocals.get_current_user()
+        if user and not user.is_anonymous() and user.is_staff \
+            and user.has_perm('sitecontent.change_htmlchunk'):
+            html += (u"""<div class="editChunkLink">&laquo;
+                        <a href="%s">Edit %s</a> &raquo;
+                        </div>""" % (reverse("admin:sitecontent_htmlchunk_change", args=[self.name]),
+                                     self.name))
+        return mark_safe(html)
+
+    class Meta:
+        verbose_name = "HTML chunk"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.