Implements a Site (Developer) generic Document editor form.
authorTodd Larsen <tlarsen@google.com>
Wed, 01 Oct 2008 06:24:17 +0000
changeset 237 d360162714b6
parent 236 d5302883f3ac
child 238 d6b533f99a45
Implements a Site (Developer) generic Document editor form.
app/soc/templates/soc/site/docs/edit.html
app/soc/views/site/docs/edit.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/site/docs/edit.html	Wed Oct 01 06:24:17 2008 +0000
@@ -0,0 +1,63 @@
+{% extends "soc/base.html" %}
+{% comment %}
+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.
+{% endcomment %}
+
+{% block scripts %}
+	<script type="text/javascript" src="/tiny_mce/tiny_mce_src.js"></script>
+{% endblock %}
+{% block page_title %}
+ {% if existing_doc %}
+  Site: Modify Existing Document
+ {% else %}
+  Site: Create New Document
+ {% endif %}
+{% endblock %}
+{% block header_title %}
+ {% if existing_doc %}
+  Modify Existing Document
+   <a href="/docs/{{ existing_doc.partial_path }}/{{ existing_doc.link_name }}">"{{ existing_doc.title }}"</a>
+ {% else %}
+  Create a New Document
+ {% endif %}
+{% endblock %}
+
+{% block body %}
+<p>
+<p>
+{% block instructions %}
+Please use this form to edit the document.
+{% endblock %}
+</p>
+<form method="POST">
+ <table>
+	{{ form.as_table }}
+  <tr>
+   <td colspan="4">&nbsp;</td>
+  </tr>
+  <tr>
+   <td> 
+    <input style="font-weight: bold" type="submit" value="Save Changes"/></span>
+   </td>
+   <td>
+    <input type="button" onclick="location.href='/'" value="Cancel"/>
+   </td>
+   <td>&nbsp;</td>
+   <td>
+    {% if submit_message %}<b><i>{{ submit_message }}</i></b>{% endif %}
+   </td>
+  </tr>
+ </table>
+</form>
+</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/views/site/docs/edit.py	Wed Oct 01 06:24:17 2008 +0000
@@ -0,0 +1,280 @@
+#!/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.
+
+"""Developer views for editing and examining Documents.
+"""
+
+__authors__ = [
+  '"Todd Larsen" <tlarsen@google.com>',
+  ]
+
+
+from google.appengine.api import users
+
+from django import http
+from django import newforms as forms
+from django.utils.translation import ugettext_lazy
+
+from soc.logic import document
+from soc.logic import key_name
+from soc.logic import out_of_band
+from soc.logic.site import id_user
+from soc.views import simple
+from soc.views.helpers import custom_widgets
+from soc.views.helpers import forms_helpers
+from soc.views.helpers import request_helpers
+from soc.views.helpers import response_helpers
+from soc.views.user import profile
+
+import soc.models.document
+
+
+class EditForm(forms_helpers.DbModelForm):
+  """Django form displayed when Developer edits a Document.
+  """
+  doc_key_name = forms.CharField(widget=forms.HiddenInput)
+  content = forms.fields.CharField(widget=custom_widgets.TinyMCE())
+  
+  class Meta:
+    model = soc.models.document.Document
+    
+    #: list of model fields which will *not* be gathered by the form
+    exclude = ['inheritance_line', 'user', 'created', 'modified']
+ 
+  def clean_partial_path(self):
+    partial_path = self.cleaned_data.get('partial_path')
+    # TODO(tlarsen): combine path and link_name and check for uniqueness
+    return partial_path
+
+  def clean_link_name(self):
+    link_name = self.cleaned_data.get('link_name')
+    # TODO(tlarsen): combine path and link_name and check for uniqueness
+    return link_name
+
+
+DEF_SITE_DOCS_EDIT_TMPL = 'soc/site/docs/edit.html'
+DEF_CREATE_NEW_DOC_MSG = ' You can create a new user by visiting the' \
+                         ' <a href="/site/docs/edit">Create ' \
+                         'a New Document</a> page.'
+
+def edit(request, partial_path=None, linkname=None,
+         template=DEF_SITE_DOCS_EDIT_TMPL):
+  """View for a Developer to modify the properties of a Document Model entity.
+
+  Args:
+    request: the standard django request object
+    path: the Document's site-unique "path" extracted from the URL
+    template: the "sibling" template (or a search list of such templates)
+      from which to construct the public.html template name (or names)
+
+  Returns:
+    A subclass of django.http.HttpResponse which either contains the form to
+    be filled out, or a redirect to the correct view in the interface.
+  """
+  # create default template context for use with any templates
+  context = response_helpers.getUniversalContext(request)
+
+  logged_in_id = users.get_current_user()
+  
+  alt_response = simple.getAltResponseIfNotDeveloper(request, context, 
+                                                     id=logged_in_id)
+  if alt_response:
+    # not a developer
+    return alt_response
+  
+  alt_response = simple.getAltResponseIfNotLoggedIn(request, context, 
+                                                    id=logged_in_id)
+  if alt_response:
+    # not logged in
+    return alt_response
+  
+  alt_response = simple.getAltResponseIfNotUser(request, context, 
+                                                id = logged_in_id)
+  if alt_response:
+    # no existing User entity for logged in Google Account. User entity is 
+    # required for creating Documents
+    return alt_response
+
+  alt_response = simple.getAltResponseIfNotDeveloper(request,
+                                                     context=context)
+  if alt_response:
+    return alt_response
+
+  doc = None  # assume that no Document entity will be found
+
+  path = key_name.combinePath([partial_path, linkname])
+
+  # try to fetch Document entity corresponding to path if one exists    
+  try:
+    doc = document.getDocumentIfPath(path)
+  except out_of_band.ErrorResponse, error:
+    # show custom 404 page when path doesn't exist in Datastore
+    error.message = error.message + DEF_CREATE_NEW_DOC_MSG
+    return simple.errorResponse(request, error, template, context)
+
+  if request.method == 'POST':
+    form = EditForm(request.POST)
+
+    if form.is_valid():
+      new_partial_path = form.cleaned_data.get('partial_path')
+      new_linkname = form.cleaned_data.get('link_name')
+      title = form.cleaned_data.get('title')
+      short_name = form.cleaned_data.get('short_name')
+      abstract = form.cleaned_data.get('abstract')
+      content = form.cleaned_data.get('content')
+      doc_key_name = form.cleaned_data.get('doc_key_name')
+      
+      doc = soc.logic.document.updateOrCreateDocument(
+          partial_path=new_partial_path, link_name=new_linkname,
+          title=title, short_name=short_name, abstract=abstract,
+          content=content, user=id_user.getUserFromId(logged_in_id))
+      
+      if not doc:
+        return http.HttpResponseRedirect('/')
+
+      new_path = key_name.combinePath([new_partial_path, new_linkname])
+        
+      # redirect to new /site/docs/edit/new_path?s=0
+      # (causes 'Profile saved' message to be displayed)
+      return response_helpers.redirectToChangedSuffix(
+          request, path, new_path,
+          params=profile.SUBMIT_PROFILE_SAVED_PARAMS)
+  else: # method == 'GET':
+    # try to fetch Document entity corresponding to path if one exists
+    if path:
+      if doc:
+        # is 'Profile saved' parameter present, but referrer was not ourself?
+        # (e.g. someone bookmarked the GET that followed the POST submit) 
+        if (request.GET.get(profile.SUBMIT_MSG_PARAM_NAME)
+            and (not request_helpers.isReferrerSelf(request, suffix=path))):
+          # redirect to aggressively remove 'Profile saved' query parameter
+          return http.HttpResponseRedirect(request.path)
+    
+        # referrer was us, so select which submit message to display
+        # (may display no message if ?s=0 parameter is not present)
+        context['submit_message'] = (
+            request_helpers.getSingleIndexedParamValue(
+                request, profile.SUBMIT_MSG_PARAM_NAME,
+                values=profile.SUBMIT_MESSAGES))
+
+        # populate form with the existing User entity
+        form = EditForm(initial={'doc_key_name': doc.key().name(),
+            'title': doc.title, 'partial_path': doc.partial_path,
+            'link_name': doc.link_name, 'short_name': doc.short_name,
+            'abstract': doc.abstract, 'content': doc.content,
+            'user': doc.user})       
+      else:
+        if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
+          # redirect to aggressively remove 'Profile saved' query parameter
+          return http.HttpResponseRedirect(request.path)
+          
+        context['lookup_error'] = ugettext_lazy(
+            'Document with that path not found.')
+        form = EditForm(initial={'link_name': linkname})
+    else:  # no link name specified in the URL
+      if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
+        # redirect to aggressively remove 'Profile saved' query parameter
+        return http.HttpResponseRedirect(request.path)
+
+      # no link name specified, so start with an empty form
+      form = EditForm()
+
+  context.update({'form': form,
+                  'existing_doc': doc})
+
+  return response_helpers.respond(request, template, context)
+
+
+class CreateForm(forms_helpers.DbModelForm):
+  """Django form displayed when Developer creates a Document.
+  """
+  doc_key_name = forms.CharField(widget=forms.HiddenInput)
+  content = forms.fields.CharField(widget=custom_widgets.TinyMCE())
+  
+  class Meta:
+    model = soc.models.document.Document
+    
+    #: list of model fields which will *not* be gathered by the form
+    exclude = ['inheritance_line', 'user', 'created', 'modified']
+ 
+  def clean_partial_path(self):
+    partial_path = self.cleaned_data.get('partial_path')
+    # TODO(tlarsen): combine path and link_name and check for uniqueness
+    return partial_path
+
+  def clean_link_name(self):
+    link_name = self.cleaned_data.get('link_name')
+    # TODO(tlarsen): combine path and link_name and check for uniqueness
+    return link_name
+
+
+DEF_SITE_DOCS_CREATE_TMPL = 'soc/site/docs/edit.html'
+
+def create(request, template=DEF_SITE_DOCS_CREATE_TMPL):
+  """View for a Developer to create a new Document entity.
+
+  Args:
+    request: the standard django request object
+    template: the "sibling" template (or a search list of such templates)
+      from which to construct the public.html template name (or names)
+
+  Returns:
+    A subclass of django.http.HttpResponse which either contains the form to
+    be filled out, or a redirect to the correct view in the interface.
+  """
+  # create default template context for use with any templates
+  context = response_helpers.getUniversalContext(request)
+
+  alt_response = simple.getAltResponseIfNotDeveloper(request,
+                                                     context=context)
+  if alt_response:
+    return alt_response
+
+  if request.method == 'POST':
+    form = CreateForm(request.POST)
+
+    if form.is_valid():
+      new_partial_path = form.cleaned_data.get('partial_path')
+      new_linkname = form.cleaned_data.get('link_name')
+      title = form.cleaned_data.get('title')
+      short_name = form.cleaned_data.get('short_name')
+      abstract = form.cleaned_data.get('abstract')
+      content = form.cleaned_data.get('content')
+      doc_key_name = form.cleaned_data.get('doc_key_name')
+      
+      doc = soc.logic.document.updateOrCreateDocument(
+          partial_path=new_partial_path, link_name=new_linkname,
+          title=title, short_name=short_name, abstract=abstract,
+          content=content, user=id_user.getUserFromId(logged_in_id))
+
+      if not doc:
+        return http.HttpResponseRedirect('/')
+
+      new_path = key_name.combinePathAndLinkName(
+          new_partial_path, new_linkname)
+        
+      # redirect to new /site/docs/edit/new_path?s=0
+      # (causes 'Profile saved' message to be displayed)
+      return response_helpers.redirectToChangedSuffix(
+          request, None, new_path,
+          params=profile.SUBMIT_PROFILE_SAVED_PARAMS)
+  else: # method == 'GET':
+    # no link name specified, so start with an empty form
+    form = CreateForm()
+
+  context.update({'form': form})
+
+  return response_helpers.respond(request, template, context)