Added public view support (not using controller yet)
authorPawel Solyga <Pawel.Solyga@gmail.com>
Fri, 22 Aug 2008 13:44:50 +0000
changeset 99 8c38b546a3cf
parent 98 b2b823466a8b
child 100 97cb7f42cd82
Added public view support (not using controller yet) Changed Google Account variable from user to id in views and templates (no more confusions with Melange user). Added templates_helpers for makeSimblingTemplate function. Addded new template tag readonly_field_as_table_row used in public views Fixed one typo in roles.py
app/soc/models/user.py
app/soc/templates/soc/base.html
app/soc/templates/soc/templatetags/_readonly_field_as_table_row.html
app/soc/templates/soc/user/profile/edit.html
app/soc/templates/soc/user/profile/public.html
app/soc/views/helpers/response_helpers.py
app/soc/views/helpers/templates_helpers.py
app/soc/views/helpers/templatetags/forms_helpers.py
app/soc/views/user/profile.py
app/soc/views/user/roles.py
--- a/app/soc/models/user.py	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/models/user.py	Fri Aug 22 13:44:50 2008 +0000
@@ -65,27 +65,27 @@
       'Lower ASCII characters only.')
 
   @staticmethod
-  def doesUserExist(user=None):
+  def doesUserExist(id=None):
     """Returns if user already exists in the Datastore.
     
     Args:
       user: a Google Account object,
     """
     #: let's do a gql query and check if user exists in datastore
-    data = self.getUser(user)
+    data = self.getUserForId(id)
     if data:
       return True
     else:
       return False
 
   @staticmethod
-  def getUser(user=None):
+  def getUserForId(id=None):
     """Returns User entity from datastore, or None if not found.  
     
     Args:
       user: a Google Account object,
     """
-    return User.gql('WHERE id = :1', user).get()
+    return User.gql('WHERE id = :1', id).get()
 
   @staticmethod
   def getUserForLinkname(link_name=None):
--- a/app/soc/templates/soc/base.html	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/templates/soc/base.html	Fri Aug 22 13:44:50 2008 +0000
@@ -27,14 +27,14 @@
 
   <div id="login">
 	{% block login_links %}
-	{% if user %}
-	<b>{{ user.email }} ({{ user.nickname }})</b> | 
+	{% if id %}
+	<b>{{ id.email }} ({{ id.nickname }})</b> | 
 	{% endif %}
 	{% if is_dev %}
 	<a class="novisit" target="_blank" href="/_ah/admin">Admin</a> | 
 	{% endif %}
 	<a class="novisit" href="http://code.google.com/p/soc/issues/list">Report bugs</a> | 
-	{% if user %}
+	{% if id %}
 	<a class="novisit" href="{{sign_out}}">Sign out</a>
 	{% else %}
 	<a class="novisit" href="{{sign_in}}">Sign in</a>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/templatetags/_readonly_field_as_table_row.html	Fri Aug 22 13:44:50 2008 +0000
@@ -0,0 +1,21 @@
+{% 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 %}
+<tr>
+ <td class="fieldlabel">
+	{{ field_label }}
+ </td>
+ <td class="fieldvalue">
+	{{ field_value }}
+ </td>
+</tr>
--- a/app/soc/templates/soc/user/profile/edit.html	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/templates/soc/user/profile/edit.html	Fri Aug 22 13:44:50 2008 +0000
@@ -15,10 +15,10 @@
 {% load forms_helpers %}
 {% block page_title %}User Profile{% endblock %}
 {% block header_title %}
-{% if soc_nick_name %}
-Modify Existing User Profile for {{ soc_nick_name }} <a href="mailto:{{ user.email }} ">&lt;{{ user.email }}&gt;</a>
+{% if user %}
+Modify Existing User Profile for {{ user.nick_name }} <a href="mailto:{{ id.email }} ">&lt;{{ id.email }}&gt;</a>
 {% else %}
