Commits

Luke Plant committed 40f7494 Merge

Merged from default

  • Participants
  • Parent commits 89d121e, 34ea494
  • Branches live

Comments (0)

Files changed (19)

File cciw/cciwmain/common.py

 import urllib
 
 
-def standard_extra_context(title=None, description=None, keywords=None):
-    """
-    Gets the 'extra_dict' dictionary used for all pages
-    """
-    from cciw.cciwmain.models import Member
-
-    if title is None:
-        title = u"Christian Camps in Wales"
-    if description is None:
-        description = u"Details of camps, message boards and photos for the UK charity Christian Camps in Wales"
-    if keywords is None:
-        keywords = u"camp, camps, summer camp, Christian, Christian camp, charity"
-
-    extra_dict = {}
-    extra_dict['title'] = title
-    extra_dict['meta_description'] = description
-    extra_dict['meta_keywords'] = keywords
-    extra_dict['thisyear'] = get_thisyear()
-    extra_dict['misc'] = {
-        'logged_in_members':
-            Member.objects.filter(last_seen__gte=datetime.datetime.now() \
-                                           - datetime.timedelta(minutes=3)).count(),
-    }
-
-    return extra_dict
-
-
-# CBV equivalent to standard_extra_context (and other base class functionality)
+# CBV baseclass functionality
 class DefaultMetaData(object):
     """
     Mixin that provides some default metadata and other standard variables to the
      * After the instance has been initialised, 'context'
        will be available on the instance as a place to store context data.
     """
-    metadata_title=u"Christian Camps in Wales"
-    metadata_description= u"Details of camps, message boards and photos for the UK charity Christian Camps in Wales"
-    metadata_keywords = u"camp, camps, summer camp, Christian, Christian camp, charity"
+    metadata_title = None
+    metadata_description = None
+    metadata_keywords = None
     extra_context = None
 
     def __init__(self, **kwargs):
         return super(DefaultMetaData, self).__init__(**kwargs)
 
     def get_context_data(self, **kwargs):
-        from cciw.cciwmain.models import Member
-        d = standard_extra_context(title=self.metadata_title,
-                                   description=self.metadata_description,
-                                   keywords=self.metadata_keywords)
-        # Allow context to overwrite standard_extra_context
+        d = dict(title=self.metadata_title,
+                 description=self.metadata_description,
+                 keywords=self.metadata_keywords)
+        # Allow context to overwrite
         d.update(self.context)
         c = super(DefaultMetaData, self).get_context_data(**kwargs)
         c.update(d)
         return context
 
     from cciw.cciwmain.models import MenuLink
+    thisyear = get_thisyear()
+    context['thisyear'] = thisyear
     assert type(request.path) is unicode
     context['homepage'] = (request.path == u"/")
     links = MenuLink.objects.filter(parent_item__isnull=True, visible=True)
 
     # Ugly special casing for 'thisyear' camps
-    m = re.match(u'/camps/%s/(\d+)/' % unicode(get_thisyear()),  request.path)
+    m = re.match(u'/camps/%s/(\d+)/' % unicode(thisyear),  request.path)
     if m is not None:
         request_path = u'/thisyear/%s/' % m.groups()[0]
     else:

File cciw/cciwmain/decorators.py

 from django.http import HttpResponse, HttpResponseRedirect
 from django import template
-from django.shortcuts import render_to_response
+from django.shortcuts import render
 from django.core.mail import mail_admins
 
 from cciw.middleware.threadlocals import get_current_member, set_member_session
-from cciw.cciwmain.common import standard_extra_context
 from cciw.cciwmain.utils import python_to_json
 
 import urllib
 ERROR_MESSAGE = u"Please enter a correct username and password. Note that both fields are case-sensitive."
 
 def _display_login_form(request, error_message='', login_page=False):
