Allow for multiple list objects
At the moment there's not really a practical use for it, since there
is no way to make soc.views.models.base.View.list() show more than
one list, but it shouldn't be too hard to allow for that.
Patch by: Sverre Rabbelier
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/logic/lists.py Fri Nov 21 23:45:37 2008 +0000
@@ -0,0 +1,134 @@
+#!/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.
+
+"""List generation logic
+"""
+
+__authors__ = [
+ '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+ ]
+
+
+class Lists(object):
+ """List array suitable for enumerating over with just 'for in'
+ """
+
+ DEF_PASSTHROUGH_FIELDS = [
+ 'pagination',
+ 'description',
+ 'heading',
+ 'row',
+ 'limit',
+ 'newest',
+ 'prev',
+ 'next',
+ 'first',
+ 'last',
+ ]
+
+ def __init__(self, contents):
+ """Constructs a new Lists object with the specified contents
+ """
+
+ # All the contents of all the lists
+ self.contents = contents
+ self.content = {}
+
+ # For iterating over all the lists
+ self.lists = range(len(contents))
+ self.list_data = []
+
+ # For iterating over the rows
+ self.rows = []
+ self.row_data = []
+
+ def __getattr__(self, attr):
+ """Delegate field lookup to the current list if appropriate
+
+ If, and only if, a lookup is done on one of the fields defined in
+ DEF_PASSTHROUGH_FIELDS, and the current list defines this field,
+ the value from the current list is returned.
+ """
+
+ if attr not in self.DEF_PASSTHROUGH_FIELDS:
+ raise AttributeError()
+
+ if attr not in self.content:
+ raise AttributeError()
+
+ return self.get(attr)
+
+ def get(self, item):
+ """Returns the item for the current list data
+ """
+
+ return self.content[item]
+
+ def next_list(self):
+ """Shifts out the current list content
+
+ The main content of the next list is returned for further processing.
+ """
+
+ # Advance the list data once
+ self.content = self.contents[0]
+ self.contents = self.contents[1:]
+
+ # Update internal 'iterators'
+ self.list_data = self.get('data')
+ self.rows = range(len(self.list_data))
+
+ return self.get('main')
+
+ def next_row(self):
+ """Returns the next list row for the current list
+
+ Before calling this method, next_list should be called at least once.
+ """
+
+ # Update internal 'iterators'
+ self.row_data = self.list_data[0]
+
+ # Advance the row data once
+ self.list_data = self.list_data[1:]
+
+ return self.get('row')
+
+ def lists(self):
+ """Returns a list of numbers the size of the amount of lists.
+
+ This method can be used to iterate over all lists with shift,
+ without using a while loop.
+ """
+
+ return self.lists
+
+ def rows(self):
+ """Returns a list of numbers the size of the amount of items.
+
+ This method can be used to iterate over all items with next for
+ the current list, without using a while loop.
+ """
+
+ return self.rows
+
+ def item(self):
+ """Returns the current row item for the current list
+
+ Before calling this method, next_row should be called at least once.
+ """
+
+ return self.row_data
--- a/app/soc/templates/soc/document/list/docs_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/document/list/docs_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,15 +1,15 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='/document/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
+onclick="document.location.href='/document/edit/{{ list.item.scope_path }}/{{ list.item.link_id }}'" name="name">
<td align="right">
<div class="title">
<a class="noul"
- href="/document/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
+ href="/document/edit/{{ list.item.scope_path }}/{{ list.item.link_id }}">{{ list.item.scope_path}}/{{ list.item.link_id }}</a>
</div>
</td>
- <td><div class="title">{{ data_element.title }}</div></td>
- <td><div class="link_id">{{ data_element.link_id }}</div></td>
- <td><div class="featured">{{ data_element.is_featured }}</div></td>
- <td><div class="author">{{ data_element.author.link_id }}</div></td>
- <td><div class="created">{{ data_element.created }}</div></td>
- <td><div class="modified">{{ data_element.modified }}</div></td>
+ <td><div class="title">{{ list.item.title }}</div></td>
+ <td><div class="link_id">{{ list.item.link_id }}</div></td>
+ <td><div class="featured">{{ list.item.is_featured }}</div></td>
+ <td><div class="author">{{ list.item.author.link_id }}</div></td>
+ <td><div class="created">{{ list.item.created }}</div></td>
+ <td><div class="modified">{{ list.item.modified }}</div></td>
</tr>
--- a/app/soc/templates/soc/group/list/group_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/group/list/group_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,9 +1,9 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='/{{ entity_type|lower }}/edit/{{ data_element.link_id }}'" name="name">
+onclick="document.location.href='/{{ entity_type|lower }}/edit/{{ list.item.link_id }}'" name="name">
<td align="right"><div class="name"><a class="noul"
- href="/{{ entity_type|lower }}/edit/{{ data_element.link_id }}">{{ data_element.name }}</a>
+ href="/{{ entity_type|lower }}/edit/{{ list.item.link_id }}">{{ list.item.name }}</a>
</div>
</td>
- <td><div class="link_id">{{ data_element.link_id }}</a></div></td>
- <td><div class="short_name">{{ data_element.short_name }}</div></td>
+ <td><div class="link_id">{{ list.item.link_id }}</a></div></td>
+ <td><div class="short_name">{{ list.item.short_name }}</div></td>
</tr>
--- a/app/soc/templates/soc/host/list/host_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/host/list/host_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,10 +1,10 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='/{{ entity_type|lower }}/edit/{{ data_element.sponsor.link_id }}/{{ data_element.user.link_id }}'" name="name">
+onclick="document.location.href='/{{ entity_type|lower }}/edit/{{ list.item.sponsor.link_id }}/{{ list.item.user.link_id }}'" name="name">
<td align="right"><div class="user_link_id"><a class="noul"
- href="/{{ entity_type|lower }}/edit/{{ data_element.sponsor.link_id }}/{{ data_element.user.link_id }}">{{ data_element.user.link_id }}</a>
+ href="/{{ entity_type|lower }}/edit/{{ list.item.sponsor.link_id }}/{{ list.item.user.link_id }}">{{ list.item.user.link_id }}</a>
</div>
</td>
- <td><div class="sponsor_name">{{ data_element.sponsor.name }}</div></td>
- <td><div class="given_name">{{ data_element.given_name }}</div></td>
- <td><div class="surname">{{ data_element.surname }}</div></td>
+ <td><div class="sponsor_name">{{ list.item.sponsor.name }}</div></td>
+ <td><div class="given_name">{{ list.item.given_name }}</div></td>
+ <td><div class="surname">{{ list.item.surname }}</div></td>
</tr>
--- a/app/soc/templates/soc/list/list_main.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/list/list_main.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,17 +1,19 @@
+{{ list.description }}
+
<div class="list">
- {% include list_pagination %}
+ {% include list.pagination %}
<table id="queues">
- {% if not list_data %}
+ {% if not list.rows %}
<tr><td colspan="9"><span class="disabled">(None)</span></td></tr>
{% else %}
- {% include list_heading %}
- {% for data_element in list_data %}
- {% include list_row %}
+ {% include list.heading %}
+ {% for _ in list.rows %}
+ {% include list.next_row %}
{% endfor %}
{% endif %}
</table>
- {% include list_pagination %}
+ {% include list.pagination %}
</div>
\ No newline at end of file
--- a/app/soc/templates/soc/list/list_pagination.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/list/list_pagination.html Fri Nov 21 23:45:37 2008 +0000
@@ -2,13 +2,13 @@
{{ pagination_form.as_table }}
- {% if newest %}
- <a class="novisit" href="{{newest}}">« First</a>
+ {% if list.newest %}
+ <a class="novisit" href="{{ list.newest }}">« First</a>
{% endif %}
- {% if prev %}
- <a class="novisit" href="{{prev}}">‹ Previous</a>
+ {% if list.prev %}
+ <a class="novisit" href="{{ list.prev }}">‹ Previous</a>
{% endif %}
- <b>{{ first }}{% if last %} - {{ last }}{% endif %}</b>
- {% if next %}<a class="novisit" href="{{next}}">Next ›</a>
+ <b>{{ list.first }}{% if list.last %} - {{ list.last }}{% endif %}</b>
+ {% if list.next %}<a class="novisit" href="{{ list.next }}">Next ›</a>
{% endif %}
</div>
--- a/app/soc/templates/soc/list/list_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/list/list_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,7 +1,7 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
onclick="document.location.href=''" name="name">
<td align="right"><div class="id"><a class="noul"
- href="">{{ data_element }}</a>
+ href="">{{ list.item }}</a>
</div>
</td>
</tr>
--- a/app/soc/templates/soc/models/list.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/models/list.html Fri Nov 21 23:45:37 2008 +0000
@@ -14,16 +14,10 @@
{% endcomment %}
{% load forms_helpers %}
{% block body %}
-<p>
+{% for _ in list.lists %}
<p>
-{% block instructions %}
-{% if instruction_text %}
-{{ instruction_text }}
-{% else %}
-List of {{ entity_type_plural }} in Google Open Source Programs.
-{% endif %}
+{% include list.next_list %}
+</p>
+{% endfor %}
+
{% endblock %}
-</p>
-{% include list_main %}
-</p>
-{% endblock %}
--- a/app/soc/templates/soc/presence/list/home_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/presence/list/home_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,10 +1,10 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='/home/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
+onclick="document.location.href='/home/settings/edit/{{ list.item.scope_path }}/{{ list.item.link_id }}'" name="name">
<td align="right">
<div class="title">
<a class="noul"
- href="/home/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
+ href="/home/settings/edit/{{ list.item.scope_path }}/{{ list.item.link_id }}">{{ list.item.scope_path}}/{{ list.item.link_id }}</a>
</div>
</td>
- <td><div class="link_id">{{ data_element.home.title }}</div></td>
+ <td><div class="link_id">{{ list.item.home.title }}</div></td>
</tr>
--- a/app/soc/templates/soc/request/list/request_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/request/list/request_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,11 +1,11 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='/{{ entity_type|lower }}/edit/{{ data_element.role|lower }}/{{ data_element.to.link_id }}/{{ data_element.requester.link_id }}'" name="name">
+onclick="document.location.href='/{{ entity_type|lower }}/edit/{{ list.item.role|lower }}/{{ list.item.to.link_id }}/{{ list.item.requester.link_id }}'" name="name">
<td align="right"><div class="user_link_id"><a class="noul"
- href="/{{ entity_type|lower }}/edit/{{ data_element.role|lower }}/{{ data_element.to.link_id }}/{{ data_element.requester.link_id }}">{{ data_element.requester.link_id }}</a>
+ href="/{{ entity_type|lower }}/edit/{{ list.item.role|lower }}/{{ list.item.to.link_id }}/{{ list.item.requester.link_id }}">{{ list.item.requester.link_id }}</a>
</div>
</td>
- <td><div class="role">{{ data_element.role }}</div></td>
- <td><div class="to">{{ data_element.to.link_id }}</div></td>
- <td><div class="accepted">{{ data_element.accepted }}</div></td>
- <td><div class="declined">{{ data_element.declined }}</div></td>
+ <td><div class="role">{{ list.item.role }}</div></td>
+ <td><div class="to">{{ list.item.to.link_id }}</div></td>
+ <td><div class="accepted">{{ list.item.accepted }}</div></td>
+ <td><div class="declined">{{ list.item.declined }}</div></td>
</tr>
--- a/app/soc/templates/soc/site/list/site_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/site/list/site_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,10 +1,10 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='/site/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
+onclick="document.location.href='/site/settings/edit/{{ list.item.scope_path }}/{{ list.item.link_id }}'" name="name">
<td align="right">
<div class="title">
<a class="noul"
- href="/site/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
+ href="/site/settings/edit/{{ list.item.scope_path }}/{{ list.item.link_id }}">{{ list.item.scope_path}}/{{ list.item.link_id }}</a>
</div>
</td>
- <td><div class="link_id">{{ data_element.home.title }}</div></td>
+ <td><div class="link_id">{{ list.item.home.title }}</div></td>
</tr>
--- a/app/soc/templates/soc/user/list/user_row.html Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/templates/soc/user/list/user_row.html Fri Nov 21 23:45:37 2008 +0000
@@ -1,10 +1,10 @@
<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'"
-onclick="document.location.href='{{redirect_action|lower}}/{{ data_element.link_id }}'" name="name">
+onclick="document.location.href='{{redirect_action|lower}}/{{ list.item.link_id }}'" name="name">
<td align="right"><div class="account"><a class="noul"
- href="{{redirect_action|lower}}/{{ data_element.link_id }}">{{ data_element.account }}</a>
+ href="{{redirect_action|lower}}/{{ list.item.link_id }}">{{ list.item.account }}</a>
</div>
</td>
- <td><div class="email">{{ data_element.account.email }}</a></div></td>
- <td><div class="public_name">{{ data_element.public_name }}</div></td>
- <td><div class="link_id">{{ data_element.link_id }}</div></td>
+ <td><div class="email">{{ list.item.account.email }}</a></div></td>
+ <td><div class="public_name">{{ list.item.public_name }}</div></td>
+ <td><div class="link_id">{{ list.item.link_id }}</div></td>
</tr>
--- a/app/soc/views/helper/lists.py Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/views/helper/lists.py Fri Nov 21 23:45:37 2008 +0000
@@ -78,36 +78,25 @@
return max(0, offset), max(1, min(limit, MAX_PAGINATION))
-DEF_LIST_TEMPLATES = {'list_main': 'soc/list/list_main.html',
- 'list_pagination': 'soc/list/list_pagination.html',
- 'list_row': 'soc/list/list_row.html',
- 'list_heading': 'soc/list/list_heading.html'}
-
-def setList(request, context, list_data,
- offset=0, limit=0, list_templates=DEF_LIST_TEMPLATES):
- """Updates template context dict with variables used for rendering lists.
+def getList(request, list_data, list_templates, description, offset=0, limit=0):
+ """Returns a dict with fields used for rendering lists.
Args:
request: the Django HTTP request object
- context: the template context dict to be updated in-place (pass in a copy
- if the original must not be modified), or None if a new one is to be
- created; any existing fields already present in the context dict passed
- in by the caller are left unaltered
list_data: array of data to be displayed in the list
offset: offset in list which defines first item to return
limit: max amount of items per page
list_templates: templates that are used when rendering list
Returns:
- updated template context dict supplied by the caller or a new context
- dict if the caller supplied None.
+ A a dictionary with the following values set:
{
- 'list_data': list data to be displayed
- 'list_main': url to list main template
- 'list_pagination': url to list pagination template
- 'list_row': url to list row template
- 'list_heading': url to list heading template
+ 'data': list data to be displayed
+ 'main': url to list main template
+ 'pagination': url to list pagination template
+ 'row': url to list row template
+ 'heading': url to list heading template
'limit': max amount of items per page,
'newest': url to first page of the list
'prev': url to previous page
@@ -115,42 +104,44 @@
'first': offset of the first item in the list
'last': offest of the lst item in the list
}
- """
+ """
+
if not list_data:
list_data = []
-
+
more = bool(list_data[limit:])
if more:
del list_data[limit:]
+
+ newest = ''
+ next = ''
+ prev = ''
+
if more:
next = request.path + '?offset=%d&limit=%d' % (offset+limit, limit)
- else:
- next = ''
+
if offset > 0:
prev = request.path + '?offset=%d&limit=%d' % (max(0, offset-limit), limit)
- else:
- prev = ''
- newest = ''
+
if offset > limit:
newest = request.path + '?limit=%d' % limit
-
- if not context:
- context = {}
-
- context.update(
- {'list_data': list_data,
- 'list_main': list_templates['list_main'],
- 'list_pagination': list_templates['list_pagination'],
- 'list_row': list_templates['list_row'],
- 'list_heading': list_templates['list_heading'],
+
+ content = {
+ 'data': list_data,
+ 'description': description,
+ 'main': list_templates['list_main'],
+ 'pagination': list_templates['list_pagination'],
+ 'row': list_templates['list_row'],
+ 'heading': list_templates['list_heading'],
'limit': limit,
'newest': newest,
'prev': prev,
'next': next,
'first': offset+1,
- 'last': len(list_data) > 1 and offset+len(list_data) or None})
-
- return context
+ 'last': len(list_data) > 1 and offset+len(list_data) or None
+ }
+
+ return content
def makePaginationForm(
--- a/app/soc/views/models/base.py Fri Nov 21 23:45:15 2008 +0000
+++ b/app/soc/views/models/base.py Fri Nov 21 23:45:37 2008 +0000
@@ -29,6 +29,7 @@
from django.utils.translation import ugettext_lazy
import soc.logic
+import soc.logic.lists
import soc.logic.out_of_band
import soc.views.helper.lists
import soc.views.helper.responses
@@ -125,6 +126,8 @@
new_params['list_redirect_action'] = '/' + params['url_name'] + '/edit'
+ description = ugettext_lazy('List of %(name)s in Google Open Source Programs.')
+ new_params['list_description'] = description % params
new_params['save_message'] = [ugettext_lazy('Profile saved.')]
new_params['edit_params'] = {
self.DEF_SUBMIT_MSG_PARAM_NAME: self.DEF_SUBMIT_MSG_PROFILE_SAVED,
@@ -349,9 +352,11 @@
context['pagination_form'] = helper.lists.makePaginationForm(request, limit)
templates = params['lists_template']
+ description = params['list_description']
- context = helper.lists.setList(request, context, entities,
- offset, limit, templates)
+ content = helper.lists.getList(request, entities, templates,
+ description, offset, limit)
+ context['list'] = soc.logic.lists.Lists([content])
context['entity_type'] = params['name']
context['entity_type_plural'] = params['name_plural']