Index: WAeUP_SRP/trunk/profiles/default/layouts.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts.xml	(revision 915)
+++ WAeUP_SRP/trunk/profiles/default/layouts.xml	(revision 916)
@@ -10,4 +10,5 @@
  <object name="faculty" meta_type="CPS Layout"/>
  <object name="members" meta_type="CPS Layout"/>
+ <object name="members_search" meta_type="CPS Layout"/>
  <object name="student" meta_type="CPS Layout"/>
  <object name="scratch_card_batch" meta_type="CPS Layout"/>
Index: WAeUP_SRP/trunk/profiles/default/layouts/members.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts/members.xml	(revision 915)
+++ WAeUP_SRP/trunk/profiles/default/layouts/members.xml	(revision 916)
@@ -4,5 +4,5 @@
  <property name="layout_edit_method"></property>
  <property name="layout_view_method"></property>
- <property name="style_prefix">layout_dir_</property>
+ <property name="style_prefix">layout_waeup_dir_</property>
  <property name="flexible_widgets"/>
  <property name="validate_values_expr"></property>
Index: WAeUP_SRP/trunk/profiles/default/layouts/members_search.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts/members_search.xml	(revision 916)
+++ WAeUP_SRP/trunk/profiles/default/layouts/members_search.xml	(revision 916)
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<object name="members_search" meta_type="CPS Layout">
+ <property name="layout_create_method"></property>
+ <property name="layout_edit_method"></property>
+ <property name="layout_view_method"></property>
+ <property name="style_prefix">layout_waeup_dir_</property>
+ <property name="flexible_widgets"/>
+ <property name="validate_values_expr"></property>
+ <widget name="email" meta_type="String Widget">
+  <property name="fields">
+   <element value="email"/>
+  </property>
+  <property name="label">label_email</property>
+  <property name="label_edit">label_email</property>
+  <property name="description">Member email</property>
+  <property name="is_i18n">True</property>
+ </widget>
+ <widget name="givenName" meta_type="String Widget">
+  <property name="fields">
+   <element value="givenName"/>
+  </property>
+  <property name="label">label_first_name</property>
+  <property name="label_edit">label_first_name</property>
+  <property name="description">Member first name</property>
+  <property name="is_i18n">True</property>
+ </widget>
+ <widget name="id" meta_type="String Widget">
+  <property name="fields">
+   <element value="id"/>
+  </property>
+  <property name="label">label_user_name</property>
+  <property name="label_edit">label_user_name</property>
+  <property name="description">Member login</property>
+  <property name="is_i18n">True</property>
+ </widget>
+ <widget name="sn" meta_type="String Widget">
+  <property name="fields">
+   <element value="sn"/>
+  </property>
+  <property name="label">label_last_name</property>
+  <property name="label_edit">label_last_name</property>
+  <property name="description">Member last name</property>
+  <property name="is_i18n">True</property>
+ </widget>
+ <table>
+  <row>
+   <cell name="id" ncols="2"/>
+  </row>
+  <row>
+   <cell name="givenName"/>
+   <cell name="sn"/>
+  </row>
+  <row>
+   <cell name="email" ncols="2"/>
+  </row>
+ </table>
+</object>
Index: WAeUP_SRP/trunk/profiles/default/skins.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/skins.xml	(revision 915)
+++ WAeUP_SRP/trunk/profiles/default/skins.xml	(revision 916)
@@ -7,4 +7,6 @@
  <object name="waeup_default" meta_type="Filesystem Directory View"
     directory="WAeUP_SRP/skins/waeup_default"/>
+ <object name="waeup_directory" meta_type="Filesystem Directory View"
+    directory="WAeUP_SRP/skins/waeup_directory"/>
  <object name="waeup_academics" meta_type="Filesystem Directory View"
     directory="WAeUP_SRP/skins/waeup_academics"/>
@@ -18,4 +20,5 @@
   <layer name="waeup_custom" insert-after="custom"/>
   <layer name="waeup_default" insert-after="waeup_custom"/>
+  <layer name="waeup_directory" insert-after="waeup_custom"/>
   <layer name="waeup_pins" insert-after="waeup_custom"/>
   <layer name="waeup_student" insert-after="waeup_custom"/>
@@ -26,4 +29,5 @@
   <layer name="waeup_custom" insert-after="custom"/>
   <layer name="waeup_default" insert-after="waeup_custom"/>