-    c = template.RequestContext(request, standard_extra_context(title="Login"))
-    return render_to_response('cciw/members/login.html', {
-        'app_path': request.get_full_path(),
-        'error_message': error_message
-    }, context_instance=c)
+    return render(request, 'cciw/members/login.html', {'app_path': request.get_full_path(),
+                                                       'error_message': error_message,
+                                                       'title': "Login"})
 
 def member_required_generic(except_methods):
     """Returns a decorator that forces a member to be logged in to access the view.

File cciw/cciwmain/tests/forums.py

             post = Post.create_post(member, "Message %s" % i, topic, None)
 
         request = self.factory.get(self.forum.get_absolute_url())
-        with self.assertNumQueries(5):
+        with self.assertNumQueries(FuzzyInt(1, 5)):
             resp = forums.topicindex(request, title="Title", forum=self.forum)
             resp.render()
             expected_count = settings.FORUM_PAGINATE_TOPICS_BY * 2
             post = Post.create_post(member, "Message %s" % i, topic, None)
 
         request = self.factory.get(self.path())
-        with self.assertNumQueries(4):
+        with self.assertNumQueries(FuzzyInt(3, 4)):
             resp = forums.all_topics(request)
             resp.render()
             expected_count = settings.FORUM_PAGINATE_TOPICS_BY
                                 count=FuzzyInt(expected_count, expected_count + 2))
 
         request = self.factory.get(self.path(), {'format':'atom'})
-        with self.assertNumQueries(2):
+        with self.assertNumQueries(FuzzyInt(1, 2)):
             forums.all_topics(request)
 
 
         init_query_caches()
 
         request = self.factory.get(self.topic.get_absolute_url())
-        with self.assertNumQueries(6):
+        with self.assertNumQueries(FuzzyInt(1, 6)):
             forums.topic(request, title_start="Title", topicid=self.topic.id).render()
 
         request = self.factory.get(self.topic.get_absolute_url(), {'format':'atom'})
-        with self.assertNumQueries(2):
+        with self.assertNumQueries(FuzzyInt(1, 2)):
             forums.topic(request, title_start="Title", topicid=self.topic.id)
 
 
             post = Post.create_post(member, "Message %s" % i, topic=topic)
 
         request = self.factory.get(self.path())
-        with self.assertNumQueries(4):
+        with self.assertNumQueries(FuzzyInt(1, 4)):
             resp = forums.all_posts(request)
             resp.render()
             expected_count = settings.FORUM_PAGINATE_POSTS_BY
                                 count=FuzzyInt(expected_count, expected_count + 2))
 
         request = self.factory.get(self.path(), {'format':'atom'})
-        with self.assertNumQueries(2):
+        with self.assertNumQueries(FuzzyInt(1, 2)):
             forums.all_posts(request)
 
     def test_query_count_photos(self):
             post = Post.create_post(member, "Message %s" % i, photo=photo)
 
         request = self.factory.get(self.path())
-        with self.assertNumQueries(4):
+        with self.assertNumQueries(FuzzyInt(1, 3)):
             resp = forums.all_posts(request)
             resp.render()
             expected_count = settings.FORUM_PAGINATE_POSTS_BY
                                 count=FuzzyInt(expected_count, expected_count + 2))
 
         request = self.factory.get(self.path(), {'format':'atom'})
-        with self.assertNumQueries(2):
+        with self.assertNumQueries(FuzzyInt(1, 2)):
             forums.all_posts(request)
 
 

File cciw/cciwmain/tests/members.py

 from cciw.cciwmain.models import Member, Message
 from cciw.cciwmain.tests.client import CciwClient, RequestFactory
 from cciw.cciwmain.tests.mailhelpers import read_email_url
-from cciw.cciwmain.tests.utils import init_query_caches
+from cciw.cciwmain.tests.utils import init_query_caches, FuzzyInt
 from cciw.utils.tests.twillhelpers import TwillMixin, make_twill_url
 import cciw.cciwmain.decorators
 import cciw.cciwmain.views.members
         from cciw.cciwmain.views.members import index
 
         request = self.factory.get(reverse('cciwmain.members.index'))
-        with self.assertNumQueries(4):
+        with self.assertNumQueries(FuzzyInt(1, 4)):
             index(request).render()
 
-
         request = self.factory.get(reverse('cciwmain.members.index'), {'format':'atom'})
         with self.assertNumQueries(1):
             index(request)
         for i in xrange(settings.MEMBERS_PAGINATE_MESSAGES_BY):
             self._send_message("Message %s" % i)
 
-        with self.assertNumQueries(8):
+        with self.assertNumQueries(FuzzyInt(1, 8)):
             resp = self._get_inbox()
             resp.render()
 

File cciw/cciwmain/tests/news.py

             post = Post.create_post(member, "Message %s" % i, topic, None)
 
         request = factory.get(path)
-        with self.assertNumQueries(5):
+        with self.assertNumQueries(FuzzyInt(1, 5)):
             resp = forums.news(request)
             resp.render()
             expected_count = settings.FORUM_PAGINATE_NEWS_BY

File cciw/cciwmain/views/__init__.py

 from django import http
 from django.template import RequestContext, loader
+
+
 def handler404(request, template_name='404.html'):
     t = loader.get_template(template_name)
     return http.HttpResponseNotFound(t.render(RequestContext(request)))

File cciw/cciwmain/views/camps.py

 import datetime
 
-from django.shortcuts import render_to_response
-from django.template import RequestContext
+from django.shortcuts import render
 from django.http import HttpResponse, Http404, HttpResponseRedirect
 from django.conf import settings
 
 from cciw.cciwmain.models import Camp, HtmlChunk, Forum, Gallery, Photo
-from cciw.cciwmain.common import standard_extra_context, create_breadcrumb, get_thisyear, standard_subs
+from cciw.cciwmain.common import create_breadcrumb, get_thisyear, standard_subs
 from cciw.cciwmain.decorators import member_required
 from cciw.cciwmain.templatetags import bbcode
 import cciw.cciwmain.utils as utils
         camps
             List of all Camp objects (or all Camp objects in the specified year).
     """
