Commits

Thomas Waldmann committed fbe32ae Merge

merged

Comments (0)

Files changed (5)

MoinMoin/apps/frontend/views.py

 from flaskext.babel import format_date
 from flaskext.themes import get_themes_list
 
-from flatland import Form
+from flatland import Form, Enum
 from flatland.validation import Validator
 
 from jinja2 import Markup
 from MoinMoin.i18n import _, L_, N_
 from MoinMoin.themes import render_template, get_editor_info, contenttype_to_class
 from MoinMoin.apps.frontend import frontend
-from MoinMoin.forms import OptionalText, RequiredText, URL, YourOpenID, YourEmail, RequiredPassword, Checkbox, InlineCheckbox, Select, Tags, Natural, Submit, Hidden
+from MoinMoin.forms import OptionalText, RequiredText, URL, YourOpenID, YourEmail, RequiredPassword, Checkbox, InlineCheckbox, Select, Tags, Natural, Submit, Hidden, MultiSelect
 from MoinMoin.items import BaseChangeForm, Item, NonExistent
 from MoinMoin import config, user, util
 from MoinMoin.config import CONTENTTYPE_GROUPS
         abort(403)
 
 
-class ContenttypeFilterForm(Form):
-    markup_text_items = InlineCheckbox.using(label=L_('markup text'))
-    other_text_items = InlineCheckbox.using(label=L_('other text'))
-    image_items = InlineCheckbox.using(label=L_('image'))
-    audio_items = InlineCheckbox.using(label=L_('audio'))
-    video_items = InlineCheckbox.using(label=L_('video'))
-    other_items = InlineCheckbox.using(label=L_('other'))
-    unknown_items = InlineCheckbox.using(label=L_('unknown'))
+contenttype_groups = []
+contenttype_group_descriptions = {}
+for gname, contenttypes in CONTENTTYPE_GROUPS:
+    contenttype_groups.append(gname)
+    contenttype_group_descriptions[gname] = ', '.join([ctlabel for ctname, ctlabel in contenttypes])
+contenttype_groups.append('unknown items')
 
-for gname, contenttypes in CONTENTTYPE_GROUPS:
-    filter_ = ContenttypeFilterForm.field_schema_mapping.get(gname.replace(' ', '_'))
-    if filter_:
-        filter_.properties['helper'] = ", ".join([ctlabel for ctname, ctlabel in contenttypes])
+ContenttypeGroup = MultiSelect.of(Enum.using(valid_values=contenttype_groups).with_properties(descriptions=contenttype_group_descriptions)).using(optional=True)
 
 class IndexForm(Form):
-    contenttype = ContenttypeFilterForm
+    contenttype = ContenttypeGroup
     submit = Submit.using(default=L_('Filter'))
 
 @frontend.route('/+index/', defaults=dict(item_name=''), methods=['GET', 'POST'])
     except AccessDenied:
         abort(403)
 
-    if request.method == 'GET':
-        form = IndexForm.from_defaults()
-        selected_groups = None
-    elif request.method == "POST":
-        form = IndexForm.from_flat(request.form)
-        selected_groups = [k.replace("_", " ") for k, v in form['contenttype'].iteritems() if v]
+    # request.args is a MultiDict instance, which degenerates into a normal
+    # single-valued dict on most occasions (making the first value the *only*
+    # value for a specific key) unless explicitly told to expose multiple
+    # values, eg. calling items with multi=True. See Werkzeug documentation for
+    # more.
+    form = IndexForm.from_flat(request.args.items(multi=True))
+    form['submit'].set_default() # XXX from_flat() kills all values
+    if not form['contenttype']:
+        form['contenttype'].set(contenttype_groups)
 
+    selected_groups = form['contenttype'].value
     startswith = request.values.get("startswith")
 
     initials = item.name_initial(item.get_subitem_revs())

MoinMoin/constants/forms.py

 WIDGET_HIDDEN = u'hidden'
 
 WIDGET_SELECT = u'select'
+WIDGET_MULTI_SELECT = u'multi_select'
 
 WIDGET_READONLY_STRING_LIST = u'readonly_string_list'
 WIDGET_READONLY_ITEM_LINK_LIST = u'readonly_item_link_list'
 import re, datetime
 import json
 
-from flatland import Element, Form, String, Integer, Boolean, Enum, Dict, JoinedString, List, DateTime as _DateTime
+from flatland import Element, Form, String, Integer, Boolean, Enum, Dict, JoinedString, List, Array, DateTime as _DateTime
 from flatland.util import class_cloner, Unspecified
 from flatland.validation import Validator, Present, IsEmail, ValueBetween, URLValidator, Converted, ValueAtLeast
 from flatland.exc import AdaptationError
     def set(self, query, **query_args):
         revs = flaskg.storage.search(query, **query_args)
         super(BackReference, self).set([rev.meta[NAME] for rev in revs])
+
+
+MultiSelect = Array.with_properties(widget=WIDGET_MULTI_SELECT)

MoinMoin/templates/forms.html

       'submit': raw_input,
       'hidden': raw_input,
       'select': select,
+      'multi_select': multi_select,
       'readonly_string_list': readonly_string_list,
       'readonly_item_link_list': readonly_item_link_list,
   }[field.properties.widget] or stub -%}
   </dd>
 {% endmacro %}
 
+{% macro multi_select(field) %}
+  {% set valid_values = field.member_schema.valid_values %}
+  {% set labels = field.member_schema.properties.get('labels', {}) %}
+  {% set descriptions = field.member_schema.properties.get('helpers', {}) %}
+  {% for value in valid_values %}
+    <li>
+      {{ raw_input(field, 'checkbox', value=value) }}
+      {{ _valued_label(field, value, labels.get(value, value), class='moin-inline-label') }}
+      {% if descriptions[value] is defined %}
+        <span class="helper-text">
+          {{ descriptions[value] }}
+        </span>
+      {% endif %}
+    </li>
+  {% endfor %}
+  {{ render_errors(field) }}
+{% endmacro %}
+
 {% macro readonly_string_list(field) %}
   <dt>
     {{ gen.label(field) }}

MoinMoin/templates/index.html

             <div class="moin-contenttypes-wrapper">
                 <div class="ct-hide">{{ _("Filter by content type") }}</div>
                 {% set unknown_items_label = _("items having unknown mime types") %}
-                {{ gen.form.open(form, method="post", action=url_for('frontend.index', item_name=item_name)) }}
+                {{ gen.form.open(form, method="get", action=url_for('frontend.index', item_name=item_name)) }}
                 <ul>
                     <li>
                         <a href="#" class="filter-toggle">&raquo; {{ _("Toggle") }}</a>
                         <a href="#" class="filter-more">&raquo; {{ _("More") }}</a>
                     </li>
-                    {% for e in [
-                        'markup_text_items',
-                        'other_text_items',
-                        'image_items',
-                        'audio_items',
-                        'video_items',
-                        'other_items',
-                        'unknown_items',
-                        ] %}
-                        <li>{{ forms.render(form['contenttype'][e]) }}</li>
-                    {% endfor %}
+                    {{ forms.render(form['contenttype']) }}
                 </ul>
                 {{ forms.render(form['submit']) }}
                 {{ gen.form.close() }}