changeset 486:b6149c732926

contenttype filtering added to global index page
author Akash Sinha <akash2607@gmail.com>
date Wed, 13 Jul 2011 04:57:51 +0530
parents 3a3aea61aa1b
children bdf613f0a062
files MoinMoin/apps/frontend/views.py MoinMoin/items/__init__.py MoinMoin/items/_tests/test_Item.py MoinMoin/templates/global_index.html MoinMoin/themes/modernized/static/css/common.css
diffstat 5 files changed, 88 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/apps/frontend/views.py	Sat Jul 09 00:34:12 2011 +0530
+++ b/MoinMoin/apps/frontend/views.py	Wed Jul 13 04:57:51 2011 +0530
@@ -490,22 +490,27 @@
                           )
 
 
-@frontend.route('/+index')
+@frontend.route('/+index', methods=['GET', 'POST'])
 def global_index():
     item = Item.create('') # XXX hack: item_name='' gives toplevel index
-    startswith = request.values.get('startswith', None)
-    index = item.flat_index(startswith)
-    if startswith:
-        initials = item.name_initial(item.flat_index())
-        # if startswith was set, we would get the filtered index above
-        # so inorder to get initial of all elements we need all index, not filtered one
-    else:
-        initials = item.name_initial(index)
+
+    passed_fields = request.values.to_dict()
+    startswith = passed_fields.pop("startswith", None)
+    selected_groups = passed_fields.keys()
+    index = item.flat_index(startswith, selected_groups)
+
+    nonexistent_item = NonExistent(item)
+    contenttype_groups = nonexistent_item.contenttype_groups
+    contenttype_groups = [(gname, ["%s" % ctlabel for ctname, ctlabel in contenttypes]) for gname, contenttypes in contenttype_groups]
+    if not selected_groups:
+        selected_groups = [gname for gname, ctlabels in contenttype_groups]
+
+    initials = item.name_initial(item.flat_index())
     initials = [initial.upper() for initial in initials]
     initials = list(set(initials))
-    initials.sort()
+    initials = sorted(initials)
     detailed_index = item.get_detailed_index(index)
-    detailed_index.sort()
+    detailed_index = sorted(detailed_index)
 
     item_name = request.values.get('item_name', '') # actions menu puts it into qs
     return render_template('global_index.html',
@@ -513,6 +518,8 @@
                            index=detailed_index,
                            initials=initials,
                            startswith=startswith,
+                           selected_groups=selected_groups,
+                           contenttype_groups=contenttype_groups,
                           )
 
 
--- a/MoinMoin/items/__init__.py	Sat Jul 09 00:34:12 2011 +0530
+++ b/MoinMoin/items/__init__.py	Wed Jul 13 04:57:51 2011 +0530
@@ -19,6 +19,7 @@
 import tarfile
 import zipfile
 import tempfile
+import itertools
 from StringIO import StringIO
 from array import array
 
@@ -575,17 +576,36 @@
                  for item in item_iterator]
         return sorted(items)
 
-    def flat_index(self, startswith=None):
+    def flat_index(self, startswith=None, selected_groups=None):
+        """
+        creates an top level index of sub items of this item
+        if startswith is set, filtering is done on the basis of starting letter of item name
+        if selected_groups is set, items whose contentype belonging to the selected contenttype_groups, are filtered.
+        """
         index = self.get_index()
+        nonexistent_item = NonExistent(self)
+        if not selected_groups:
+            selected_groups = [gname for (gname, contenttypes) in nonexistent_item.contenttype_groups]
+
+        ctypes = [[ctype for ctype, clabel in contenttypes]
+                  for gname, contenttypes in nonexistent_item.contenttype_groups
+                  if gname in selected_groups]
+
+        ctypes_chain = itertools.chain(*ctypes)
+        selected_contenttypes = list(ctypes_chain)
+
         if startswith:
             startswith = (u'%s' % startswith, u'%s' % startswith.swapcase())
             index = [(fullname, relname, contenttype)
                      for fullname, relname, contenttype in index
-                     if u'/' not in relname and relname.startswith(startswith)]
+                     if u'/' not in relname
+                     and relname.startswith(startswith)
+                     and contenttype in selected_contenttypes]
         else:
             index = [(fullname, relname, contenttype)
                      for fullname, relname, contenttype in index
-                     if u'/' not in relname]
+                     if u'/' not in relname
+                     and contenttype in selected_contenttypes]
 
         return index
 
--- a/MoinMoin/items/_tests/test_Item.py	Sat Jul 09 00:34:12 2011 +0530
+++ b/MoinMoin/items/_tests/test_Item.py	Wed Jul 13 04:57:51 2011 +0530
@@ -85,7 +85,8 @@
         for name in ['', '/ab', '/cd/ef', '/gh', '/ij', '/ij/kl', ]:
             item = Item.create(basename + name)
             item._save({CONTENTTYPE: 'text/plain;charset=utf-8'}, "foo")
-
+        item = Item.create(basename + '/mn')
+        item._save({CONTENTTYPE: 'image/jpeg'}, "JPG")
         # check index
         baseitem = Item.create(basename)
         index = baseitem.get_index()
