# HG changeset patch # User Todd Larsen # Date 1227340620 0 # Node ID 280a1ac6bcc175d8d57739a0b1521a40d0d7d9dc # Parent 7cc99461b64d3f967696936657981aa77f162fbe Merge soc/logic/out_of_band.py into soc/views/out_of_band.py. Merge errorResponse() and requestLogin() from soc/views/simple.py into out_of_band.Error and out_of_band.LoginRequest exception classes, respectively. Remove no-longer-used soc/logic/out_of_band.py and soc/views/simple.py. Fix some problems where usage of out_of_band was broken. Patch by: Todd Larsen diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/logic/accounts.py --- a/app/soc/logic/accounts.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/logic/accounts.py Sat Nov 22 07:57:00 2008 +0000 @@ -26,7 +26,7 @@ from google.appengine.api import users from soc.logic import models -from soc.logic import out_of_band +from soc.views import out_of_band import soc.models.user import soc.logic.models.user @@ -117,7 +117,7 @@ """Like getUserFromLinkId but expects to find a user. Raises: - out_of_band.ErrorResponse if no User entity is found + out_of_band.Error if no User entity is found """ user = models.user.logic.getForFields({'link_id': link_id}, unique=True) @@ -125,5 +125,5 @@ if user: return user - raise out_of_band.ErrorResponse( + raise out_of_band.Error( 'There is no user with a "link ID" of "%s".' % link_id, status=404) diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/logic/models/base.py --- a/app/soc/logic/models/base.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/logic/models/base.py Sat Nov 22 07:57:00 2008 +0000 @@ -30,7 +30,7 @@ from django.utils.translation import ugettext_lazy from soc.logic import dicts -from soc.logic import out_of_band +from soc.views import out_of_band class Error(Exception): @@ -218,7 +218,7 @@ * Entity for supplied fields Raises: - out_of_band.ErrorResponse if link ID is not false, but no entity + out_of_band.Error if link ID is not false, but no entity with the supplied link ID exists in the Datastore. """ @@ -245,7 +245,7 @@ # else: fields were supplied, but there is no Entity that has it - raise out_of_band.ErrorResponse(msg, status=404) + raise out_of_band.Error(msg, status=404) def getKeyNameForFields(self, fields): """Return a Datastore key_name for a Entity from the specified fields. diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/logic/out_of_band.py --- a/app/soc/logic/out_of_band.py Sat Nov 22 03:13:59 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -#!/usr/bin/python2.5 -# -# Copyright 2008 the Melange authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Out-of-band responses to render instead of the usual HTTP response. -""" - -__authors__ = [ - '"Todd Larsen" ', - ] - - -class OutOfBandResponse(Exception): - """Base exception for out-of-band responses raised by controller logic. - """ - - pass - - -class ErrorResponse(OutOfBandResponse): - """Out-of-band response when controller logic needs a special error page. - """ - - def __init__(self, message, **response_args): - """Constructor used to set error message and HTTP response arguments. - - Args: - message: error message to display on the error page - **response_args: keyword arguments that are supplied directly to - django.http.HttpResponse; the most commonly used is 'status' to - set the HTTP status code for the response - """ - - self.message = message - self.response_args = response_args diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/templates/soc/error.html --- a/app/soc/templates/soc/error.html Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/templates/soc/error.html Sat Nov 22 07:57:00 2008 +0000 @@ -12,8 +12,29 @@ See the License for the specific language governing permissions and limitations under the License. {% endcomment %} -{% block page_title %}Error{%if error_status %} {{ error_status }}{% endif %}{% endblock %} -{% block header_title %}Error{%if error_status %} {{ error_status }}{% endif %}{% endblock %} +{% block page_title %} + {%if title %} + {{ title }} + {% else %} + Error{% if status %} {{ status }}{% endif %} + {% endif %} +{% endblock %} +{% block header_title %} + {%if header %} + {{ header }} + {% else %} + {% comment %} + Attempt to use title again if header is not defined. + {% endcomment %} + {%if title %} + {{ title }} + {% else %} + Error{% if status %} {{ status }}{% endif %} + {% endif %} + {% endif %} +{% endblock %} {% block body %} -
{%if error_status %}Error {{ error_status }}: {% endif %}{{ error_message|safe }}
-{% endblock %} \ No newline at end of file +
+{%if status %}Error {{ status }}: {% endif %}{{ message|safe }} +
+{% endblock %} diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/templates/soc/login.html --- a/app/soc/templates/soc/login.html Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/templates/soc/login.html Sat Nov 22 07:57:00 2008 +0000 @@ -13,26 +13,26 @@ limitations under the License. {% endcomment %} {% block page_title %} - {%if login_title %} - {{ login_title }} + {%if title %} + {{ title }} {% else %} Sign In Required {% endif %} {% endblock %} {% block header_title %} - {%if login_header %} - {{ login_header }} + {%if header %} + {{ header }} {% else %} {% comment %} - Attempt to use login_title again if login_header is not defined. + Attempt to use title again if header is not defined. {% endcomment %} - {%if login_title %} - {{ login_title }} + {%if title %} + {{ title }} {% else %} Sign In Required {% endif %} {% endif %} {% endblock %} {% block body %} -