+  <layer name="waeup_directory" insert-after="waeup_custom"/>
   <layer name="waeup_pins" insert-after="waeup_custom"/>
   <layer name="waeup_student" insert-after="waeup_custom"/>
Index: WAeUP_SRP/trunk/profiles/default/skins/waeup_directory.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/skins/waeup_directory.xml	(revision 916)
+++ WAeUP_SRP/trunk/profiles/default/skins/waeup_directory.xml	(revision 916)
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<object name="waeup_directory" meta_type="Folder">
+ <property name="title"></property>
+</object>
Index: WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_create.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_create.pt	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_create.pt	(revision 916)
@@ -0,0 +1,2 @@
+<tal:block define="global creation python:1" />
+<metal:block use-macro="here/layout_waeup_dir_edit/macros/edit" />
Index: WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_edit.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_edit.pt	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_edit.pt	(revision 916)
@@ -0,0 +1,83 @@
+<metal:block define-macro="edit">
+<tal:block define="
+  layout options/layout;
+  ds options/datastructure;
+  creation creation|nothing;
+  formaction python: test(creation, 'cpsdirectory_entry_create_form',
+                                    'cpsdirectory_entry_edit_form');
+  ">
+<div class="group">
+<form action="." method="post" name="form" enctype="multipart/form-data">
+<input type="hidden" name="dirname" value="."
+  tal:attributes="value request/dirname" />
+<input type="hidden" name="id" value="."
+  tal:attributes="value request/id|nothing" />
+<table cellpadding="0" cellspacing="2" summary="form layout"
+  tal:define="global has_edits nothing">
+  <tr tal:repeat="row layout/rows">
+    <tal:block repeat="cell row">
+    <tal:block define="widget cell/widget;
+                       wid widget/getWidgetId;
+                       err python: ds.getError(wid);
+                       is_edit python: cell['widget_mode'] == 'edit';
+                       is_required python: is_edit and widget.is_required;
+                       global has_edits python: has_edits or is_edit;
+                       tooltip_id python:wid + '_help';
+                       ">
+      <td align="right"  valign="top">
+        <div class="label" tal:condition="widget/label_edit"
+          tal:attributes="class python:is_required and 'label required'
+                                                    or 'label'">
+          <span i18n:translate="" tal:condition="widget/is_i18n"
+            tal:content="widget/label_edit">label</span>
+          <span tal:condition="not:widget/is_i18n"
+            tal:content="widget/label_edit">label</span>
+          <button type="button" class="tooltipControl"
+            tal:condition="widget/help"
+            tal:attributes="onclick python:'toggleElementVisibility(\'%s\')' % tooltip_id;"> ? </button>
+        </div>
+      </td>
+      <td valign="top" colspan="1"
+        tal:attributes="colspan python:cell['ncols']*2-1">
+        <div tal:attributes="class python:err and 'error' or nothing">
+          <div tal:attributes="class widget/css_class|nothing">
+            <tal:block replace="structure cell/widget_rendered" />
+          </div>
+          <div tal:condition="err">
+            <em style="color:red" tal:content="err"
+              i18n:translate="">Error</em>
+          </div>
+        </div>
+        <div class="tooltipArea" style="visibility: hidden;"
+          tal:condition="widget/help"
+          tal:attributes="id tooltip_id;
+            onclick python:'showElement(false, \'%s\')' % tooltip_id;">
+          <span i18n:translate="" tal:condition="widget/is_i18n"
+            tal:content="widget/help">i18_key-help_for_this_field</span>
+          <span tal:condition="not:widget/is_i18n"
+            tal:content="widget/help">This is the help for this field</span>
+        </div>
+      </td>
+    </tal:block>
+    </tal:block>
+  </tr>
+  <tr>
+    <td></td>
+    <td>
+    <tal:block condition="has_edits">
+    <input type="submit" class="standalone"
+      name="cpsdirectory_entry_edit_form:method"
+      value="button_change" i18n:attributes="value"
+      tal:condition="not:creation" />
+    <input type="submit" class="standalone"
+      name="cpsdirectory_entry_create_form:method"
+      value="button_create" i18n:attributes="value"
+      tal:condition="creation" />
+    </tal:block>
+    </td>
+  </tr>
+</table>
+</form>
+</div>
+</tal:block>
+</metal:block>
Index: WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_search.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_search.pt	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_search.pt	(revision 916)
@@ -0,0 +1,51 @@
+<tal:block define="
+  layout options/layout;
+  ds options/datastructure;
+  formaction request/formaction|python: 'search_members_form';
+  ">
+<div class="group">
+<form action="." method="post" name="form" enctype="multipart/form-data"
+  tal:attributes="action formaction">
+<input type="hidden" name="dirname" value="."
+  tal:attributes="value request/dirname|string:members" />
+<table cellpadding="0" cellspacing="2" summary="form layout">
+  <tr tal:repeat="row layout/rows">
+    <tal:block repeat="cell row">
+    <tal:block define="widget cell/widget;
+                       wid widget/getWidgetId;
+                       err python: ds.getError(wid);
+                       is_required python: cell['widget_mode'] == 'edit' and widget.is_required;
+                       ">
+      <td align="right"  valign="top">
+        <div class="label" tal:condition="widget/label_edit">
+          <span i18n:translate="" tal:condition="widget/is_i18n"
+            tal:content="widget/label_edit">label</span
+          ><span tal:condition="not:widget/is_i18n"
+            tal:content="widget/label_edit">label</span
+          >&nbsp;:
+        </div>
+      </td>
+      <td valign="top" colspan="1"
+        tal:attributes="colspan python:cell['ncols']*2-1">
+        <div tal:attributes="class python:err and 'error' or nothing">
+          <div tal:attributes="class widget/css_class|nothing">
+            <tal:block replace="structure cell/widget_rendered" />
+          </div>
+          <div tal:condition="err">
+            <em style="color:red" tal:content="err"
+              i18n:translate="">Error</em>
+          </div>
+        </div>
+      </td>
+    </tal:block>
+    </tal:block>
+  </tr>
+  <tr><td></td>
+    <td><input type="submit" class="standalone"
+          name="cpsdirectory_search_button" value="button_search"
+          i18n:attributes="value" /></td>
+  </tr>
+</table>
+</form>
+</div>
+</tal:block>
Index: WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_view.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_view.pt	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/layout_waeup_dir_view.pt	(revision 916)
@@ -0,0 +1,31 @@
+<tal:block define="layout options/layout;
+                   dirname request/dirname;
+                   dir here/portal_directories/?dirname;
+                   id_field dir/id_field;
+                   ">
+<div class="group">
+  <table cellpadding="2" cellspacing="2" summary="layout">
+    <tr tal:repeat="row layout/rows">
+      <tal:block repeat="cell row">
+      <tal:block define="widget cell/widget">
+        <td align="right" valign="top">
+          <div class="dlabel">
+          <span i18n:translate="" tal:condition="widget/is_i18n"
+            tal:content="widget/label">label</span
+          ><span tal:condition="not:widget/is_i18n"
+            tal:content="widget/label">label</span
+          >&nbsp;:
+          </div>
+        </td>
+        <td valign="top" colspan="1"
+          tal:attributes="colspan python:cell['ncols']*2-1">
+          <div tal:attributes="class widget/css_class|nothing">
+            <tal:block replace="structure cell/widget_rendered" />
+          </div>
+        </td>
+      </tal:block>
+      </tal:block>
+    </tr>
+  </table>
+</div>
+</tal:block>
Index: WAeUP_SRP/trunk/skins/waeup_directory/search_members.py
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/search_members.py	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/search_members.py	(revision 916)
@@ -0,0 +1,96 @@
+## Script (Python) "search_members"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=dir, datastructure, **kw
+##title=
+##
+# $Id$
+
+from Products.CPSDirectory.BaseDirectory import SearchSizeLimitExceeded
+try:
+    from Products.AdvancedQuery import Eq, Between, Le,In
+    evalAdvancedQuery = context.portal_catalog.evalAdvancedQuery
+except:
+    evalAdvancedQuery = None
+
+datamodel = datastructure.getDataModel()
+
+mapping = {}
+for key, value in datamodel.items():
+    if value:
+        mapping[key] = value
+
+result_fields = context.getDirectoryResultFields(dir.getId(),
+                                                 dir.title_field)
+
+return_fields = []
+sort_by = None
+sort_direction = None
+process_fields = {}
+for field in result_fields:
+    return_fields.append(field['id'])
+    sorted = field.get('sort')
+    if sorted == 'asc':
+        sort_by = field['id']
+        sort_direction = 'asc'
+    elif sorted == 'desc':
+        sort_by = field['id']
+        sort_direction = 'desc'
+    if field.get('process'):
+        process_fields[field['id']] = field['process']
+
+# empty search will not return anything
+if not mapping:
+    return dir.search_members_results(results=[]), 'results'
+
+try:
+    results = dir.searchEntries(return_fields=return_fields, **mapping)
+except SearchSizeLimitExceeded, e:
+    rendered = dir.cpsdirectory_entry_search_errors(exception=e)
+    return rendered, 'results'
+
+for field, process_meth in process_fields.items():
+    meth = getattr(context, process_meth, None)
+    if not meth:
+        continue
+    for item in results:
+        value = item[1].get(field)
+        item[1][field] = meth(field, value)
+
+if sort_by:
+    items = [(str(item[1].get(sort_by, 'ZZZZ')).lower(), item) for item in results]
+    items.sort()
+    if sort_direction == 'desc':
+        items.reverse()
+    results = [item[1] for item in items]
+
+allres = []
+for item in results:
+    user_id = item[0]
+    data = item[1]
+    query = In('portal_type',('Faculty','Department')) &\
+            In('localUsersWithRoles',('user:%s' % user_id,))
+##    query = Eq('path', "%s/campus/academics" % context.portal_url.getPortalPath()) &\
+##            In('allowedRolesAndUsers',('user:%s' % user_id,))
+    res = evalAdvancedQuery(query)
+    facs = []
+    roles = []
+    for r in res:
+        p = r.getPath().split('/')
+        fac = p[4]
+        if len(p) == 5:
+            facs.append(fac)
+            roles.append(r)
+        elif len(p) > 5:
+            if fac not in facs:
+                roles.append(r)
+    item[1]['roles'] = roles
+context.REQUEST.set('facs',facs)
+rendered = dir.search_members_results(results=results)
+
+return rendered, 'results'
+
+
Index: WAeUP_SRP/trunk/skins/waeup_directory/search_members_form.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/search_members_form.pt	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/search_members_form.pt	(revision 916)
@@ -0,0 +1,42 @@
+<tal:block define="
+  global dirname request/dirname|string:members;
+  global dir here/portal_directories/?dirname;
+  global dirtitle dir/title_or_id;
+  "/>
+<metal:block use-macro="here/main_template/macros/master">
+  <metal:block fill-slot="style_slot">
+    <tal:block define="dummy
+      python:context.setDirectoryBreadCrumbs(request, dirname, dir, dirtitle)"/>
+    <tal:block define="global actions
+      python:context.getDirectoryActions(actions, dirname, dir, 'search')"/>
+
+    <link rel="Stylesheet" type="text/css" href=""
+      tal:attributes="href string:${base_url}document.css" />
+
+  </metal:block>
+
+  <metal:block fill-slot="header"/>
+
+  <metal:block fill-slot="main" tal:define="
+    validate python: request.has_key('cpsdirectory_search_button');
+    res python: dir.renderSearchDetailed(request=request, validate=validate,
+                                      callback='search_members');
+    global rendered_main python: res[0];
+    global ok python: res[1];
+    ds python: res[2];
+    global portal_status_message python: (validate and not ok and
+      'psm_content_error') or request.form.get('portal_status_message', '');">
+    <h1>
+      <span i18n:translate="" tal:content="dirtitle" />:
+      <span tal:condition="python: ok == 'results'"
+        i18n:translate="">cpsdir_label_results
+      </span>
+      <span tal:condition="python: ok != 'results'"
+         i18n:translate="cpsdir_label_search_entry">search an entry
+      </span>
+    </h1>
+
+    <div tal:replace="structure rendered_main">Rendered main...</div>
+  </metal:block>
+
+</metal:block>
Index: WAeUP_SRP/trunk/skins/waeup_directory/search_members_results.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_directory/search_members_results.pt	(revision 916)
+++ WAeUP_SRP/trunk/skins/waeup_directory/search_members_results.pt	(revision 916)
@@ -0,0 +1,110 @@
+<tal:block define="results options/results;
+  params python:here.getDisplayParams(nb_items=len(results));
+  columns python:1;
+  items_per_page params/items_per_page;
+  batches_all python:here.getBatchList(results, columns, items_per_page);
+  batch_list python:batches_all[0];
+  batch_info python:batches_all[1];
+  form request/form;
+  mq nocall:modules/ZTUtils/make_query;
+  portal_url here/portal_url;
+  dirname here/getId;
+  title_field here/title_field;
+  fields python:here.getDirectoryResultFields(dirname);
+  isAdmin python:here.portal_membership.getAuthenticatedMember().has_role(['Manager',]);
+  cpsmcat nocall:here/translation_service;
+  ">
+  <div style="padding-left: 1.5em">
+    <form action="cpsdirectory_entry_delete" method="post">
+      <table tal:condition="results" summary="search result list">
+        <tr>
+          <th tal:condition="isAdmin" i18n:translate="label_selection">
+            Selection
+          </th>
+          <tal:block repeat="field fields">
+            <th i18n:translate="" tal:content="field/title">id</th>
+          </tal:block>
+        <th>Roles In</th>
+        </tr>
+        <tal:block repeat="result python:batch_list[0]">
+          <tal:block define="id python:result[0];
+            data python:result[1];
+            even repeat/result/even;
+            ">
+            <tr tal:attributes="class python:test(even, 'even', 'odd')">
+              <tal:block repeat="field fields">
+                <tal:block tal:condition="isAdmin">
+                  <td tal:condition="not:repeat/field/index">
+                    <input type="checkbox" name="ids:list" tal:attributes="value id" />
+                  </td>
+                </tal:block>
+                <td>
+                  <a href="."
+                    tal:attributes="href string:${portal_url}/cpsdirectory_entry_view?dirname=${dirname}&id=${id}"
+                    ><strong tal:content="structure python:data.get(field['id'])">john</strong></a>
+                </td>
+              </tal:block>
+          <td tal:define="roles python:data['roles']">
+            <span tal:repeat="role roles"> 
+              <a href="" tal:attributes="href string:${role/getPath}/folder_localrole_form"
+                 tal:content="role/getId"></a><br />
+            </span>
+          </td>
+        </tr>
+          </tal:block>
+        </tal:block>
+      </table>
+      <div tal:condition="not:results">
+        <span i18n:translate="label_no_results" />
+      </div>
+      <p>
+        <input type="hidden" name="dirname" tal:attributes="value dirname" />
+        <input type="hidden" name="ids:tokens:default" value="" />
+        <tal:block condition="python:isAdmin and results">
+          <input type="button" value="button_select_all" class="context"
+            i18n:attributes="value"
+            tal:attributes="onclick python:'toggleSelect(this, \'%s\', \'%s\')'
+            % (cpsmcat('button_select_all'), cpsmcat('button_deselect_all'))" />
+          <input type="submit" class="destructive" value="button_delete"
+            i18n:attributes="value"
+            tal:attributes="onclick python:'return window.confirm(\'%s\')'
+            % cpsmcat('description_confirm_delete')" />
+        </tal:block>
+        <input type="button" class="context" value="button_back"
+          onclick="javascript:history.back()" i18n:attributes="value" />
+      </p>
+    </form>
+    <tal:block condition="python:batch_info and batch_info['nb_pages'] > 1">
+      <br />
+      <table width="100%" cellspacing="0" cellpadding="0"
+        summary="navigation layout">
+        <tr class="even">
+          <td align="center" width="100%">
+            <span i18n:translate="label_page">Pages</span>:
+            <a tal:define="previous batch_info/previous"
+               tal:condition="python:previous is not None"
+               tal:attributes="href python:'%s?%s'%(request['URL'],
+                                              mq(request.form, b_start=previous))"
+               i18n:translate="batch_previous">Previous</a>
+            <tal:block repeat="page batch_info/pages">
+              <a tal:condition="python:page != batch_info['start'] - 1"
+                tal:attributes="href python:'%s?%s'%(request['URL'],
+                mq(request.form, b_start=page))"
+                tal:content="repeat/page/number">1</a>
+              <span tal:condition="python:page == batch_info['start'] - 1"
+                tal:content="string:[${repeat/page/number}]" />
+            </tal:block>
+            <a tal:define="next batch_info/next"
+               tal:condition="python:next is not None"
+               tal:attributes="href python:'%s?%s'%(request['URL'],
+                                                  mq(request.form, b_start=next))"
+               i18n:translate="batch_next">Next</a>
+          </td>
+        </tr>
+        <tr>
+          <td>&nbsp;</td>
+        </tr>
+      </table>
+    </tal:block>
+  </div>
+</tal:block>
