3 # Copyright 2008 the Melange authors.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 """Helpers functions for displaying views.
21 '"Sverre Rabbelier" <sverre@rabbelier.nl>',
22 '"Lennard de Rijk" <ljvderijk@gmail.com>',
23 '"Pawel Solyga" <pawel.solyga@gmail.com>',
30 from google
.appengine
.ext
import db
32 from django
import http
33 from django
.utils
import simplejson
34 from django
.utils
.translation
import ugettext
36 from soc
.logic
import dicts
37 from soc
.views
import helper
38 from soc
.views
import out_of_band
39 from soc
.views
.helper
import decorators
40 from soc
.views
.helper
import forms
41 from soc
.views
.helper
import redirects
42 from soc
.views
.helper
import requests
43 from soc
.views
.helper
import responses
44 from soc
.views
import sitemap
46 import soc
.cache
.logic
48 import soc
.logic
.lists
49 import soc
.views
.helper
.lists
50 import soc
.views
.helper
.params
54 """Views for entity classes.
56 The View class functions specific to Entity classes by relying
57 on the the child-classes to define the following fields:
59 self._logic: the logic singleton for this entity
62 DEF_CREATE_NEW_ENTITY_MSG_FMT
= ugettext(
63 ' You can create a new %(entity_type)s by visiting'
64 ' <a href="%(create)s">Create '
65 'a New %(entity_type)s</a> page.')
67 DEF_CREATE_INSTRUCTION_MSG_FMT
= ugettext(
68 'Please select a %s for the new %s.')
70 def __init__(self
, params
=None):
74 params: This dictionary should be filled with the parameters
75 specific to this entity. See the methods in this class on
76 the fields it should contain, and how they are used.
79 self
._params
= helper
.params
.constructParams(params
)
80 self
._logic
= params
['logic']
82 @decorators.merge_params
83 @decorators.check_access
84 def public(self
, request
, access_type
,
85 page_name
=None, params
=None, **kwargs
):
86 """Displays the public page for the entity specified by **kwargs.
89 rights: The rights dictionary is used to check if the user has
90 the required rights to view the public page for this entity.
91 See checkAccess for more details on how the rights dictionary
92 is used to check access rights.
93 error_public: The error_public value is used as template when
94 the key values (as defined by the page's url) do not
95 correspond to an existing entity.
96 name: The name value is used to set the entity_type in the
97 context so that the template can refer to it.
98 public_template: The public_template value is used as template
99 to display the public page of the found entity.
102 request: the standard Django HTTP request object
103 access_type : the name of the access type which should be checked
104 page_name: the page name displayed in templates as page and header title
105 params: a dict with params for this View
106 kwargs: the Key Fields for the specified entity
109 # create default template context for use with any templates
110 context
= helper
.responses
.getUniversalContext(request
)
111 helper
.responses
.useJavaScript(context
, params
['js_uses_all'])
112 context
['page_name'] = page_name
114 logic
= params
['logic']
116 if not all(kwargs
.values()):
117 #TODO: Change this into a proper redirect
118 return http
.HttpResponseRedirect('/')
121 entity
= logic
.getFromKeyFieldsOr404(kwargs
)
122 except out_of_band
.Error
, error
:
123 return helper
.responses
.errorResponse(
124 error
, request
, template
=params
['error_public'], context
=context
)
126 if not self
._public
(request
, entity
, context
):
127 redirect
= params
['public_redirect']
129 return http
.HttpResponseRedirect(redirect
)
131 context
['entity'] = entity
132 context
['entity_type'] = params
['name']
133 context
['entity_type_url'] = params
['url_name']
135 context
= dicts
.merge(params
['context'], context
)
137 template
= params
['public_template']
139 return helper
.responses
.respond(request
, template
, context
=context
)
141 @decorators.merge_params
142 @decorators.check_access
143 def admin(self
, request
, access_type
,
144 page_name
=None, params
=None, **kwargs
):
145 """Displays the admin page for the entity specified by **kwargs.
148 rights: The rights dictionary is used to check if the user has
149 the required rights to view the admin page for this entity.
150 See checkAccess for more details on how the rights dictionary
151 is used to check access rights.
152 name: The name value is used to set the entity_type in the
153 context so that the template can refer to it.
154 public_template: The public_template value is used as template
155 to display the public page of the found entity.
158 request: the standard Django HTTP request object
159 access_type : the name of the access type which should be checked
160 page_name: the page name displayed in templates as page and header title
161 params: a dict with params for this View
162 kwargs: the Key Fields for the specified entity
165 # create default template context for use with any templates
166 context
= helper
.responses
.getUniversalContext(request
)
167 helper
.responses
.useJavaScript(context
, params
['js_uses_all'])
168 context
['page_name'] = page_name
169 logic
= params
['logic']
172 entity
= logic
.getFromKeyFieldsOr404(kwargs
)
173 except out_of_band
.Error
, error
:
174 return helper
.responses
.errorResponse(error
, request
, context
=context
)
176 form
= params
['admin_form'](instance
=entity
)
177 template
= params
['admin_template']
179 return self
._constructResponse
(request
, entity
, context
, form
,
180 params
, template
=template
)
182 @decorators.merge_params
183 @decorators.check_access
184 def export(self
, request
, access_type
,
185 page_name
=None, params
=None, **kwargs
):
186 """Displays the export page for the entity specified by **kwargs.
189 rights: The rights dictionary is used to check if the user has
190 the required rights to view the export page for this entity.
191 See checkAccess for more details on how the rights dictionary
192 is used to check access rights.
193 error_export: The error_export value is used as template when
194 the key values (as defined by the page's url) do not
195 correspond to an existing entity.
196 Params is passed to download, refer to it's docstring for more
197 details on how it uses it.
200 request: the standard Django HTTP request object
201 access_type : the name of the access type which should be checked
202 page_name: the page name displayed in templates as page and header title
203 params: a dict with params for this View
204 kwargs: the Key Fields for the specified entity
207 if not ('export_content_type' in params
) and ('export_function' in params
):
208 return self
.public(request
, access_type
, page_name
=page_name
,
209 params
=params
, **kwargs
)
211 # create default template context for use with any templates
213 logic
= params
['logic']
215 if not all(kwargs
.values()):
216 #TODO: Change this into a proper redirect
217 return http
.HttpResponseRedirect('/')
220 entity
= logic
.getFromKeyFieldsOr404(kwargs
)
221 except out_of_band
.Error
, error
:
222 return helper
.responses
.errorResponse(
223 error
, request
, template
=params
['error_export'])
225 export_function
= params
['export_function']
226 data
, filename
= export_function(entity
)
228 return self
.download(request
, data
, filename
, params
)
230 def download(self
, request
, data
, filename
, params
):
231 """Returns data as a downloadable file with the specified name.
234 export_template: The export_template value is used as template
235 to display the export page of the found entity.
236 export_content_type: The export_content_type value is used to set
237 the Content-Type header of the HTTP response. If empty (or None),
238 public() is called instead.
239 export_extension: The export_extension value is used as the suffix
240 of the file that will be offered for download.
243 request: the standard Django HTTP request object
244 data: the data that should be offered as file content
245 filename: the name the file should have
246 params: a dict with params for this View
250 context
['data'] = data
252 template
= params
['export_template']
254 response_args
= {'mimetype': params
['export_content_type']}
256 export_extension
= params
['export_extension']
259 'Content-Disposition': 'attachment; filename=%s%s' % (
260 filename
, export_extension
),
263 return helper
.responses
.respond(request
, template
, context
=context
,
264 response_args
=response_args
,
265 response_headers
=response_headers
)
267 @decorators.check_access
268 def create(self
, request
, access_type
,
269 page_name
=None, params
=None, **kwargs
):
270 """Displays the create page for this entity type.
273 The params dictionary is passed on to edit, see the docstring
274 for edit on how it uses it.
277 request: the standard Django HTTP request object
278 access_type : the name of the access type which should be checked
279 page_name: the page name displayed in templates as page and header title
280 params: a dict with params for this View
281 kwargs: not used for create()
284 new_params
= dicts
.merge(params
, self
._params
)
286 # redirect to scope selection view
287 if ('scope_view' in new_params
) and ('scope_path' not in kwargs
):
288 view
= new_params
['scope_view'].view
289 redirect
= new_params
['scope_redirect']
290 return self
.select(request
, view
, redirect
,
291 params
=params
, page_name
=page_name
, **kwargs
)
295 context
= helper
.responses
.getUniversalContext(request
)
296 helper
.responses
.useJavaScript(context
, params
['js_uses_all'])
297 context
['page_name'] = page_name
299 if request
.method
== 'POST':
300 return self
.createPost(request
, context
, params
)
302 return self
.createGet(request
, context
, params
, kwargs
)
304 def createGet(self
, request
, context
, params
, seed
):
307 Handles generating the patch to create new entities.
310 self
._editSeed
(request
, seed
)
313 # pass the seed through the context to _constructResponse
314 # it will be popped before dispatching to Django
315 context
['seed'] = seed
316 form
= params
['create_form'](initial
=seed
)
318 form
= params
['create_form']()
320 return self
._constructResponse
(request
, None, context
, form
, params
)
322 def createPost(self
, request
, context
, params
):
325 Handles the creation of new entities.
328 form
= params
['create_form'](request
.POST
)
330 if not form
.is_valid():
331 return self
._constructResponse
(request
, None, context
, form
, params
)
333 _
, fields
= forms
.collectCleanedFields(form
)
334 self
._editPost
(request
, None, fields
)
336 logic
= params
['logic']
337 entity
= logic
.updateOrCreateFromFields(fields
)
339 page_params
= params
['edit_params']
340 params
['suffix'] = entity
.key().id_or_name()
342 request
.path
= params
['edit_redirect'] % params
344 return helper
.responses
.redirectToChangedSuffix(
345 request
, None, params
=page_params
)
347 @decorators.merge_params
348 @decorators.check_access
349 def edit(self
, request
, access_type
,
350 page_name
=None, params
=None, seed
=None, **kwargs
):
351 """Displays the edit page for the entity specified by **kwargs.
354 The params dictionary is passed on to either editGet or editPost
355 depending on the method type of the request. See the docstring
356 for editGet and editPost on how they use it.
358 rights: The rights dictionary is used to check if the user has
359 the required rights to edit (or create) a new entity.
360 See checkAccess for more details on how the rights dictionary
361 is used to check access rights.
362 name: The name value is used to construct the message_fmt of the
363 raised error when there key_values do not define an existing
364 entity. See DEF_CREATE_NEW_ENTITY_MSG_FMT on how the name
365 (and the lower() version of it) is used.
366 missing_redirect: The missing_redirect value is also used to
367 construct the message_fmt mentioned above.
368 error_public: The error_public value is used as the template for
369 the error response mentioned above.
372 request: the standard Django HTTP request object
373 access_type : the name of the access type which should be checked
374 page_name: the page name displayed in templates as page and header title
375 params: a dict with params for this View
376 kwargs: The Key Fields for the specified entity
379 logic
= params
['logic']
381 context
= helper
.responses
.getUniversalContext(request
)
382 helper
.responses
.useJavaScript(context
, params
['js_uses_all'])
383 context
['page_name'] = page_name
386 entity
= logic
.getFromKeyFieldsOr404(kwargs
)
387 except out_of_band
.Error
, error
:
388 msg
= self
.DEF_CREATE_NEW_ENTITY_MSG_FMT
% {
389 'entity_type_lower' : params
['name'].lower(),
390 'entity_type' : params
['name'],
391 'create' : params
['missing_redirect']
393 error
.message_fmt
= error
.message_fmt
+ msg
394 return helper
.responses
.errorResponse(
395 error
, request
, context
=context
)
397 if request
.method
== 'POST':
398 return self
.editPost(request
, entity
, context
, params
=params
)
400 return self
.editGet(request
, entity
, context
, params
=params
)
402 @decorators.merge_params
403 def editPost(self
, request
, entity
, context
, params
=None):
404 """Processes POST requests for the specified entity.
407 The params dictionary is passed to _constructResponse when the
408 form is not valid (see edit_form and create_form below). See
409 the docstring of _constructResponse on how it uses it.
411 edit_form: The edit_form value is used as form when there is an
412 existing entity. It is provided with with the request.POST
413 dictionary on construction. The collectCleanedFields method
414 is called with the newly constructed form. If the form is
415 not valid, it is passed as argument to _constructResponse.
416 create_form: The create_form value is used in a similar way to
417 edit_form, only it is used when there is no existing entity.
418 edit_redirect: The edit_redirect value is used as the first part
419 of the url if the form was valid. The last part of the url is
420 created using the .key().id_or_name() method of the entity.
421 edit_params: The edit_params dictionary is used as argument to
422 redirectToChangedSuffix, it will be appended to the url in the
423 standard ?key=value format.
426 request: a django request object
427 entity: the entity that will be modified or created, may be None
428 context: the context dictionary that will be provided to Django
429 params: required, a dict with params for this View
432 logic
= params
['logic']
434 form
= params
['edit_form'](request
.POST
)
436 if not form
.is_valid():
437 return self
._constructResponse
(request
, entity
, context
, form
, params
)
439 _
, fields
= forms
.collectCleanedFields(form
)
441 self
._editPost
(request
, entity
, fields
)
443 entity
= logic
.updateEntityProperties(entity
, fields
)
445 page_params
= params
['edit_params']
446 params
['suffix'] = entity
.key().id_or_name()
448 request
.path
= params
['edit_redirect'] % params
450 return helper
.responses
.redirectToChangedSuffix(
451 request
, None, params
=page_params
)
453 @decorators.merge_params
454 def editGet(self
, request
, entity
, context
, params
=None):
455 """Processes GET requests for the specified entity.
458 The params dictionary is passed to _constructResponse, see the
459 docstring of _constructResponse on how it uses it.
461 save_message: The save_message list is used as argument to
462 getSingleIndexedParamValue when an existing entity was saved.
463 edit_form: The edit_form is used as form if there is an existing
464 entity. The existing entity is passed as instance to it on
465 construction. If key_name is part of it's fields it will be
466 set to the entity's key().id_or_name() value. It is also passed as
467 argument to the _editGet method. See the docstring for
468 _editGet on how it uses it.
469 create_form: The create_form is used as form if there was no
470 existing entity. If the seed argument is present, it is passed
471 as the 'initial' argument on construction. Otherwise, it is
472 called with no arguments.
473 submit_msg_param_name: The submit_msg_param_name value is used
474 as the key part in the ?key=value construct for the submit
475 message parameter (see also save_message).
478 request: the django request object
479 entity: the entity that will be edited, may be None
480 context: the context dictionary that will be provided to django
481 seed: if no entity is provided, the initial values for the new entity
482 params: required, a dict with params for this View
485 # logic = params['logic']
486 suffix
= entity
.key().id_or_name() if entity
else None
488 # remove the params from the request, this is relevant only if
489 # someone bookmarked a POST page.
490 is_self_referrer
= requests
.isReferrerSelf(
491 request
, suffix
=suffix
, url_name
=params
['url_name'])
493 if request
.GET
.get(params
['submit_msg_param_name']):
494 if (not entity
) or (not is_self_referrer
):
495 return http
.HttpResponseRedirect(request
.path
)
497 # note: no message will be displayed if parameter is not present
498 context
['notice'] = requests
.getSingleIndexedParamValue(
499 request
, params
['submit_msg_param_name'],
500 values
=params
['save_message'])
502 # populate form with the existing entity
503 form
= params
['edit_form'](instance
=entity
)
505 self
._editGet
(request
, entity
, form
)
507 return self
._constructResponse
(request
, entity
, context
, form
, params
)
509 @decorators.merge_params
510 @decorators.check_access
511 def list(self
, request
, access_type
,
512 page_name
=None, params
=None, filter=None, order
=None, **kwargs
):
513 """Displays the list page for the entity type.
516 request: the standard Django HTTP request object
517 access_type : the name of the access type which should be checked
518 page_name: the page name displayed in templates as page and header title
519 params: a dict with params for this View
520 filter: a dict for the properties that the entities should have
523 The params dictionary is passed as argument to getListContent in
524 the soc.views.helper.list module. See the docstring for getListContent
525 on how it uses it. The params dictionary is also passed as argument to
526 the _list method. See the docstring for _list on how it uses it.
529 content
= helper
.lists
.getListContent(request
, params
, filter, order
=order
)
532 return self
._list
(request
, params
, contents
, page_name
)
534 def _list(self
, request
, params
, contents
, page_name
, context
=None):
535 """Returns the list page for the specified contents.
537 If the export parameter is present in request.GET a csv export of
538 the specified list is returned instead, see csv().
541 request: the standard Django HTTP request object
542 params: a dict with params for this View
543 contents: a list of content dicts
544 page_name: the page name displayed in templates as page and header title
545 context: the context for this page
548 name: The name value is used to set the entity_type in the
549 context so that the template can refer to it.
550 name_plural: The name_plural value is used to set
551 the entity_type_plural value in the context so that the
552 template can refer to it.
553 list_template: The list_template value is used as template for
554 to display the list of all entities for this View.
558 export
= int(request
.GET
.get('export', -1))
559 export
= export
if export
>= 0 else None
563 content
= [i
for i
in contents
if i
.get('idx') == export
]
564 if len(content
) == 1:
566 key_order
= content
.get('key_order')
569 data
= [i
.toDict(key_order
) for i
in content
['data']]
571 filename
= "export_%d" % export
572 return self
.csv(request
, data
, filename
, params
, key_order
)
574 context
= dicts
.merge(context
,
575 helper
.responses
.getUniversalContext(request
))
576 helper
.responses
.useJavaScript(context
, params
['js_uses_all'])
577 context
['page_name'] = page_name
578 context
['list'] = soc
.logic
.lists
.Lists(contents
)
580 context
['entity_type'] = params
['name']
581 context
['entity_type_plural'] = params
['name_plural']
582 context
['list_msg'] = params
['list_msg']
583 context
['no_lists_msg'] = params
['no_lists_msg']
585 template
= params
['list_template']
587 return helper
.responses
.respond(request
, template
, context
)
589 @decorators.merge_params
590 @decorators.check_access
591 def delete(self
, request
, access_type
,
592 page_name
=None, params
=None, **kwargs
):
593 """Shows the delete page for the entity specified by **kwargs.
596 request: the standard Django HTTP request object
597 access_type : the name of the access type which should be checked
598 page_name: the page name displayed in templates as page and header title
599 params: a dict with params for this View
600 kwargs: The Key Fields for the specified entity
603 rights: The rights dictionary is used to check if the user has
604 the required rights to delete the specified entity. See checkAccess
605 for more details on how the rights dictionary is used to check access
607 name: used in the same way as in edit(), see it's docstring for
608 a more detailed explanation on how it is used.
609 missing_redirect: see name
611 delete_redirect: The delete_redirect value is used as the url to
612 redirect to after having successfully deleted the entity.
615 logic
= params
['logic']
618 entity
= logic
.getFromKeyFieldsOr404(kwargs
)
619 except out_of_band
.Error
, error
:
620 error
.message_fmt
= (
621 error
.message_fmt
+ self
.DEF_CREATE_NEW_ENTITY_MSG_FMT
% {
622 'entity_type_lower' : params
['name'].lower(),
623 'entity_type' : params
['name'],
624 'create' : params
['missing_redirect']})
625 return helper
.responses
.errorResponse(
626 error
, request
, template
=params
['error_edit'])
628 if not logic
.isDeletable(entity
):
629 page_params
= params
['cannot_delete_params']
630 params
['suffix'] = entity
.key().id_or_name()
631 request
.path
= params
['edit_redirect'] % params
633 # redirect to the edit page
634 # display notice that entity could not be deleted
635 return helper
.responses
.redirectToChangedSuffix(
636 request
, None, params
=page_params
)
639 redirect
= params
['delete_redirect']
641 return http
.HttpResponseRedirect(redirect
)
643 def select(self
, request
, view
, redirect
,
644 page_name
=None, params
=None, filter=None):
645 """Displays a list page allowing the user to select an entity.
647 After having selected the Scope, the user is redirected to the
648 'create a new entity' page with the scope_path set appropriately.
651 The params dictionary is also passed to getListContent from
652 the helper.list module, please refer to its docstring also.
653 The params dictionary is passed to self._list as well, refer
654 to its docstring for details on how it uses it.
657 request: the standard Django HTTP request object
658 view: the view for which to generate the select page
659 redirect: the redirect to use
660 page_name: the page name displayed in templates as page and header title
661 params: a dict with params for this View
662 filter: a filter that all displayed entities should satisfy
665 params
= dicts
.merge(params
, view
.getParams())
666 params
= dicts
.merge(params
, self
._params
)
667 params
['list_action'] = (redirect
, self
._params
)
668 params
['list_description'] = self
.DEF_CREATE_INSTRUCTION_MSG_FMT
% (
669 params
['name'], self
._params
['name'])
671 content
= helper
.lists
.getListContent(request
, params
, filter=filter)
674 return self
._list
(request
, params
, contents
, page_name
)
676 def _getData(self
, model
, filter, order
, logic
):
677 """Retrieves the pick data for this query.
680 model: the model that is being queried
681 filter: the filters that apply
682 logic: the logic that will be used for the query
685 entities
= logic
.getForFields(filter=filter, order
=order
, limit
=1000)
688 @decorators.merge_params
689 @decorators.check_access
690 def pick(self
, request
, acces_type
, page_name
=None, params
=None):
691 """Displays a list page allowing the user to select an entity.
693 After having selected an entity, the user is redirected to the
694 return_url as specified in the GET args.
697 The params dictionary is passed to self.select, refer
698 to its docstring for details on how it uses it.
701 request: the standard Django HTTP request object
702 access_type : the name of the access type which should be checked
703 page_name: the page name displayed in templates as page and header title
704 params: a dict with params for this View
707 logic
= params
['logic']
709 # convert to a regular dict
711 for key
in request
.GET
.keys():
712 # need to use getlist as we want to support multiple values
713 filter[key
] = request
.GET
.getlist(key
)
715 if params
['cache_pick']:
716 fun
= soc
.cache
.logic
.cache(self
._getData
)
721 entities
= fun(logic
.getModel(), filter, order
, logic
)
723 key_order
= params
.get('cache_pick_order')
724 data
= [i
.toDict(key_order
) for i
in entities
]
726 return self
.json(request
, data
)
728 def json(self
, request
, data
):
729 """Returns data as a json object.
736 json
= simplejson
.dumps(to_json
)
738 context
= {'json': json
}
739 template
= 'soc/json.html'
741 response
= responses
.respond(request
, template
, context
)
743 # if the browser supports HTTP/1.1
744 # post-check and pre-check and no-store for IE7
745 response
['Cache-Control'] = 'no-store, no-cache, must-revalidate, ' \
746 'post-check=0, pre-check=0'
748 # if the browser supports HTTP/1.0
749 response
['Pragma'] = 'no-cache'
753 def csv(self
, request
, data
, filename
, params
, key_order
=None):
754 """Returns data as a csv file.
756 If key_order is set data should be a sequence of dicts, otherwise
757 data should be a sequence of lists, see csv.writer and
758 csv.DictWriter for more information.
761 params
= params
.copy()
762 params
['export_extension'] = '.csv'
763 params
['export_content_type'] = 'text/csv'
764 # fieldnames = params['csv_fieldnames']
766 file_handler
= StringIO
.StringIO()
769 writer
= csv
.DictWriter(file_handler
, key_order
, dialect
='excel')
770 writer
.writerow(dicts
.identity(key_order
))
772 # encode the data to UTF-8 to ensure compatibiliy
773 for row_dict
in data
:
774 for key
in row_dict
.keys():
775 value
= row_dict
[key
]
776 if isinstance(value
, basestring
):
777 row_dict
[key
] = value
.encode("utf-8")
779 row_dict
[key
] = str(value
)
780 writer
.writerow(row_dict
)
782 writer
= csv
.writer(file_handler
, dialect
='excel')
784 # encode the data to UTF-8 to ensure compatibiliy
787 writer
.writerow(row
.encode("utf-8"))
791 data
= file_handler
.getvalue()
793 return self
.download(request
, data
, filename
, params
)
795 def _editPost(self
, request
, entity
, fields
):
796 """Performs any required processing on the entity to post its edit page.
799 request: the django request object
800 entity: the entity to create or update from POST contents
801 fields: the new field values
804 references
= self
._params
['references']
805 for field_name
, original_name
, _
in references
:
806 if field_name
not in fields
:
809 entity
= fields
.get('resolved_%s' % field_name
)
810 fields
[original_name
] = entity
812 # If scope_logic is not defined, this entity has no scope
813 if not self
._params
['scope_logic']:
816 # If this entity is unscoped, do not try to retrieve a scope
817 if 'scope_path' not in fields
:
821 scope
= self
._params
['scope_logic'].logic
.getFromKeyName(
822 fields
['scope_path'])
823 fields
['scope'] = scope
825 def _public(self
, request
, entity
, context
):
826 """Performs any required processing to get an entity's public page.
828 Should return True iff the public page should be displayed.
831 request: the django request object
832 entity: the entity to make public
833 context: the context object
838 def _editGet(self
, request
, entity
, form
):
839 """Performs any required processing on the form to get its edit page.
842 request: the django request object
843 entity: the entity to get
844 form: the django form that will be used for the page
847 # fill in the email field with the data from the entity
848 if 'scope_path' in form
.fields
:
849 form
.fields
['scope_path'].initial
= entity
.scope_path
851 for field_name
, _
, getter
in self
._params
['references']:
853 field
= getter(entity
)
854 form
.fields
[field_name
].initial
= field
.link_id
if field
else None
856 # TODO(Pawel.Solyga): use logging to log exception
859 for field
, value
in request
.GET
.iteritems():
860 if field
in form
.fields
:
861 form
.fields
[field
].initial
= value
863 def _editSeed(self
, request
, seed
):
864 """Performs any required processing on the form to get its edit page.
867 request: the django request object
868 seed: the fields to seed the create page with
872 def _editContext(self
, request
, context
):
873 """Performs any required processing on the context for edit pages.
876 request: the django request object
877 context: the context dictionary that will be used
882 def _constructResponse(self
, request
, entity
, context
,
883 form
, params
, template
=None):
884 """Updates the context and returns a response for the specified arguments.
887 request: the django request object
888 entity: the entity that is used and set in the context
889 context: the context to be used
890 form: the form that will be used and set in the context
891 params: a dict with params for this View
892 template: if specified, this template is
895 name: The name value is used to set the entity_type
896 value in the context so that the template can refer to it.
897 name_plural: same as name, but used to set entity_type_plural
898 name_short: same as name, but used to set entity_type_short
899 url_name: same as name, but used to set entity_type_url
900 edit_template: The edit_template value is used as template when
901 there is an existing entity to display the edit page for the
903 create_template: similar to edit_template, but is used when
904 there is no existing entity.
907 # logic = params['logic']
908 suffix
= entity
.key().id_or_name() if entity
else None
910 context
['form'] = form
911 context
['entity'] = entity
912 context
['entity_suffix'] = suffix
913 context
['entity_type'] = params
['name']
914 context
['entity_type_plural'] = params
['name_plural']
915 context
['entity_type_short'] = params
['name_short']
916 context
['entity_type_url'] = params
['url_name']
917 context
['edit_cancel_redirect'] = params
.get('edit_cancel_redirect')
918 context
['return_url'] = request
.path
920 if params
.get('export_content_type') and entity
:
921 context
['export_link'] = redirects
.getExportRedirect(entity
, params
)
925 template
= params
['edit_template']
927 template
= params
['create_template']
929 self
._editContext
(request
, context
)
931 # remove the seed from the context before dispatching to Django
932 context
.pop('seed', None)
934 return helper
.responses
.respond(request
, template
, context
)
937 """Returns this view's params attribute.
942 @decorators.merge_params
943 def getSidebarMenus(self
, id, user
, params
=None):
944 """Returns an dictionary with one sidebar entry.
947 params: a dict with params for this View
950 The params dictionary is passed as argument to getSidebarItems
951 from the soc.views.sitemap.sidebar module, see the docstring
952 of _getSidebarItems on how it uses it.
955 return sitemap
.sidebar
.getSidebarMenus(id, user
, params
=params
)
957 @decorators.merge_params
958 def getDjangoURLPatterns(self
, params
=None):
959 """Retrieves a list of sidebar entries for this view
962 The params dictionary is passed to the getDjangoURLPatterns
963 function in the soc.views.sitemap.sitemap module, see the
964 docstring of getDjangoURLPatterns on how it uses it.
967 params: a dict with params for this View
970 return sitemap
.sitemap
.getDjangoURLPatterns(params
)