-    c = standard_extra_context()
+    c = {}
     c['title'] = u"Camp forums and photos"
     all_camps = Camp.objects.filter(end_date__lte=datetime.datetime.today())
     if (year == None):
             raise Http404
     c['camps'] = camps
 
-    return render_to_response('cciw/camps/index.html',
-            context_instance=RequestContext(request, c))
+    return render(request, 'cciw/camps/index.html', c)
 
 def detail(request, year, number):
     """
     except Camp.DoesNotExist:
         raise Http404
 
-    c = RequestContext(request, standard_extra_context())
+    c = {}
     c['camp'] = camp
     c['title'] = camp.nice_name
 
         c['breadcrumb'] = create_breadcrumb(year_forum_breadcrumb(unicode(camp.year)) + [camp.nice_name])
     else:
         c['breadcrumb'] = create_breadcrumb([standard_subs(u'<a href="/thisyear/">Camps {{thisyear}}</a>'), "Camp " + number])
-    return render_to_response('cciw/camps/detail.html', context_instance=c)
+    return render(request, 'cciw/camps/detail.html', c)
 
 def thisyear(request):
-    c = RequestContext(request,
-                       standard_extra_context(title=u"Camps %d" % get_thisyear()))
+    c = dict(title=u"Camps %d" % get_thisyear())
     c['camps'] = Camp.objects.filter(year=get_thisyear()).order_by('number')
-    return render_to_response('cciw/camps/thisyear.html', context_instance=c)
+    return render(request, 'cciw/camps/thisyear.html', c)
 
 def get_forum_for_camp(camp):
     location = camp.get_absolute_url()[1:] + 'forum/'
         title = u"%s - Forum" % camp.nice_name
         breadcrumb_extra = camp_forum_breadcrumb(camp)
 
-    c = standard_extra_context(title=title)
+    c = dict(title=title)
     return forums_views.topicindex(request, extra_context=c, forum=forum,
         template_name='cciw/forums/topicindex.html', breadcrumb_extra=breadcrumb_extra)
 
 
     breadcrumb_extra = camp_forum_breadcrumb(camp)
 
-    ec = standard_extra_context(title=camp.nice_name + " - Photos")
+    ec = dict(title=camp.nice_name + " - Photos")
     return forums_views.photoindex(request, gallery, ec, breadcrumb_extra)
 
 def oldcampgallery(request, year, galleryname):
 
     breadcrumb_extra = year_forum_breadcrumb(year) + [utils.unslugify(galleryname)]
 
-    ec = standard_extra_context(title=utils.unslugify(year+", " + galleryname) + " - Photos")
+    ec = dict(title=utils.unslugify(year+", " + galleryname) + " - Photos")
     return forums_views.photoindex(request, gallery, ec, breadcrumb_extra)
 
 def photo(request, year, number, photonumber):
     except Photo.DoesNotExist:
         raise Http404
 
-    ec = standard_extra_context(title=u"Photos: %s" % camp.nice_name)
+    ec = dict(title=u"Photos: %s" % camp.nice_name)
 
     return forums_views.photo(request, photo, ec, breadcrumb_extra)
 
     except Photo.DoesNotExist:
         raise Http404
 
-    ec = standard_extra_context(title=u"%s, %s - Photos" %
-                                (utils.unslugify(year), utils.unslugify(galleryname)))
+    ec = dict(title=u"%s, %s - Photos" %
+              (utils.unslugify(year), utils.unslugify(galleryname)))
     return forums_views.photo(request, photo, ec, breadcrumb_extra)
 
 def camp_forum_breadcrumb(camp):

File cciw/cciwmain/views/forums.py

 
 from django.views.generic.edit import ModelFormMixin
 from django.http import Http404, HttpResponseForbidden, HttpResponseRedirect
-from django.template import RequestContext
-from django.shortcuts import render_to_response
+from django.shortcuts import render
 from django.conf import settings
 from django import forms
 from django.forms import widgets
 from django.utils.safestring import mark_safe
 
 from cciw.cciwmain.models import Forum, Topic, Photo, Post, Member, VoteInfo, NewsItem, Permission, Poll, PollOption
-from cciw.cciwmain.common import create_breadcrumb, standard_extra_context, get_order_option, object_list, DefaultMetaData, AjaxyFormView
+from cciw.cciwmain.common import create_breadcrumb, get_order_option, object_list, DefaultMetaData, AjaxyFormView
 from cciw.middleware.threadlocals import get_current_member
 from cciw.cciwmain.decorators import login_redirect
 from django.utils.html import escape
     resp = feeds.handle_feed_request(request, feeds.forum_topic_feed(forum), query_set=topics)
     if resp: return resp
 
+    # Title could be either in extra_context or in title
     if extra_context is None:
-        if title is None:
-            raise Exception("No title provided for page")
-        extra_context = standard_extra_context(title=title)
+        extra_context = {}
+    if title is not None:
+        extra_context['title'] = title
 
     extra_context['forum'] = forum
     extra_context['atom_feed_title'] = u"Atom feed for new topics on this board."
     forum = _get_forum_or_404(request.path, 'add/')
 
     cur_member = get_current_member()
-    context = RequestContext(request, standard_extra_context(title='Add topic'))
+    context = dict(title='Add topic')
 
     if not forum.open:
         context['message'] = u'This forum is closed - new topics cannot be added.'
     if breadcrumb_extra is None:
         breadcrumb_extra = []
     context['breadcrumb'] = create_breadcrumb(breadcrumb_extra + topic_breadcrumb(forum, None))
-    return render_to_response('cciw/forums/add_topic.html', context_instance=context)
+    return render(request, 'cciw/forums/add_topic.html', context)
 
 # Called directly as a view for /website/forum/, and used by other views
 @member_required
     if not cur_member.has_perm(Permission.NEWS_CREATOR):
         return HttpResponseForbidden("Permission denied")
 
-    context = RequestContext(request, standard_extra_context(title='Add short news item'))
+    context = dict(title='Add short news item')
 
     if not forum.open:
         context['message'] = 'This forum is closed - new news items cannot be added.'
     if breadcrumb_extra is None:
         breadcrumb_extra = []
     context['breadcrumb'] = create_breadcrumb(breadcrumb_extra + topic_breadcrumb(forum, None))
-    return render_to_response('cciw/forums/add_news.html', context_instance=context)
+    return render(request, 'cciw/forums/add_news.html', context)
 
 def update_poll_options(poll, new_option_list):
     """Takes a Poll object and a list of strings,
     title = topic.subject[0:40]
     if len(title_start) > 0:
         title = title_start + u": " + title