{{ login_message|safe }}

-{% endblock %} \ No newline at end of file +

{{ message|safe }}

+{% endblock %} diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/views/helper/access.py --- a/app/soc/views/helper/access.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/views/helper/access.py Sat Nov 22 07:57:00 2008 +0000 @@ -38,15 +38,8 @@ from soc.logic.models import user as user_logic from soc.logic.models import request as request_logic from soc.views import helper -from soc.views.simple import requestLogin - -import soc.views.out_of_band - +from soc.views import out_of_band -DEF_LOGIN_TMPL = 'soc/login.html' - -DEF_LOGIN_MSG_FMT = ugettext_lazy( - 'Please sign in to continue.') DEF_NO_USER_LOGIN_MSG_FMT = ugettext_lazy( 'Please create User Profile' @@ -65,7 +58,7 @@ """Never returns an alternate HTTP response Args: - request: a django HTTP request + request: a Django HTTP request """ return @@ -74,26 +67,23 @@ """Returns an alternate HTTP response Args: - request: a django HTTP request + request: a Django HTTP request Returns: a subclass of django.http.HttpResponse which contains the alternate response that should be returned by the calling view. """ context = helper.responses.getUniversalContext(request) - context['login_title'] = 'Access denied' - context['login_header'] = 'Access denied' - context['login_message'] = DEF_PAGE_DENIED_MSG + context['title'] = 'Access denied' - denied_response = helper.responses.respond(request, DEF_LOGIN_TMPL, context=context) + raise out_of_band.AccessViolation(DEF_PAGE_DENIED_MSG, context=context) - raise soc.views.out_of_band.AccessViolationResponse(denied_response) def checkIsLoggedIn(request): """Returns an alternate HTTP response if Google Account is not logged in. Args: - request: A Django HTTP request + request: a Django HTTP request Raises: AccessViolationResponse: If the required authorization is not met. @@ -107,17 +97,14 @@ if users.get_current_user(): return - login_response = requestLogin(request, None, DEF_LOGIN_TMPL, - login_message_fmt=DEF_LOGIN_MSG_FMT) - - raise soc.views.out_of_band.AccessViolationResponse(login_response) + raise out_of_band.LoginRequest() def checkIsUser(request): """Returns an alternate HTTP response if Google Account has no User entity. Args: - request: A Django HTTP request + request: a Django HTTP request Raises: AccessViolationResponse: If the required authorization is not met. @@ -136,10 +123,7 @@ if user: return - login_response = requestLogin(request, None, DEF_LOGIN_TMPL, - login_message_fmt=DEF_NO_USER_LOGIN_MSG_FMT) - - raise soc.views.out_of_band.AccessViolationResponse(login_response) + raise out_of_band.LoginRequest(message_fmt=DEF_NO_USER_LOGIN_MSG_FMT) def checkIsDeveloper(request): @@ -163,13 +147,9 @@ return None login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % { - 'role' : 'a site developer ', - } + 'role': 'a site developer '} - login_response = requestLogin(request, None, DEF_LOGIN_TMPL, - login_message_fmt=login_message_fmt) - - raise soc.views.out_of_band.AccessViolationResponse(login_response) + raise out_of_band.LoginRequest(message_fmt=login_message_fmt) def checkIsInvited(request, role): @@ -205,10 +185,6 @@ return login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % { - 'role' : 'a host for this program', - } + 'role': 'a host for this program'} - login_response = requestLogin(request, None, DEF_LOGIN_TMPL, - login_message_fmt=login_message_fmt) - - raise soc.views.out_of_band.AccessViolationResponse(login_response) + raise out_of_band.LoginRequest(message_fmt=login_message_fmt) diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/views/models/base.py --- a/app/soc/views/models/base.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/views/models/base.py Sat Nov 22 07:57:00 2008 +0000 @@ -30,16 +30,14 @@ import soc.logic import soc.logic.lists -import soc.logic.out_of_band import soc.views.helper.lists import soc.views.helper.responses -import soc.views.out_of_band from soc.logic import dicts from soc.logic import models from soc.models import linkable -from soc.views import simple from soc.views import helper +from soc.views import out_of_band from soc.views.helper import access @@ -153,8 +151,8 @@ try: self.checkAccess('public', request) - except soc.views.out_of_band.AccessViolationResponse, alt_response: - return alt_response.response() + except out_of_band.Error, error: + return error.response(request) # create default template context for use with any templates context = helper.responses.getUniversalContext(request) @@ -168,9 +166,9 @@ try: key_fields = self._logic.getKeyFieldsFromDict(kwargs) entity = self._logic.getIfFields(key_fields) - except soc.logic.out_of_band.ErrorResponse, error: - template = params['public_template'] - return simple.errorResponse(request, page_name, error, template, context) + except out_of_band.Error, error: + return error.response(request, template=params['public_template'], + context=context) self._public(request, entity, context) @@ -208,7 +206,8 @@ return self.edit(request, page_name=page_name, params=params, **empty_kwargs) else: - return self.edit(request, page_name=page_name, params=params, seed=kwargs, **empty_kwargs) + return self.edit(request, page_name=page_name, params=params, + seed=kwargs, **empty_kwargs) def edit(self, request, page_name=None, params=None, seed=None, **kwargs): """Displays the edit page for the entity specified by **kwargs. @@ -224,8 +223,8 @@ try: self.checkAccess('edit', request, rights=params['rights']) - except soc.views.out_of_band.AccessViolationResponse, alt_response: - return alt_response.response() + except out_of_band.Error, error: + return error.response(request) context = helper.responses.getUniversalContext(request) context['page_name'] = page_name @@ -235,16 +234,15 @@ if all(kwargs.values()): key_fields = self._logic.getKeyFieldsFromDict(kwargs) entity = self._logic.getIfFields(key_fields) - except soc.logic.out_of_band.ErrorResponse, error: + except out_of_band.Error, error: if not seed: - template = params['public_template'] - error.message = error.message + self.DEF_CREATE_NEW_ENTITY_MSG_FMT % { + error.message_fmt = ( + error.message_fmt + self.DEF_CREATE_NEW_ENTITY_MSG_FMT % { 'entity_type_lower' : params['name'].lower(), 'entity_type' : params['name'], - 'create' : params['missing_redirect'] - } - return simple.errorResponse(request, page_name, error, template, - context) + 'create' : params['missing_redirect']}) + return error.response(request, template=params['public_template'], + context=context) if request.method == 'POST': return self.editPost(request, entity, context, params) @@ -338,8 +336,8 @@ try: self.checkAccess('list', request) - except soc.views.out_of_band.AccessViolationResponse, alt_response: - return alt_response.response() + except out_of_band.Error, error: + return error.response(request) context = helper.responses.getUniversalContext(request) context['page_name'] = page_name @@ -349,9 +347,9 @@ # Fetch one more to see if there should be a 'next' link if not filter: - entities = self._logic.getForLimitAndOffset(limit + 1, offset=offset) + entities = self._logic.getForLimitAndOffset(limit+1, offset=offset) else: - entities = self._logic.getForFields(filter, limit=limit + 1, offset=offset) + entities = self._logic.getForFields(filter, limit=limit+1, offset=offset) context['pagination_form'] = helper.lists.makePaginationForm(request, limit) @@ -387,8 +385,8 @@ try: self.checkAccess('delete', request) - except soc.views.out_of_band.AccessViolationResponse, alt_response: - return alt_response.response() + except out_of_band.Error, error: + return error.response(request) # create default template context for use with any templates context = helper.responses.getUniversalContext(request) @@ -398,14 +396,14 @@ try: key_fields = self._logic.getKeyFieldsFromDict(kwargs) entity = self._logic.getIfFields(key_fields) - except soc.logic.out_of_band.ErrorResponse, error: - template = params['edit_template'] - error.message = error.message + self.DEF_CREATE_NEW_ENTITY_MSG_FMT % { + except out_of_band.Error, error: + error.message_fmt = ( + error.message_fmt + self.DEF_CREATE_NEW_ENTITY_MSG_FMT % { 'entity_type_lower' : params['name'].lower(), 'entity_type' : params['name'], - 'create' : params['missing_redirect'] - } - return simple.errorResponse(request, page_name, error, template, context) + 'create' : params['missing_redirect']}) + return error.response(request, template=params['edit_template'], + context=context) if not entity: #TODO: Create a proper error page for this diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/views/models/role.py --- a/app/soc/views/models/role.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/views/models/role.py Sat Nov 22 07:57:00 2008 +0000 @@ -33,6 +33,7 @@ from soc.logic.models import request as request_logic from soc.logic.models import user as user_logic from soc.views import helper +from soc.views import out_of_band from soc.views.models import base from soc.views.models import user as user_view @@ -103,8 +104,8 @@ try: self.checkAccess('invite', request) - except soc.views.out_of_band.AccessViolationResponse, alt_response: - return alt_response.response() + except out_of_band.Error, error: + return error.response(request) return user_view.list(request, page_name=page_name, params=params) diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/views/models/user.py --- a/app/soc/views/models/user.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/views/models/user.py Sat Nov 22 07:57:00 2008 +0000 @@ -32,6 +32,7 @@ from soc.logic import validate from soc.logic.models import user as user_logic from soc.views import helper +from soc.views import out_of_band from soc.views.helper import access from soc.views.models import base @@ -183,6 +184,8 @@ base.View.__init__(self, params=params) + EDIT_SELF_TMPL = 'soc/user/edit_self.html' + def editSelf(self, request, page_name=None, params=None, **kwargs): """Displays User self edit page for the entity specified by **kwargs. @@ -200,11 +203,11 @@ try: self.checkAccess('editSelf', request, rights=rights) - except soc.views.out_of_band.AccessViolationResponse, alt_response: - return alt_response.response() + except out_of_band.Error, error: + return error.response(request, template=self.EDIT_SELF_TMPL) new_params = {} - new_params['edit_template'] = 'soc/user/edit_self.html' + new_params['edit_template'] = self.EDIT_SELF_TMPL new_params['rights'] = rights params = dicts.merge(params, new_params) @@ -232,10 +235,8 @@ # check if user account is not in former_accounts # if it is show error message that account is invalid if soc.logic.models.user.logic.isFormerAccount(account): - msg = DEF_USER_ACCOUNT_INVALID_MSG - error = out_of_band.ErrorResponse(msg) - return simple.errorResponse(request, page_name, error, template, - context) + error = out_of_band.Error(DEF_USER_ACCOUNT_INVALID_MSG) + return error.response(request, template=template, context=context) user = soc.logic.models.user.logic.updateOrCreateFromFields( properties, {'link_id': new_link_id}) diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/views/out_of_band.py --- a/app/soc/views/out_of_band.py Sat Nov 22 03:13:59 2008 +0000 +++ b/app/soc/views/out_of_band.py Sat Nov 22 07:57:00 2008 +0000 @@ -18,32 +18,100 @@ """ __authors__ = [ + '"Todd Larsen" ', '"Sverre Rabbelier" ', ] -class OutOfBandResponse(Exception): - """Base exception for out-of-band responses raised by views. - """ +from django.utils.translation import ugettext_lazy - pass +from soc.views import helper + +import soc.views.helper.responses +import soc.views.helper.templates -class AccessViolationResponse(OutOfBandResponse): - """"Out of band response when an access requirement was not met. +class Error(Exception): + """Base exception for out-of-band responses raised by logic or views. """ + TEMPLATE_NAME = 'error.html' + DEF_TEMPLATE = 'soc/error.html' - def __init__(self, response): - """Constructor used to set response message. + def __init__(self, message_fmt, context=None, **response_args): + """Constructor used to set response message and HTTP response arguments. + + Args: + message_fmt: format string, when combined with a context supplied to + the response() method, produces the message to display on the + response page; this can be a simple string containing *no* named + format specifiers + context: see response() + **response_args: keyword arguments that are supplied directly to + django.http.HttpResponse; the most commonly used is 'status' to + set the HTTP status code for the response + """ + self.message_fmt = message_fmt + self._context = context + self._response_args = response_args + def response(self, request, template=None, context=None): + """Creates an HTTP response from the OutOfBandResponse exception. + Args: - response: The response that should be returned to the user. + request: a Django HTTP request + template: the "sibling" template (or a search list of such templates) + from which to construct the actual template name (or names) + context: optional context dict supplied to the template, which is + modified (so supply a copy if such modification is not acceptable) """ + if not context: + context = self._context - self._response = response + if not context: + context = helper.responses.getUniversalContext(request) + + if not template: + template = [] + + # make a list of possible "sibling" templates, then append a default + templates = helper.templates.makeSiblingTemplatesList(template, + self.TEMPLATE_NAME, default_template=self.DEF_TEMPLATE) + + context['status'] = self._response_args.get('status') + + if not context.get('message'): + # supplied context did not explicitly override the message + context['message'] = self.message_fmt % context + + return helper.responses.respond(request, templates, context=context, + response_args=self._response_args) + - def response(self): - """Returns the response that was set in the constructor. +class LoginRequest(Error): + """Out of band error raised when login is requested. + """ + TEMPLATE_NAME = 'login.html' + DEF_TEMPLATE = 'soc/login.html' + + DEF_LOGIN_MSG_FMT = ugettext_lazy( + 'Please sign in to continue.') + + def __init__(self, message_fmt=None, **response_args): + """Constructor used to set response message and HTTP response arguments. + + Args: + message_fmt: same as Error.__init__() message_fmt, with the addition + of a default value of None, in which case self.DEF_LOGIN_MSG_FMT is + used + **response_args: see Error.__init__() """ + if not message_fmt: + message_fmt = self.DEF_LOGIN_MSG_FMT - return self._response + Error.__init__(self, message_fmt, **response_args) + + +class AccessViolation(Error): + """"Out of band error raised when an access requirement was not met. + """ + pass diff -r 7cc99461b64d -r 280a1ac6bcc1 app/soc/views/simple.py --- a/app/soc/views/simple.py Sat Nov 22 03:13:59 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -#!/usr/bin/python2.5 -# -# Copyright 2008 the Melange authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Simple views that depend entirely on the template and context. -""" - -__authors__ = [ - '"Todd Larsen" ', - '"Pawel Solyga" ', - ] - - -from django.utils.translation import ugettext_lazy - -from soc.logic import accounts -from soc.logic import out_of_band -from soc.views import helper -from soc.views.helper import decorators - -import soc.views.helper.responses -import soc.views.helper.templates - - -DEF_PUBLIC_TMPL = 'soc/base.html' - -@decorators.view -def public(request, page_name=None, template=DEF_PUBLIC_TMPL, link_id=None, - context=None): - """A simple template view that expects a link_id extracted from the URL. - - Args: - request: the standard Django HTTP request object - page_name: the page name displayed in templates as page and header title - template: the template to use for rendering the view (or a search list - of templates) - link_id: a site-unique "link_id" (usually extracted from the URL) - context: the context dict supplied to the template, which is modified - (so supply a copy if such modification is not acceptable) - link_id: the link_id parameter is added to the context - link_id_user: if the link_id exists for a User, that User - is added to the context - - - Returns: - A subclass of django.http.HttpResponse containing the generated page. - """ - - template = helper.templates.makeSiblingTemplatesList(template, 'public.html') - - # TODO(tlarsen): fix getUniversalContext() so that it is back to being a - # dict merge of missing defaults (as discussed at length in recent code - # reviews) - if not context: - context = helper.responses.getUniversalContext(request) - - context['page_name'] = page_name - - try: - if link_id: - user = accounts.getUserFromLinkIdOr404(link_id) - except out_of_band.ErrorResponse, error: - return errorResponse(request, page_name, error, template, context) - - context['link_id'] = link_id - context['link_id_user'] = user - - return helper.responses.respond(request, template, context) - - -DEF_ERROR_TMPL = 'soc/error.html' - -def errorResponse(request, page_name, error, template, context): - """Displays an error page for an out_of_band.ErrorResponse exception. - - Args: - request: the standard Django HTTP request object - page_name: the page name displayed in templates as page and header title - error: an out_of_band.ErrorResponse exception - template: the "sibling" template (or a search list of such templates) - from which to construct the error.html template name (or names) - context: the context dict supplied to the template, which is modified - (so supply a copy if such modification is not acceptable) - error_message: the error message string from error.message - error_status: error.response_args['status'], or None if a status code - was not supplied to the ErrorResponse - - """ - - if not context: - context = helper.responses.getUniversalContext(request) - - # make a list of possible "sibling" templates, then append a default - error_templates = helper.templates.makeSiblingTemplatesList( - template, 'error.html', default_template=DEF_ERROR_TMPL) - - context['error_status'] = error.response_args.get('status') - context['error_message'] = error.message - - return helper.responses.respond(request, error_templates, context=context, - response_args=error.response_args) - - -DEF_LOGIN_TMPL = 'soc/login.html' -DEF_LOGIN_MSG_FMT = ugettext_lazy( - 'Please sign in to continue.') - -def requestLogin(request, page_name, template, context=None, login_message_fmt=None): - """Displays a login request page with custom message and login link. - - Args: - request: the standard Django HTTP request object - page_name: the page name displayed in templates as page and header title - template: the "sibling" template (or a search list of such templates) - from which to construct the login.html template name (or names) - login_message_fmt: a custom message format string used to create a - message displayed on the login page; the format string can contain - named format specifiers for any of the keys in context, but should at - least contain %(sign_in)s - context: the context dict supplied to the template, which is modified - (so supply a copy if such modification is not acceptable) - login_message: the caller can completely construct the message supplied - to the login template in lieu of using login_message_fmt - - """ - - if not context: - context = helper.responses.getUniversalContext(request) - - # make a list of possible "sibling" templates, then append a default - login_templates = helper.templates.makeSiblingTemplatesList( - template, 'login.html', default_template=DEF_LOGIN_TMPL) - - if not context.get('login_message'): - if not login_message_fmt: - login_message_fmt = DEF_LOGIN_MSG_FMT - context['login_message'] = login_message_fmt % context - - return helper.responses.respond(request, login_templates, context=context) -