-Create a New User Profile for <a href="mailto:{{ user.email }} ">&lt;{{ user.email }}&gt;</a>
+Create a New User Profile for <a href="mailto:{{ id.email }} ">&lt;{{ id.email }}&gt;</a>
 {% endif %}
 {% endblock %}
 {% block body %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/user/profile/public.html	Fri Aug 22 13:44:50 2008 +0000
@@ -0,0 +1,27 @@
+{% 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 %}
+{% load forms_helpers %}
+{% block page_title %}User Public Profile{% endblock %}
+{% block header_title %}
+User Public Profile for {{ user.nick_name }}
+{% endblock %}
+{% block body %}
+<p>
+ <table>
+  {% readonly_field_as_table_row "Nick name:" user.nick_name %}
+  {% readonly_field_as_table_row "Link name:" user.link_name %}
+ </table>
+</p>
+{% endblock %}
--- a/app/soc/views/helpers/response_helpers.py	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/views/helpers/response_helpers.py	Fri Aug 22 13:44:50 2008 +0000
@@ -55,7 +55,7 @@
     params = {}
   
   params['request'] = request
-  params['user'] = users.get_current_user()
+  params['id'] = users.get_current_user()
   params['is_admin'] = users.is_current_user_admin()
   params['is_dev'] = IS_DEV
   params['sign_in'] = users.create_login_url(request.path)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/views/helpers/templates_helpers.py	Fri Aug 22 13:44:50 2008 +0000
@@ -0,0 +1,31 @@
+#!/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.
+
+"""Helpers used with templates.
+"""
+
+__authors__ = [
+  '"Todd Larsen" <tlarsen@google.com>',
+  '"Pawel Solyga" <pawel.solyga@gmail.com',
+  ]
+
+
+def makeSiblingTemplatePath(template_path, view_template):
+  """Replaces the template name at the end of template_path with
+     view_template argument.
+  """
+  #TODO(solydzajs) : implements this funtion
+  return
\ No newline at end of file
--- a/app/soc/views/helpers/templatetags/forms_helpers.py	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/views/helpers/templatetags/forms_helpers.py	Fri Aug 22 13:44:50 2008 +0000
@@ -19,6 +19,7 @@
 
 __authors__ = [
   '"Todd Larsen" <tlarsen@google.com>',
+  '"Pawel Solyga" <pawel.solyga@gmail.com>',
   ]
 
 
@@ -53,3 +54,37 @@
       { 'field': field }
   """
   return {'field': field}
+
+
+@register.inclusion_tag('soc/templatetags/_readonly_field_as_table_row.html')
+def readonly_field_as_table_row(field_label, field_value):
+  """Prints a field value and it's verbose name as a table row.
+
+  This function actually does very little, simply passing the 
+  supplied field_label and field_value in a simple context used by the 
+  _readonly_field_as_table_row.html template (which is actually 
+  doing all of the work).
+
+  See soc/templates/soc/templatetags/_readonly_field_as_table_row.html for the CSS
+  styles used by this template tag.
+
+  Usage:
+    {% load forms_helpers %}
+    ...
+    <table>
+     {% readonly_field_as_table_row field_label field_value %}
+     ...
+    </table>
+
+  Args:
+    field_label: label of the field to render
+    field_value: value of the field to render
+
+  Returns:
+    a simple context containing the supplied newforms field instance:
+      { 'field_label': field_label',
+        'field_value': field_value'}
+  """
+  return {'field_label': field_label,
+          'field_value': field_value}
+
--- a/app/soc/views/user/profile.py	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/views/user/profile.py	Fri Aug 22 13:44:50 2008 +0000
@@ -53,16 +53,16 @@
     """
     #: db.Model subclass for which the form will gather information
     model = soc.models.user.User
-
+    
     #: list of model fields which will *not* be gathered by the form
     exclude = ['id']
   
   def clean_link_name(self):
     linkname = self.cleaned_data.get('link_name')
     linkname_user = soc.models.user.User.getUserForLinkname(linkname)
-    user = users.get_current_user()
+    current_id = users.get_current_user()
     # if linkname exist in datastore and doesn't belong to current user
-    if linkname_user and (linkname_user.id != user):
+    if linkname_user and (linkname_user.id != current_id):
       raise forms.ValidationError("This link name is already in use.")
     elif not self.LINKNAME_REGEX.match(linkname):
       raise forms.ValidationError("This link name is in wrong format.")
@@ -83,28 +83,42 @@
   """
   #TODO(solydzajs): create controller for User and cleanup code in this handler
   
-  #: If user not signed in redirect to sign-in page
-  user = users.get_current_user()
-  if not user:
+  #TODO(solydzajs): use makeSiblingTemplatePath from templates_helpers and pass
+  #                 result to public view
+  
+  # TODO: use something like the code below, define global public tmpl 
+  # template_choices = [makeSiblingTemplatePath(template, 'public.html'),
+  # DEF_USER_PROFILE_PUBLIC_TMPL])
+  # public(request, linkname=linkname, template=template_choices)
+  
+  #: If user not signed and there is no linkname redirect to sign-in page
+  #: otherwise show public profile for linkname user
+  current_id = users.get_current_user()
+  if not current_id and not linkname:
     return http.HttpResponseRedirect(users.create_login_url(request.path))
-
-  soc_user = soc.models.user.User.getUser(user)
+  elif not current_id and linkname:
+    return public(request, linkname)
+    
+  user = soc.models.user.User.getUserForId(current_id)
   
-  #: Show custom 404 page when linkname in url doesn't match current user
+  #: Show custom 404 page when linkname doesn't exist in datastore
+  #: or show public view for linkname user
   if linkname:
     linkname_user = soc.models.user.User.getUserForLinkname(linkname)
-    if (linkname_user and linkname_user.id != user) or not linkname_user:
+    if not linkname_user:
       return http.HttpResponseNotFound('No user exists with that link name "%s"' %
                                 linkname)
+    elif linkname_user and (linkname_user.id != current_id):
+      return public(request, linkname)
 
   #: GET method
-  if (request.method != 'POST') and soc_user:
-    form = UserForm(initial={'nick_name': soc_user.nick_name,
-                             'link_name': soc_user.link_name})
+  if (request.method != 'POST') and user:
+    form = UserForm(initial={'nick_name': user.nick_name,
+                             'link_name': user.link_name})
     return response_helpers.respond(request,
         template, {'template': template, 
                    'form': form, 
-                   'soc_nick_name': soc_user.nick_name})
+                   'user': user})
   
   #: POST method
   form = UserForm()
@@ -114,18 +128,46 @@
     if form.is_valid():
       linkname = form.cleaned_data.get('link_name')
       nickname = form.cleaned_data.get("nick_name")
-      if not soc_user:
-        soc_user = soc.models.user.User(id = user,link_name = linkname,
+      if not user:
+        user = soc.models.user.User(id = user,link_name = linkname,
                                         nick_name = nickname)
       else:
-        soc_user.nick_name = nickname
-        soc_user.link_name = linkname
-      soc_user.put()
+        user.nick_name = nickname
+        user.link_name = linkname
+      user.put()
       return response_helpers.respond(request,
               template, {'template': template, 
-                        'form': form, 
-                        'soc_nick_name': nickname,
-                        'submit_message': 'Profile saved.'})
+                         'form': form, 
+                         'user': user,
+                         'submit_message': 'Profile saved.'})
 
   return response_helpers.respond(request,
       template, {'template': template, 'form': form})
+
+
+def public(request, linkname=None,
+           template='soc/user/profile/public.html'):
+  """A "general public" view of a User on the site.
+
+  Args:
+    request: the standard django request object.
+    linkname: the User's site-unique "linkname" extracted from the URL
+    template: the template path to use for rendering the template.
+
+  Returns:
+    A subclass of django.http.HttpResponse with generated template.
+  """
+  #: If linkname is empty or not a valid linkname on the site, display
+  #: "user does not exist", otherwise render public view for linkname user
+  if linkname:
+    linkname_user = soc.models.user.User.getUserForLinkname(linkname)
+    if not linkname_user:
+      return http.HttpResponseNotFound('No user exists with that link name "%s"' %
+                                linkname)
+    else:
+      return response_helpers.respond(request, 
+          template, {'template': template,
+                     'user': linkname_user})
+      
+  return http.HttpResponseNotFound('No user exists with that link name "%s"' %
+                            linkname)
--- a/app/soc/views/user/roles.py	Wed Aug 20 21:59:00 2008 +0000
+++ b/app/soc/views/user/roles.py	Fri Aug 22 13:44:50 2008 +0000
@@ -72,7 +72,7 @@
   """
   #TODO(tlarsen): this module is currently a placeholder for future work
   
-  # TODO: if linkname is empty or not a vaild linkname on the site, display
+  # TODO: if linkname is empty or not a valid linkname on the site, display
   # some sort of "user does not exist" page (a custom 404 page, maybe?).
   
   return response_helpers.respond(request,