-    extra_context = standard_extra_context(title=title)
+    extra_context = dict(title=title)
 
     if breadcrumb_extra is None:
         breadcrumb_extra = []
         paginate_by=settings.FORUM_PAGINATE_POSTS_BY)
 
 def all_posts(request):
-    context = standard_extra_context(title=u"Recent posts")
+    context = dict(title=u"Recent posts")
     posts = Post.objects.exclude(posted_at__isnull=True).order_by('-posted_at').select_related('topic__forum', 'photo__gallery', 'posted_by')
 
     resp = feeds.handle_feed_request(request, feeds.PostFeed, query_set=posts)
     return HttpResponseRedirect(url)
 
 def all_topics(request):
-    context = standard_extra_context(title=u"Recent new topics")
+    context = dict(title=u"Recent new topics")
     topics = Topic.objects.exclude(created_at__isnull=True).order_by('-created_at').select_related('forum', 'started_by')
 
     resp = feeds.handle_feed_request(request, feeds.TopicFeed, query_set=topics)

File cciw/cciwmain/views/htmlchunk.py

-from django import template
-from django.shortcuts import render_to_response
+from django.shortcuts import render
 from django.http import Http404
-from django.template import RequestContext
 
 from cciw.cciwmain.common import *
 from cciw.cciwmain.models import HtmlChunk, MenuLink
     except IndexError:
         raise Http404()
 