@@ -94,16 +95,26 @@
                          (u'Foo/gh', u'gh', 'text/plain;charset=utf-8'),
                          (u'Foo/ij', u'ij', 'text/plain;charset=utf-8'),
                          (u'Foo/ij/kl', u'ij/kl', 'text/plain;charset=utf-8'),
+                         (u'Foo/mn', u'mn', 'image/jpeg'),
                         ]
         flat_index = baseitem.flat_index()
         assert flat_index == [(u'Foo/ab', u'ab', 'text/plain;charset=utf-8'),
                               (u'Foo/gh', u'gh', 'text/plain;charset=utf-8'),
                               (u'Foo/ij', u'ij', 'text/plain;charset=utf-8'),
+                              (u'Foo/mn', u'mn', 'image/jpeg'),
                              ]
+        # check index when startswith param is passed
+        flat_index = baseitem.flat_index(startswith=u'a')
+        assert flat_index == [(u'Foo/ab', u'ab', 'text/plain;charset=utf-8')]
+        # check index when contenttype_groups is passed
+        ctgroups = ["image items"]
+        flat_index = baseitem.flat_index(selected_groups=ctgroups)
+        assert flat_index == [(u'Foo/mn', u'mn', 'image/jpeg')]
         detailed_index = baseitem.get_detailed_index(baseitem.flat_index())
         assert detailed_index == [(u'Foo/ab', u'ab', 'text/plain;charset=utf-8', False),
                                   (u'Foo/gh', u'gh', 'text/plain;charset=utf-8', False),
                                   (u'Foo/ij', u'ij', 'text/plain;charset=utf-8', True),
+                                  (u'Foo/mn', u'mn', 'image/jpeg', False),
                                  ]
 
 
--- a/MoinMoin/templates/global_index.html	Sat Jul 09 00:34:12 2011 +0530
+++ b/MoinMoin/templates/global_index.html	Wed Jul 13 04:57:51 2011 +0530
@@ -1,7 +1,31 @@
 {% extends theme("layout.html") %}
 
 {% block item %}
+    <div class="moin-select-contenttypes">
+        <div class="moin-contenttypes-wrapper">
+            <div>Filter by content type </div>
+            <form action="" method="post">
+                <ul>
+                    {% for gname, ctlabels in contenttype_groups %}
+                    <li>
+                        {% if gname in selected_groups %}
+                            <input type="checkbox" name="{{ gname }}" checked="true">
+                        {% else %}
+                            <input type="checkbox" name="{{ gname }}">
+                        {% endif %}
+                        <label for="{{ gname }}">{{ gname|replace("items", "") }}</label>
+                        <span class="contenttype-labels">{{ ctlabels|join(", ") }}</span>
+                    </li>
+                    {% endfor %}
+                    <li>
+                        <input type="submit" value="{{ _("Filter") }}">
+                    </li>
+                </ul>
+            </form>
+        </div>
+    </div>
     <h1>{{ _("Global Index") }}</h1>
+    <div class='moin-clr'></div>
     {% if index %}
     <div id="moin-letters">
         {% if not startswith %}
--- a/MoinMoin/themes/modernized/static/css/common.css	Sat Jul 09 00:34:12 2011 +0530
+++ b/MoinMoin/themes/modernized/static/css/common.css	Wed Jul 13 04:57:51 2011 +0530
@@ -249,6 +249,17 @@
 #moin-item-index { width: 100%; margin-left: 0.5em; }
 #moin-global-index div,
 #moin-item-index div { float: left; width: 15em; }
+.moin-select-contenttypes { float: right; position: relative; width: 14em; }
+.moin-select-contenttypes .moin-contenttypes-wrapper { position: absolute; top: 0; left: 0; color: #342D7E; background: #FFFFFF; border: 1px solid #342D7E; width: 14em; }
+.moin-contenttypes-wrapper div { cursor: pointer; margin: 0.1em; padding: 0.2em 1.3em 0.2em 0.2em; background: transparent url("../img/moin-moveup.png") no-repeat center right; } 
+.moin-contenttypes-wrapper ul { display: none; margin: 0.3em 0; border-top: 1px solid #E5E5E5; } 
+.moin-contenttypes-wrapper ul li { list-style-type: none; padding: 0.5em 0.2em; width: 13.6em; }
+.moin-contenttypes-wrapper ul li label { margin-left: 0.5em; }
+.moin-contenttypes-wrapper ul li .contenttype-labels { font-size: 0.7em; color: #6E6A6B; display: none; }
+.moin-contenttypes-wrapper ul li:hover { background: #E5E5E5; }
+.moin-contenttypes-wrapper ul li:hover .contenttype-labels{ display: block; }
+.moin-contenttypes-wrapper:hover ul { display: block; }
+.moin-contenttypes-wrapper:hover div { background-image: url("../img/moin-movedown.png"); } 
 .moin-more-index:before { content: url("../img/moin-expand.png"); }
 .moin-index-path { margin-left: 0.5em; }
 .moin-index-path:before { content: url("../img/moin-parent.png"); margin: 0 0.3em; }