changeset 185:3d1a07772d4d

Rework title/icon template infrastructure
author Sylvain Beucler <beuc@beuc.net>
date Sun, 25 Jul 2010 09:59:57 +0200
parents 49cc271f6de8
children 6bc5e698e9c4
files savane/svmain/models.py savane/svmain/templatetags/svpagemenu.py savane/svmain/templatetags/svtopmenu.py savane/svmain/urls.py savane/svmain/views.py static_media/savane/css/Savannah.css templates/base.html templates/index.html templates/svmain/group_admin.html templates/svmain/group_admin_members.html templates/svmain/group_detail.html templates/svmain/svpagemenu.html templates/svmain/svtopmenu.html templates/title.html
diffstat 14 files changed, 161 insertions(+), 107 deletions(-) [+]
line wrap: on
line diff
--- a/savane/svmain/models.py
+++ b/savane/svmain/models.py
@@ -480,6 +480,12 @@
     #patch_private_exclude_address text
     #cookbook_private_exclude_address text
 
+    def full_name_display(self):
+        if self.full_name != "":
+            return self.full_name
+        else:
+            return self.group.name
+
     @staticmethod
     def query_active_groups_raw(conn, fields):
         """
deleted file mode 100644
--- a/savane/svmain/templatetags/svpagemenu.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Top-level menu
-# Copyright (C) 2010  Sylvain Beucler
-#
-# This file is part of Savane.
-# 
-# Savane is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-# 
-# Savane is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-# 
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from django import template
-from django.core.urlresolvers import reverse
-import savane.svmain.models as svmain_models
-from django.conf import settings
-
-register = template.Library()
-
-@register.inclusion_tag('svmain/svpagemenu.html', takes_context=True)
-def svpagemenu(context, menu_name):
-    """
-    Return info to build the top menu, including menu structure and
-    page icon.
-    """
-    icon = 'main'
-    entries = []
-
-    if menu_name == 'group':
-        entry_home = { 'text' : 'Home',
-                   'href' : reverse('savane.svmain.group_detail', args=[context['group'].name]),
-                   'title': "Project Main Page at %s" % 'this website'}
-        entry_home['children'] = []
-        entry_home['children'].append({'text' : 1.1, 'href' : 1.1, 'title': 1.1 })
-        if (context['user'].groups.filter(name=context['group']).count()):
-            entry_home['children'].append({'separator' : True })
-            entry_home['children'].append({'text' : "I'm a member", 'href' : 1.2, 'title': 1.2 })
-        if (svmain_models.Membership.objects.filter(user=context['user'], group=context['group'], admin_flags='A').count()):
-            entry_home['children'].append({'separator' : True })
-            entry_home['children'].append({'text' : "I'm an admin",
-                                           'href' : reverse('savane.svmain.group_admin', args=[context['group'].name]) })
-
-        entry_test = {
-                    'text' : 2, 'href' : 2, 'title': 2, 'children':
-                    [
-                        {'text' : 2.1, 'href' : 2.1, 'title': 2.1 },
-                    ]
-                }
-
-        entries.append(entry_home)
-        entries.append(entry_test)
-    elif menu_name == 'my':
-        pass
-
-    context = {
-        'title' : context['title'],
-        'menu_name' : menu_name,
-        'entries' : entries,
-        'icon' : icon,
-        # STATIC_MEDIA_URL is not available in inclusion tags, because
-        # RequestContext is not used; let's work around that lack:
-        'STATIC_MEDIA_URL' : settings.STATIC_MEDIA_URL,
-        }
-    return context
new file mode 100644
--- /dev/null
+++ b/savane/svmain/templatetags/svtopmenu.py
@@ -0,0 +1,69 @@
+# Top-level menu
+# Copyright (C) 2010  Sylvain Beucler
+#
+# This file is part of Savane.
+# 
+# Savane is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+# 
+# Savane is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from django import template
+from django.core.urlresolvers import reverse
+import savane.svmain.models as svmain_models
+from django.conf import settings
+
+register = template.Library()
+
+@register.inclusion_tag('svmain/svtopmenu.html', takes_context=True)
+def svtopmenu(context, menu_name):
+    """
+    Return info to build the top menu, including menu structure and
+    page icon.
+
+    TODO: use context['request'].PATH_INFO to determine if a link is
+    the current URL, and mark it so we can apply a different CSS style
+    on it.
+    """
+    icon = 'main'
+    entries = []
+
+    if menu_name == 'group':
+        entry_home = { 'text' : 'Home',
+                   'href' : reverse('savane.svmain.group_detail', args=[context['group'].name]),
+                   'title': "Project Main Page at %s" % 'this website'}
+        entry_home['children'] = []
+        entry_home['children'].append({'text' : 1.1, 'href' : 1.1, 'title': 1.1 })
+        if (context['user'].groups.filter(name=context['group']).count()):
+            entry_home['children'].append({'separator' : True })
+            entry_home['children'].append({'text' : "I'm a member", 'href' : 1.2, 'title': 1.2 })
+        if (svmain_models.Membership.objects.filter(user=context['user'], group=context['group'], admin_flags='A').count()):
+            entry_home['children'].append({'separator' : True })
+            entry_home['children'].append({'text' : "I'm an admin",
+                                           'href' : reverse('savane.svmain.group_admin', args=[context['group'].name]) })
+
+        entry_test = {
+                    'text' : 2, 'href' : 2, 'title': 2, 'children':
+                    [
+                        {'text' : 2.1, 'href' : 2.1, 'title': 2.1 },
+                    ]
+                }
+
+        entries.append(entry_home)
+        entries.append(entry_test)
+    elif menu_name == 'my':
+        pass
+
+    context = {
+        'menu_name' : menu_name,
+        'entries' : entries,
+        }
+    return context
--- a/savane/svmain/urls.py
+++ b/savane/svmain/urls.py
@@ -83,8 +83,11 @@
   url(r'^projects/(?P<slug>[-\w]+)/$', views.group_redir),
   url(r'^p/(?P<slug>[-\w]+)/join/$', views.group_join),
   url(r'^p/(?P<slug>[-\w]+)/admin/$', views.group_admin,
-      { 'extra_context' : { 'title' : 'Project administration' }, },
+      { 'extra_context' : { 'title' : 'Administration Summary' }, },
       name='savane.svmain.group_admin'),
+  url(r'^p/(?P<slug>[-\w]+)/admin/members/$', views.group_admin_members,
+      { 'extra_context' : { 'title' : 'Administration Summary: Manage Members' }, },
+      name='savane.svmain.group_admin_members'),
 
   url(r'^license/$', 'django.views.generic.list_detail.object_list',
       { 'queryset' : svmain_models.License.objects.all(),
--- a/savane/svmain/views.py
+++ b/savane/svmain/views.py
@@ -51,3 +51,15 @@
         }
     context.update(extra_context)
     return context
+
+@render_to('svmain/group_admin_members.html', mimetype=None)
+def group_admin_members(request, slug, extra_context={}):
+    group = get_object_or_404(auth_models.Group, name=slug)
+    members = group.user_set.all()
+
+    context = {
+        'group' : group,
+        'members' : members,
+        }
+    context.update(extra_context)
+    return context
--- a/static_media/savane/css/Savannah.css
+++ b/static_media/savane/css/Savannah.css
@@ -903,6 +903,7 @@
 /* <h1> Page title */
 h1 {
 	text-indent: 0.3em;
+	font-size: 1.5em;
 }
 /* <h3> Section title */
 h3 {
--- a/templates/base.html
+++ b/templates/base.html
@@ -36,16 +36,18 @@
       </ul>
 
       <div class="main"><a name="top"></a>
-	{% block pagemenu %}
-	<h1><img src="{{STATIC_MEDIA_URL}}savane/images/common/contexts1/main.orig.png"
+	{% block top %}{% comment %} top's purpose is to be emptied in index.html {% endcomment %}
+	<h1><img src="{{STATIC_MEDIA_URL}}savane/images/common/contexts1/{% block icon %}main{% endblock %}.orig.png"
 		 width="48" height="48" alt="" class="pageicon" />{% include "title.html" %}</h1>
+	{% block topmenu %}{% comment %} topmenu is usually overriden with a block containing a call to "{% svtopmenu ... %}" {% endcomment %}
 	<div class="topmenu" id="topmenu"></div>
 	{% endblock %}
+	{% endblock %}
 
         <div class="content">
-        {% if messages %}
-        <ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>
-        {% endif %}
+          {% if messages %}
+          <ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>
+          {% endif %}
 
           {% block content %}
           {% endblock %}
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,6 +1,6 @@
 {%  extends "base.html" %}
 
-{% block pagemenu %}{% endblock %}
+{% block top %}{% endblock %}
 
 {% block content %}
 <div class="intro">
--- a/templates/svmain/group_admin.html
+++ b/templates/svmain/group_admin.html
@@ -1,17 +1,19 @@
 {% extends "base.html" %}
 {% load i18n %}
-{% load svpagemenu %}
+{% load svtopmenu %}
 
-{% block pagemenu %}
-  {% svpagemenu "group" %}
+{% block title %}
+{{group.svgroupinfo.full_name_display}} - {{title}}
+{% endblock %}
+
+{% block icon %}preferences{% endblock %}
+
+{% block topmenu %}
+  {% svtopmenu "group" %}
 {% endblock %}
 
 {% block content %}
 
-<p>
-Project: {{group.name}}<br />
-</p>
-
 <ul>
 <li><a href="members/">Manage members</a></li>
 </ul>
new file mode 100644
--- /dev/null
+++ b/templates/svmain/group_admin_members.html
@@ -0,0 +1,26 @@
+{% extends "base.html" %}
+{% load i18n %}
+{% load svtopmenu %}
+
+{% block title %}
+{{group.svgroupinfo.full_name_display}} - {{title}}
+{% endblock %}
+
+{% block icon %}preferences{% endblock %}
+
+{% block topmenu %}
+  {% svtopmenu "group" %}
+{% endblock %}
+
+{% block content %}
+
+
+{% endblock %}
+
+{% comment %}
+Local Variables: **
+mode: django-html **
+tab-width: 4 **
+indent-tabs-mode: nil **
+End: **
+{% endcomment %}
--- a/templates/svmain/group_detail.html
+++ b/templates/svmain/group_detail.html
@@ -1,9 +1,9 @@
 {% extends "base.html" %}
 {% load i18n %}
-{% load svpagemenu %}
+{% load svtopmenu %}
 
-{% block pagemenu %}
-  {% svpagemenu "group" %}
+{% block topmenu %}
+  {% svtopmenu "group" %}
 {% endblock %}
 
 {% block content %}
deleted file mode 100644
--- a/templates/svmain/svpagemenu.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<h1><img src="{{STATIC_MEDIA_URL}}savane/images/common/contexts1/{{icon}}.orig.png"
-	 width="48" height="48" alt="" class="pageicon" />{% include "title.html" %}</h1>
-
-<ul class="topmenu" id="topmenu">
-{% for l1 in entries %}
-  <li class="topmenuitemmainitem">
-    <a class="tabs" href="{{l1.href}}" title="{{l1.title}}">{{ l1.text }}</a>
-    <ul id="submenu{{forloop.counter}}" class="topmenuitemsubmenu">
-    {% for l2 in l1.children %}
-      {% if l2.separator %}
-	  <li class="topmenuitemsubmenuseparator">&nbsp;</li>
-	  {% else %}
-      <li class="topmenuitemsubmenu"><a href="{{l2.href}}" title="{{l2.title}}">{{ l2.text }}</a></li>
-	  {% endif %}
-    {% endfor %}
-    </ul>
-  </li>
-{% endfor %}
-</ul>
-<div id="topmenunooverlap"></div><div id="topmenunooverlapbis"></div>
new file mode 100644
--- /dev/null
+++ b/templates/svmain/svtopmenu.html
@@ -0,0 +1,17 @@
+<ul class="topmenu" id="topmenu">
+{% for l1 in entries %}
+  <li class="topmenuitemmainitem">
+    <a class="tabs" href="{{l1.href}}" title="{{l1.title}}">{{ l1.text }}</a>
+    <ul id="submenu{{forloop.counter}}" class="topmenuitemsubmenu">
+    {% for l2 in l1.children %}
+      {% if l2.separator %}
+	  <li class="topmenuitemsubmenuseparator">&nbsp;</li>
+	  {% else %}
+      <li class="topmenuitemsubmenu"><a href="{{l2.href}}" title="{{l2.title}}">{{ l2.text }}</a></li>
+	  {% endif %}
+    {% endfor %}
+    </ul>
+  </li>
+{% endfor %}
+</ul>
+<div id="topmenunooverlap"></div><div id="topmenunooverlapbis"></div>
--- a/templates/title.html
+++ b/templates/title.html
@@ -1,3 +1,9 @@
 {% load i18n %}
 
 {% block title %}{% if title %}{{ title }}{% else %}{% trans 'Welcome' %}{% endif %}{% endblock %}
+
+{% comment %}
+The title can be defined in either the 'title' context variable, or by
+overriding the 'title' block (useful when relying on 3rd-party views
+that we cannot add context variables to).
+{% endcomment %}