-    c = RequestContext(request, standard_extra_context(title=chunk.page_title))
+    c = dict(title=chunk.page_title)
     c['contentBody'] = chunk.render(request)
-    return render_to_response('cciw/standard.html', context_instance=c)
+    return render(request, 'cciw/standard.html', c)

File cciw/cciwmain/views/memberadmin.py

 """Administrative views for members (signup, password change etc)"""
-from django import shortcuts, template
+from django.shortcuts import render
 from django.core import mail
 from django.contrib import messages
 from django.contrib.sites.models import Site
 from django.utils.crypto import salted_hmac
 from django.views.generic.edit import ModelFormMixin
 from django import forms
-from cciw.cciwmain.common import standard_extra_context, DefaultMetaData, AjaxyFormView, member_username_re
+from cciw.cciwmain.common import DefaultMetaData, AjaxyFormView, member_username_re
 from cciw.cciwmain.models import Member
 from cciw.middleware.threadlocals import set_member_session, get_current_member
 from cciw.cciwmain.decorators import member_required
 # a user's e-mails).
 NEW_PASSWORD_EXPIRY = 5
 
+
 class ValidationError(Exception):
     pass
 
+
 # Ideally would add synchronize lock here, but YAGNI with any imaginable amount of traffic
 def create_user(user_name, password1, password2):
     if member_username_re.match(user_name) is None:
                     "%s/%s/%s" % (settings.MEDIA_ROOT, settings.MEMBER_ICON_PATH, iconfilename))
         return m
 
+
 def email_hash(email):
     """Gets a hash of an email address, to be used in the signup process"""
     # Use every other character to make it shorter and friendlier
     return salted_hmac("cciw.cciwmain.memberadmin.signupemail", email).hexdigest()[::2]
 
+
 def email_address_used(email):
     return Member.all_objects.filter(email__iexact=email).count() != 0
 
+
 def random_password():
     chars = list(string.lowercase)
     random.shuffle(chars)
     return ''.join(chars[0:8])
 
+
 def validate_email_and_hash(email, hash):
     if email_address_used(email):
         # in reality shouldn't get here, unless user has
     else:
         return (True, '')
 
+
 def email_and_username_hash(email, user_name):
     """Gets a hash of an email address + user_name"""
     # Use every other character to make it shorter and friendlier
     else:
         return (True, '')
 
+
 def send_signup_mail(email):
     mail.send_mail("CCIW - Sign-up instructions",
 """Thank you for beginning the sign-up process on the CCIW website
 """ % {'domain': common.get_current_domain(), 'email': urllib.quote(email), 'hash': email_hash(email)},
 "website@cciw.co.uk", [email])
 
+
 def send_username_reminder(member):
     mail.send_mail("CCIW - user name reminder",
 """You requested a user name reminder on the CCIW website.
 """ % {'domain': common.get_current_domain(), 'user_name': member.user_name },
     "website@cciw.co.uk", [member.email])
 
+
 def send_newpassword_email(member):
     # Create a new password
     password = random_password()
        'password': password, 'hash': hash},
     "website@cciw.co.uk", [member.email])
 
+
 def create_new_password_hash(password, user_name):
     # Create string used to verify user_name and date.
     hash_str = u':'.join([datetime.date.today().isoformat(), user_name, password])
     return base64.urlsafe_b64encode(hash_str.encode("utf-8"))
 
+
 def extract_new_password(hash, user_name):
     """Extracts the new password from the hash, throwing a ValidationError
     containing an error message if it fails."""
 #################  VIEW FUNCTIONS #####################
 
 def signup(request):
-    c = standard_extra_context(title="Sign up")
+    c = dict(title="Sign up")
 
     if not request.POST and not request.GET:
         ######## 1. START #########
             c['stage'] = 'invalid'
             c['error_message'] = msg
 
-    ## Do this at end, so that the context_processors
-    ## are executed after set_member_session
-    ctx = template.RequestContext(request, c)
-
-    return shortcuts.render_to_response('cciw/members/signup.html',
-        context_instance=ctx)
+    # RequestContext should be created at the end, so that the
+    # context_processors are executed after set_member_session
+    return render(request, 'cciw/members/signup.html', c)
 
 
 def help_logging_in(request):
     """View that has reset password and username reminder functionality."""
-    c = standard_extra_context(title="Logging in problems.")
+    c = dict(title="Logging in problems.")
     if request.method == 'POST':
         # Check e-mail
         email = request.POST.get('email', '').strip()
                 send_newpassword_email(member)
                 c['success_message'] = "An e-mail has been sent to you with a new password."
 
-    ctx = template.RequestContext(request, c)
-    return shortcuts.render_to_response('cciw/members/help_logging_in.html', context_instance=ctx)
+    return render(request, 'cciw/members/help_logging_in.html', c)
 
 
 def change_password(request):
     user_name = request.GET.get('u', '')
     hash = request.GET.get('h', '')
 
-    c = standard_extra_context(title="Change password")
+    c = dict(title="Change password")
     if user_name:
         # New password from e-mail
         try:
             else:
                 c['error_message'] = error_message
 
-    ctx = template.RequestContext(request, c)
-    return shortcuts.render_to_response('cciw/members/change_password.html',
-            context_instance=ctx)
+    return render(request, 'cciw/members/change_password.html', c)
+
 
 def change_email(request):
     """View that responds to links in the 'change e-mail' emails."""
-    c = standard_extra_context(title="Change email")
+    c = dict(title="Change email")
 
     user_name = request.GET.get('u')
     email = request.GET.get('email', '')
     else:
         c['error_message'] = msg
 
-    ctx = template.RequestContext(request, c)
-    return shortcuts.render_to_response('cciw/members/change_email.html',
-            context_instance=ctx)
+    return render(request, 'cciw/members/change_email.html', c)
+
 
 preferences_fields = ["real_name", "email", "show_email", "comments", "message_option", "icon"]
 class PreferencesForm(CciwFormMixin, forms.ModelForm):

File cciw/cciwmain/views/services.py

 import urllib
 from django.conf import settings
-from django import shortcuts
-from django.template import RequestContext
+from django.shortcuts import render
 from django.utils.safestring import mark_safe
 
-from cciw.cciwmain.common import standard_extra_context
-
 options = [ 'output-format=html',
             'include-footnotes=0' # otherwise we'll have to strip them out in the javascript function.
         ]
     passage = request.GET.get('passage', '')
     url = esv_base_url % urllib.urlencode({'passage':passage})
     page = urllib.urlopen(url)
-    c = standard_extra_context(title="Bible passage lookup")
+    c = {}
+    c['title'] = "Bible passage lookup"
     c['passagetext'] = mark_safe(page.read())
     c['passage'] = passage
-    return shortcuts.render_to_response('cciw/services/esv_passage.html',
-            context_instance=RequestContext(request, c))
+    return render(request,'cciw/services/esv_passage.html', c)
 
 

File cciw/officers/tests/crbs.py

-from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
-from django.test import TestCase
-from twill.shell import TwillCommandLoop
-from twill import commands as tc
-
-from cciw.officers.tests.references import OFFICER, LEADER
-from cciw.utils.tests.twillhelpers import TwillMixin, make_django_url, make_twill_url
-
-
-class CRBForm(TwillMixin, TestCase):
-
-    fixtures = ['basic.json', 'officers_users.json']
-
-    def test_add_crb(self):
-        self._twill_login(OFFICER)
-        u = User.objects.get(username=OFFICER[0])
-        assert len(u.crbapplication_set.all()) == 0
-        tc.go(make_django_url('cciw.officers.views.add_crb'))
-        tc.code(200)
-        tc.formvalue('1', 'crb_number', '123456')
-        tc.formvalue('1', 'completed', '2010-05-06')
-        tc.submit()
-        tc.url(reverse('cciw.officers.views.index'))
-        self.assertEqual(len(u.crbapplication_set.all()), 1)

File cciw/officers/urls.py

     (r'^ref/(?P<ref_id>\d+)-(?P<prev_ref_id>\d*)-(?P<hash>.*)/$', 'create_reference_form'),
     (r'^ref/thanks/$', 'create_reference_thanks'),
     (r'^add-officer/$', 'create_officer'),
-    (r'^add-crb/$', 'add_crb'),
     (r'^files/(.*)$', 'officer_files'),
     url(r'^info/$', TemplateView.as_view(template_name='cciw/officers/info.html'), name="cciw.officers.views.info"),
 )

File cciw/officers/views.py

     return render(request, 'cciw/officers/stats.html', d)
 
 
-class AddCrbForm(forms.ModelForm):
-    class Meta:
-        model = CRBApplication
-        fields = ('crb_number',
-                  'completed',
-                  )
-AddCrbForm.base_fields['completed'].widget = widgets.AdminDateWidget()
-
-@staff_member_required
-def add_crb(request):
-    """
-    Form for an officer to add info about their CRB applications
-    """
-    if request.method == "POST":
-        form = AddCrbForm(request.POST)
-        if form.is_valid():
-            obj = form.save(commit=False)
-            obj.officer = request.user
-            obj.save()
-            messages.info(request, "CRB information added, thank you.")
-            return HttpResponseRedirect(reverse('cciw.officers.views.index'))
-    else:
-        form = AddCrbForm()
-    c = {'form': form}
-
-    return render(request, 'cciw/officers/add_crb.html', c)
-
-
 @staff_member_required
 @camp_admin_required
 def manage_crbs(request, year=None):

File cciw/utils/tests/twillhelpers.py

         tc.fv(1, 'id_username', creds[0])
         tc.fv(1, 'id_password', creds[1])
         tc.submit()
+        tc.code(200)
 
     def _twill_logout(self):
         twill.get_browser().clear_cookies()

File templates/cciw/base.html

 <!DOCTYPE html>
 <html lang="en-gb">
 <head>
-<title>{% block title %}CCIW: {{ title }}{% endblock %}</title>
+<title>{% block title %}{{ title }} | CCIW{% endblock %}</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <link href="https://fonts.googleapis.com/css?family=Amaranth" rel="stylesheet" type="text/css" />
 <link rel="stylesheet" href="{{ STATIC_URL }}css/style.css" type="text/css" />

File templates/cciw/officers/add_crb.html

-{% extends "cciw/officers/base.html" %}
-{% load url from future %}
-{% load adminmedia %}
-{% block title %}Add CRB information | CCIW Officers{% endblock %}
-{% block extrastyle %}{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />
-{% endblock %}
-{% block content %}
-
-<h1>Add CRB information</h1>
-
-<p>If you have a completed CRB disclosure, please enter the details below.</p>
-
-<p>Or <a href="{% url 'cciw.officers.views.index' %}">return to the menu</a>.</p>
-
-<form action="." method="post">
-{% csrf_token %}
-<div>
-  <table>
-    {{ form.as_table }}
-  </table>
-</div>
-
-<p><input type="submit" name="add" value="Add information" /></p>
-</form>
-
-{% endblock %}

File templates/cciw/officers/index.html

 <h2>Menu:</h2>
 <ul>
   <li><a href="{% url 'cciw.officers.views.applications' %}">Submit/view applications</a></li>
-  <li><a href="{% url 'cciw.officers.views.add_crb' %}">Add your CRB information</a></li>
   <li><a href="{% url 'cciw.officers.views.info' %}">Information about camp</a></li>
   {% if show_leader_links %}
     <li><a href="{% url 'cciw.officers.views.leaders_index' %}">Tools for leaders</a></li>

File templates/cciw/standard.html

 {% load standardpage %}
 
 {% block extraheader %}
+  {% if meta_description %}
 	<meta name="description" content="{{ meta_description }}" />
+  {% else %}
+     {% if homepage %}
+        <meta name="description" content="Details of camps, message boards and photos for the UK charity Christian Camps in Wales" />
+     {% endif %}
+  {% endif %}
+  {% if meta_keywords %}
 	<meta name="keywords" content="{{ meta_keywords }}" />
+  {% else %}
+    {% if homepage %}
+        <meta name="keywords" content="camp, camps, summer camp, Christian, Christian camp, charity" />
+    {% endif %}
+ {% endif %}
 	{{ block.super }}
 	{% block atomfeed %}
 		{% atomfeedlink %}
 	<div id="contentOuter">
 		<div id="content">
 			<div id="pageTitle">
-				<h1>{% block title %}{{ title }}{% endblock %}</h1>
+				<h1>{{ title }}</h1>
 			</div>
 			<div id="contentBody">
 				{% block breadcrumb %}
 	{% else %}
 		<li><a href="/login/?redirect={{ request.get_full_path}}">Login</a></li>
 	{% endif %}
-		<li><a href="/members/?online=1"> {{ misc.logged_in_members }} member(s) online</a></li>
 	</ul>
 </div>
 {% endblock %}