From 5e1d8ed3f55be6a1498f028bebc3e494761046c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Thu, 6 Apr 2023 08:55:36 +0200
Subject: [PATCH] stack/erp5: backport a fix for portal_skins Find tab in ZMI

---
 .../portal_skins_ZMI_find.patch               | 767 ++++++++++++++++++
 stack/erp5/buildout.cfg                       |   4 +-
 2 files changed, 770 insertions(+), 1 deletion(-)
 create mode 100644 component/egg-patch/Products.CMFCore/portal_skins_ZMI_find.patch

diff --git a/component/egg-patch/Products.CMFCore/portal_skins_ZMI_find.patch b/component/egg-patch/Products.CMFCore/portal_skins_ZMI_find.patch
new file mode 100644
index 0000000000..15c50c0f20
--- /dev/null
+++ b/component/egg-patch/Products.CMFCore/portal_skins_ZMI_find.patch
@@ -0,0 +1,767 @@
+From c2b800e61e10d401fcbdc57dd150270da5b550e9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <perrinjerome@gmail.com>
+Date: Thu, 16 Mar 2023 14:44:52 +0900
+Subject: [PATCH] SkinsTool: fix Find form with Zope4 ZMI (#127)
+
+SkinsTool: fix Find form with Zope4 ZMI
+
+SkinsTool has a custom "Find" tab that got broken when FindSupport API changed for Zope4, this repairs all this.
+
+Co-authored-by: Maurits van Rees <maurits@vanrees.org>
+---
+ src/Products/CMFCore/SkinsTool.py         |   7 +-
+ src/Products/CMFCore/dtml/findForm.dtml   | 394 +++++++++++++++-------
+ src/Products/CMFCore/dtml/findResult.dtml | 313 -----------------
+ 4 files changed, 280 insertions(+), 437 deletions(-)
+ delete mode 100644 src/Products/CMFCore/dtml/findResult.dtml
+
+diff --git a/src/Products/CMFCore/SkinsTool.py b/src/Products/CMFCore/SkinsTool.py
+index c7df7000..acfd6c8f 100644
+--- a/src/Products/CMFCore/SkinsTool.py
++++ b/src/Products/CMFCore/SkinsTool.py
+@@ -100,13 +100,8 @@ def _getSelections(self):
+                               'manage_propertiesForm')
+     manage_propertiesForm = DTMLFile('dtml/skinProps', globals())
+ 
+-    # the following two methods override those in FindSupport, to
++    # the following method override the one in FindSupport, to
+     # support marking of objects used in specific skins
+-    security.declareProtected(ManagePortal,  # NOQA: flake8: D001
+-                              'manage_findResult')
+-    manage_findResult = DTMLFile('findResult', _dtmldir,
+-                                 management_view='Find')
+-
+     security.declareProtected(ManagePortal,  # NOQA: flake8: D001
+                               'manage_findForm')
+     manage_findForm = DTMLFile('findForm', _dtmldir,
+diff --git a/src/Products/CMFCore/dtml/findForm.dtml b/src/Products/CMFCore/dtml/findForm.dtml
+index 0fcb7102..7d935e16 100644
+--- a/src/Products/CMFCore/dtml/findForm.dtml
++++ b/src/Products/CMFCore/dtml/findForm.dtml
+@@ -1,131 +1,289 @@
+ <dtml-var manage_page_header>
++
+ <dtml-var manage_tabs>
+ 
+ <main class="container-fluid">
+ 
+-<p class="form-help">
+-Find allows you to locate Zope objects based on different
+-criteria. For more find choices choose the <EM>Advanced</EM>
+-find option.
+-</p>
+-
+-<FORM ACTION="manage_findResult" METHOD="GET">
+-<INPUT TYPE = "hidden" NAME="searchtype" VALUE="simple">
+-<TABLE class="action">
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  Find objects of type:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_metatypes:list" SIZE="8" MULTIPLE>
+-  <OPTION VALUE="all" SELECTED> All types
+-<dtml-let sorted_meta_types="[]">
+-  <dtml-in all_meta_types mapping>
+-  <dtml-call "sorted_meta_types.append(name)">
+-  </dtml-in>
+-  <dtml-call "sorted_meta_types.sort()">
+-  <dtml-in sorted_meta_types>
+-  <OPTION VALUE="&dtml-sequence-item;">&dtml-sequence-item;
+-  </dtml-in>
+-</dtml-let>
+-  </SELECT>
+-  </div>
+-  </TD>
+-</TR>
++<!-- BO findResults.dtml -->
++<dtml-in "('obj_ids', 'obj_searchterm', 'obj_expr', 'obj_mtime', 'obj_mspec', 'obj_permission', 'obj_roles', 'search_sub','searchtype')"
++	><dtml-else "_.hasattr(REQUEST, _['sequence-item'])"
++	><dtml-call "REQUEST.set(_['sequence-item'], None)"
++	></dtml-else
++></dtml-in>
++<dtml-call "REQUEST.set('obj_metatypes',
++                        [x for x in (REQUEST.get('obj_metatypes', []) or [])])">
+ 
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  with ids:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <INPUT TYPE="TEXT" NAME="obj_ids:tokens" SIZE="30">
+-  </TD>
+-</TR>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  containing:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <INPUT TYPE="TEXT" NAME="obj_searchterm" SIZE="30">
+-  </TD>
+-</TR>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  modified:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_mspec">
+-  <OPTION VALUE="&lt;"> before
+-  <OPTION VALUE="&gt;"> after
+-  </SELECT> 
+-  </div>
+-  <INPUT TYPE="TEXT" NAME="obj_mtime" SIZE="22">
+-  </TD>
+-</TR>
++<dtml-if btn_submit>
++<dtml-with "_.namespace(
++	results=ZopeFind(this(),
++		obj_ids=obj_ids,
++		obj_metatypes=obj_metatypes,
++		obj_searchterm=obj_searchterm,
++		obj_expr=obj_expr,
++		obj_mtime=obj_mtime,
++		obj_mspec=obj_mspec,
++		obj_permission=obj_permission,
++		obj_roles=obj_roles,
++		search_sub=search_sub,
++		REQUEST=REQUEST)
++	)">
++<form action="manage_compareResults">
++<dtml-unless batch_size><dtml-call "REQUEST.set('batch_size',20)"></dtml-unless>
+ 
++<dtml-if results>
++	<div class="alert alert-success">
++		Displaying items
++		<dtml-in name="results" size=batch_size start=query_start
++			><dtml-if sequence-start>&dtml-sequence-number;</dtml-if
++			><dtml-if sequence-end>-&dtml-sequence-number; of
++				<dtml-var "_.len(results)"
++			></dtml-if
++		></dtml-in>
++		items matching your query. You can <a href="#zmi-search-form">revise</a>
++		your search terms below.
++	</div>
++<dtml-else>
++	<div class="alert alert-danger">
++		No items were found matching your query. You can
++		<a href="#zmi-search-form">revise</a> your search terms below.
++	</div>
++</dtml-if>
+ 
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  mark the object used in skin:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_skinspec">
+-   <dtml-in getSkinSelections>
+-    <OPTION value="&dtml-sequence-item;"
+-            <dtml-if "_['sequence-item'] == getDefaultSkin()">selected</dtml-if>>
+-            <dtml-var sequence-item>
+-    </OPTION>
+-   </dtml-in>
+-  </SELECT>
+-  </div>
+-  </TD>
+-</TR>
+-
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-text">
+-  <INPUT TYPE="RADIO" NAME="search_sub:int" VALUE="0"> 
+-  Search only in this folder
+-  <BR>
+-  <INPUT TYPE="RADIO" NAME="search_sub:int" VALUE="1" CHECKED> 
+-  Search all subfolders
++<dtml-unless searchtype><dtml-call "REQUEST.set('searchtype', 'simple')"></dtml-unless>
++<dtml-unless skey><dtml-call "REQUEST.set('skey', 'id')"></dtml-unless>
++<dtml-unless rkey><dtml-call "REQUEST.set('rkey', '')"></dtml-unless>
++<dtml-if "rkey == 'reverse'"><dtml-call "REQUEST.set('rkey', skey)"></dtml-if>
++
++
++<dtml-if "_.len(results) > int(batch_size)">
++	<nav class="zmi-find-results nav row mb-2">
++	<div class="col-6">
++	<dtml-in name="results" previous size=batch_size start=query_start>
++		<a class="btn btn-primary float-left"
++			href="<dtml-var "REQUEST.URL" html_quote>&dtml-sequence-query;query_start=&dtml-previous-sequence-start-number;">
++			<i class="fa fa-caret-left"></i>&nbsp;&nbsp;Previous
++		</a>
++	</dtml-in>
++	</div>
++	<div class="col-6 text-right">
++	<dtml-in name="results" next size=batch_size start=query_start>
++		<a class="btn btn-primary"
++			href="<dtml-var "REQUEST.URL" html_quote>&dtml-sequence-query;query_start=&dtml-next-sequence-start-number;">
++			Next&nbsp;&nbsp;<i class="fa fa-caret-right"></i>
++		</a>
++	</dtml-in>
++	</div>
++	</nav>
++</dtml-if>
++
++
++<ul class="zmi-find-results list-group mb-5">
++<dtml-in results size="batch_size" start="query_start" sort_expr="skey"
++         reverse_expr="rkey">
++	<li class="list-group-item">
++  <div class="form-check">
++    <input class="form-check-input col-0" type="checkbox" value="&dtml.url_quote-sequence-key;" name="item_paths:list"/>
++    <a href="&dtml.url_quote-sequence-key;/manage_workspace"
++    class="col-2
++      <dtml-if "isFirstInSkin(_['sequence-key'], obj_skinspec)">font-weight-bold"</dtml-if>
++      ">
++            <i title="&dtml-meta_type;"
++               class="&dtml-zmi_icon;">&nbsp;</i>
++            &dtml-sequence-key; <dtml-if title>(&dtml-title;)</dtml-if>
++		</a>
+   </div>
+-  </TD>
+-</TR>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <INPUT class="form-element" TYPE="SUBMIT" NAME="btn_submit" VALUE="Find">  
+-  <span class="form-text">
+-  <a href="manage_findAdv">Advanced...<a>
+-  </span>
++	</li>
++</dtml-in>
++</ul>
++
++</dtml-with> <!-- /namespace -->
++  <div class="zmi-controls">
++    <input class="btn btn-primary" type="submit" name="btn_submit" value="Compare" />
+   </div>
+-  </TD>
+-</TR>
+-</TABLE>
+-</FORM>
++</form>
++</dtml-if> <!-- /button submit -->
++<!-- EO findResults.dtml -->
++
++<form id="zmi-search-form" action="manage_findForm" method="get" class="zmi-find">
++<table class="table table-borderless">
++<tr class="simple-search">
++	<td style="width:10rem">
++		<label for="type" class="form-label">Find objects of type:</label>
++	</td>
++	<td style="width:*">
++	<div class="form-element">
++		<select id="type" class="form-control" name="obj_metatypes:list" size="8" multiple="multiple">
++		<option value="all"
++			<dtml-if "not obj_metatypes">
++				selected="selected"
++			<dtml-else>
++				<dtml-var "('all' in obj_metatypes) and 'selected=\042selected\042' or ''">
++			</dtml-if>
++		>All types</option>
++		<dtml-let sorted_meta_types="[]"
++			><dtml-in all_meta_types mapping
++				><dtml-call "sorted_meta_types.append(name)"
++			></dtml-in><dtml-call "sorted_meta_types.sort()"
++			><dtml-in sorted_meta_types
++				><option value="&dtml-sequence-item;"
++				<dtml-if "not obj_metatypes">
++				<dtml-else>
++					<dtml-var "(_['sequence-item'] in obj_metatypes) and 'selected=\042selected\042' or ''">
++				</dtml-if>
++				>&dtml-sequence-item;</option>
++			</dtml-in
++		></dtml-let>
++		</select>
++	</div>
++	</td>
++</tr>
++
++<tr class="simple-search">
++	<td>
++	<label for="ids" class="form-label">With ids:</label>
++	</td>
++	<td>
++	<input id="ids" class="form-control" type="text" name="obj_ids:tokens" value="<dtml-var "' '.join(obj_ids or [])" html_quote>" />
++	</td>
++</tr>
++
++<tr class="simple-search">
++	<td>
++	<label for="contain" class="form-label">Containing:</label>
++	</td>
++	<td>
++	<input id="contain" class="form-control" type="text" name="obj_searchterm"
++		value="<dtml-var "obj_searchterm and obj_searchterm or ''" html_quote>" />
++	</td>
++</tr>
++
++<tr class="advanced-search-only" <dtml-if "searchtype!='advanced'">style="display:none;"</dtml-if>>
++	<td>
++	<label for="expr" class="form-label">Expr:</label>
++	</td>
++	<td>
++	<textarea id="expr" class="form-control" name="obj_expr" rows="4" cols="30"
++		><dtml-var "obj_expr and obj_expr or ''"></textarea>
++	</td>
++</tr>
++
++<tr class="advanced-search-only" <dtml-if "searchtype!='advanced'">style="display:none;"</dtml-if>>
++	<td>
++	<label for="roles" class="form-label">Where the roles:</label>
++	</td>
++	<td>
++	<div class="form-element">
++		<select id="roles" class="form-control" name="obj_roles:list" size="3" multiple="multiple">
++		<dtml-in valid_roles>
++			<dtml-if obj_roles>
++				<option value="&dtml-sequence-item;"<dtml-if "_['sequence-item'] in obj_roles"> selected="selected"</dtml-if>>&dtml-sequence-item;</option>
++			<dtml-else>
++			 <option value="&dtml-sequence-item;">&dtml-sequence-item;</option>
++			</dtml-if>
++		</dtml-in>
++		</select>
++	</div>
++	</td>
++</tr>
++
++<tr class="advanced-search-only" <dtml-if "searchtype!='advanced'">style="display:none;"</dtml-if>>
++	<td>
++	<label for="perm" class="form-label">Have permission:</label>
++	</td>
++	<td>
++	<div class="form-element">
++		<select id="perm" class="form-control" name="obj_permission">
++		<dtml-in permission_settings mapping>
++			<option value="&dtml-name;"> &dtml-name;</option>
++		</dtml-in>
++		</select>
++	</div>
++	</td>
++</tr>
++
++<tr class="advanced-search-only" <dtml-if "searchtype!='advanced'">style="display:none;"</dtml-if>>
++	<td>
++	<label for="skey" class="form-label">Sort results by:</label>
++	</td>
++	<td>
++	<div class="form-group">
++		<select name="skey" id="skey" class="form-control">
++			<option value="meta_type">Type</option>
++			<option value="id">Id</option>
++		</select>
++		<div class="form-check px-4 mt-2">
++			<input id="rkey" class="form-check-input" type="checkbox" name="rkey" value="reverse" />
++			<label for="rkey" class="form-check-label">Reverse?</label>
++		</div>
++	</div>
++	</td>
++</tr>
++
++<tr class="simple-search">
++	<td>
++	<label for="mod" class="form-label">Modified:</label>
++	</td>
++	<td>
++	<div class="form-inline">
++		<div class="input-group px-0 col-12">
++			<select id="mod" name="obj_mspec" class="input-group-prepend form-control col-4 col-md-3">
++				<option value="&lt;"> before</option>
++				<option value="&gt;"> after</option>
++			</select>
++			<input class="form-control col-8 col-md-9 px-0" type="text" name="obj_mtime" />
++		</div>
++	</div>
++	</td>
++</tr>
++
++<tr class="simple-search">
++	<td>
++	<label for="skinspec" class="form-label">Mark the object used in skin:</label>
++	</td>
++	<td>
++	<div class="form-inline">
++      <select id="skinspec" name="obj_skinspec" class="form-control">
++        <dtml-in getSkinSelections>
++          <option value="&dtml-sequence-item;"
++                  <dtml-if "_['sequence-item'] == getDefaultSkin()">selected</dtml-if>>
++                  <dtml-var sequence-item>
++          </option>
++        </dtml-in>
++			</select>
++		</div>
++	</div>
++	</td>
++</tr>
++
++<tr class="simple-search">
++	<td>&nbsp;</td>
++	<td>
++		<div class="form-check">
++			<input id="thisfolder" class="form-check-input" type="radio" name="search_sub:int" value="0" />
++			<label for="thisfolder" class="form-check-label">Search only in this folder</label>
++		</div>
++		<div class="form-check">
++			<input id="subfolder" class="form-check-input" type="radio" name="search_sub:int" value="1" checked="checked" />
++			<label for="subfolder" class="form-check-label">Search all subfolders</label>
++		</div>
++	</td>
++</tr>
+ 
+-</main>
++<tr class="simple-search">
++	<td>&nbsp;</td>
++	<td>
++		<div class="zmi-controls">
++			<input class="btn btn-primary" type="submit" name="btn_submit" value="Find" />
++			<div class="btn ml-3" >
++				<input id="searchtype"
++					onclick="$('.advanced-search-only').toggle()"
++					class="form-check-input" type="checkbox" name="searchtype" value="advanced" <dtml-if "searchtype=='advanced'"> checked="checked"</dtml-if> />
++				<label for="searchtype" class="form-check-label">Advanced Search</label>
++			</div>
++		</div>
++	</td>
++</tr>
++</table>
++</form>
+ 
+ <dtml-var manage_page_footer>
+diff --git a/src/Products/CMFCore/dtml/findResult.dtml b/src/Products/CMFCore/dtml/findResult.dtml
+deleted file mode 100644
+index 6e0ca36a..00000000
+--- a/src/Products/CMFCore/dtml/findResult.dtml
++++ /dev/null
+@@ -1,313 +0,0 @@
+-<dtml-var manage_page_header>
+-<dtml-var manage_tabs>
+-
+-<main class="container-fluid">
+-
+-<dtml-in expr="('obj_ids', 'obj_metatypes', 'obj_searchterm', 'obj_expr', 'obj_mtime', 'obj_mspec', 'obj_permission', 'obj_roles', 'search_sub')">
+-<dtml-else expr="_.hasattr(REQUEST, _['sequence-item'])">
+-<dtml-call expr="REQUEST.set(_['sequence-item'], _.None)">
+-</dtml-else>
+-</dtml-in>
+-
+-<dtml-if btn_submit>
+-<dtml-with "_.namespace(
+-    results=PrincipiaFind(this(), 
+-	obj_ids=obj_ids, 
+-        obj_metatypes=obj_metatypes, 
+-        obj_searchterm=obj_searchterm, 
+-        obj_expr=obj_expr, 
+-        obj_mtime=obj_mtime, 
+-        obj_mspec=obj_mspec, 
+-        obj_permission=obj_permission, 
+-        obj_roles=obj_roles, 
+-        search_sub=search_sub, 
+-        REQUEST=REQUEST))">
+-
+-<dtml-unless batch_size>
+-<dtml-call "REQUEST.set('batch_size',20)">
+-</dtml-unless>
+-
+-<dtml-if results>
+-<p class="std-text">
+-Displaying items
+-<dtml-in name="results" size=batch_size start=query_start>
+-<dtml-if sequence-start>&dtml-sequence-number;</dtml-if><dtml-if 
+- sequence-end>-&dtml-sequence-number; of <dtml-var 
+- "_.len(results)"></dtml-if></dtml-in> items matching your query. You can 
+-<a href="#form">revise</a> your search terms below.
+-</p>
+-<dtml-else>
+-<p class="std-text">
+-No items were found matching your query. You can <a href="#form">revise</a> 
+-your search terms below.
+-</p>
+-</dtml-if>
+-
+-<dtml-unless searchtype>
+-<dtml-call expr="REQUEST.set('searchtype', 'simple')">
+-</dtml-unless>
+-<dtml-unless skey>
+-<dtml-call expr="REQUEST.set('skey', 'id')">
+-</dtml-unless>
+-<dtml-unless rkey>
+-<dtml-call expr="REQUEST.set('rkey', '')">
+-</dtml-unless>
+-<dtml-if "rkey == 'reverse'">
+-<dtml-call "REQUEST.set('rkey', skey)">
+-</dtml-if>
+-
+-<TABLE width="100%" CELLSPACING="0" CELLPADDING="2" border="0">
+-<dtml-if expr="_.len(results) > batch_size">
+-<tr class="list-header">
+-<td width="50%">
+- <div class="list-item">
+- <dtml-in name="results" previous size="batch_size" start="query_start">
+- <strong> <a href="&dtml-URL;&dtml-sequence-query;query_start=&dtml-previous-sequence-start-number;">&lt; Previous</a></strong>
+- <dtml-else>&nbsp;</dtml-in></div>
+-</td>
+-<td align="right" width="50%">
+- <div class="list-item">
+- <dtml-in name="results" next size=batch_size start=query_start>
+- <strong><a href="&dtml-URL;&dtml-sequence-query;query_start=&dtml-next-sequence-start-number;">Next &gt;</a></strong>
+- <dtml-else>&nbsp;</dtml-in></div>
+-</td>
+-</tr>
+-</dtml-if>
+-</table>
+-
+-<FORM ACTION="manage_compareResults" METHOD="GET">
+-<TABLE width="100%" CELLSPACING="0" CELLPADDING="2" border="0">
+-<dtml-in results size="batch_size" start="query_start" sort_expr="skey" reverse_expr="rkey">
+-<dtml-if sequence-odd>
+-<TR class="row-normal">
+-<dtml-else>
+-<TR class="row-hilite">
+-</dtml-if>
+-  <TD ALIGN="LEFT" VALIGN="TOP" WIDTH="40">
+-  <input type="checkbox" value="&dtml.url_quote-sequence-key;" name="item_paths:list"/>
+-  <A HREF="&dtml.url_quote-sequence-key;/manage_workspace">
+-  <IMG SRC="&dtml-BASEPATH1;/&dtml-icon;"
+-   ALT="[&dtml-meta_type;]" BORDER="0"></A>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="list-item">
+-  <A HREF="&dtml.url_quote-sequence-key;/manage_workspace">
+-  <dtml-if "isFirstInSkin(_['sequence-key'], obj_skinspec)">
+-    <span style="color: red">*</span>
+-  </dtml-if>
+-  &dtml-sequence-key;
+-  <dtml-if title>
+-  (&dtml-title;)
+-  </dtml-if>
+-  </A>
+-  </div>
+-</TD>
+-</TR>
+-</dtml-in>
+-</TABLE>
+-<INPUT TYPE="SUBMIT" NAME="btn_submit" VALUE="Compare">  
+-</FORM>
+-</dtml-with>
+-
+-</dtml-if>
+-
+-<a name="form">
+-<FORM ACTION="manage_findResult" METHOD="GET">
+-<TABLE class="action">
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  Find objects of type:</a>
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_metatypes:list" SIZE="4" MULTIPLE>
+-  <OPTION VALUE="all" <dtml-in obj_metatypes><dtml-if "_['sequence-item'] == 'all'">SELECTED</dtml-if></dtml-in>> All types
+-<dtml-in all_meta_types mapping>
+-  <OPTION VALUE="&dtml-name;" <dtml-in obj_metatypes><dtml-if "_['sequence-item'] == _['name']">SELECTED</dtml-if></dtml-in>>&dtml-name;
+-</dtml-in>
+-  </SELECT>
+-  </div>
+-  </TD>
+-</TR>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  with ids:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <INPUT TYPE="TEXT" NAME="obj_ids:tokens" SIZE="30" VALUE="<dtml-unless "REQUEST.obj_ids == []">
+-<dtml-in expr="REQUEST.obj_ids">
+-&dtml-sequence-item;&nbsp;
+-
+-</dtml-in>
+-</dtml-unless>">
+-  </TD>
+-</TR>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  containing:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <INPUT TYPE="TEXT" NAME="obj_searchterm" SIZE="30" VALUE="<dtml-var "REQUEST.obj_searchterm" html_quote>">
+-  </TD>
+-</TR>
+-
+-<dtml-if "searchtype == 'advanced'">
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  expr:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <TEXTAREA NAME="obj_expr" ROWS="4" COLS="30">&dtml-obj_expr;</TEXTAREA>
+-  </TD>
+-</TR>
+-</dtml-if>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  modified:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_mspec">
+-
+-  <OPTION VALUE="&lt;" <dtml-if "REQUEST.obj_mspec == '<'">SELECTED</dtml-if>> before
+-  <OPTION VALUE="&gt;" <dtml-if "REQUEST.obj_mspec == '>'">SELECTED</dtml-if>> after
+-  </SELECT> 
+-  </div>
+-  <INPUT TYPE="TEXT" NAME="obj_mtime" SIZE="22" VALUE="&dtml-obj_mtime;">
+-  </TD>
+-</TR>
+-
+-
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  mark the object used in skin:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_skinspec">
+-   <dtml-in getSkinSelections>
+-    <OPTION value="&dtml-sequence-item;"
+-            <dtml-if "_['sequence-item'] == obj_skinspec">selected</dtml-if>>
+-            <dtml-var sequence-item>
+-    </OPTION>
+-   </dtml-in>
+-  </SELECT>
+-  </div>
+-  </TD>
+-</TR>
+-
+-<dtml-if "searchtype == 'advanced'">
+-<INPUT TYPE = "hidden" NAME="searchtype" VALUE="advanced">
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  where the roles:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_roles:list" SIZE="3" MULTIPLE>
+-<dtml-in valid_roles>
+-<dtml-if obj_roles>
+-  <OPTION VALUE="&dtml-sequence-item;"<dtml-if "_['sequence-item'] in obj_roles">SELECTED</dtml-if>>&dtml-sequence-item;
+-<dtml-else>
+- <OPTION VALUE="&dtml-sequence-item;">&dtml-sequence-item;
+-</dtml-if>
+- 
+-</dtml-in>
+-  </SELECT>
+-  </div>
+-  </TD>
+-</TR>
+-
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  have permission:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="obj_permission">
+-<dtml-in permission_settings mapping>
+-  <OPTION VALUE="&dtml-name;"<dtml-in obj_metatypes><dtml-if "_['sequence-item'] == _['name']">SELECTED</dtml-if></dtml-in>> &dtml-name;
+-</dtml-in>
+-  </SELECT>
+-  </div>
+-  </TD>
+-</TR>
+-
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-label">
+-  Sort results by:
+-  </div>
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <SELECT NAME="skey">
+-  <OPTION VALUE="id">Id
+-  <OPTION VALUE="meta_type">Type
+-  </SELECT> 
+-  <span class="form-label">
+-  <INPUT TYPE="checkbox" NAME="rkey" VALUE="reverse"> Reverse?
+-  </span>
+-  </div>
+-  </TD>
+-</TR>
+-</dtml-if>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-text">
+-  <INPUT TYPE="RADIO" NAME="search_sub:int" VALUE="0" <dtml-if "REQUEST.search_sub == 0">CHECKED</dtml-if>> 
+-  Search only in this folder
+-  <BR>
+-  <INPUT TYPE="RADIO" NAME="search_sub:int" VALUE="1" <dtml-if "REQUEST.search_sub == 1">CHECKED</dtml-if>> 
+-  Search all subfolders
+-  </div>
+-  </TD>
+-</TR>
+-
+-<TR>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  </TD>
+-  <TD ALIGN="LEFT" VALIGN="TOP">
+-  <div class="form-element">
+-  <INPUT TYPE="SUBMIT" NAME="btn_submit" VALUE="Find">  
+-  <span class="form-text">
+- <dtml-if "searchtype == 'advanced'">
+- <a href="manage_findForm">Simple...<a>
+- <dtml-else>
+- <a href="manage_findAdv">Advanced...<a>
+- </dtml-if>
+-  </span>
+-  </div>
+-  </TD>
+-</TR>
+-</TABLE>
+-</FORM>
+-
+-</main>
+-
+-<dtml-var manage_page_footer>
diff --git a/stack/erp5/buildout.cfg b/stack/erp5/buildout.cfg
index 9df55e5b07..179c003a51 100644
--- a/stack/erp5/buildout.cfg
+++ b/stack/erp5/buildout.cfg
@@ -692,6 +692,8 @@ Acquisition-patches = ${:_profile_base_location_}/../../component/egg-patch/Acqu
 Acquisition-patch-options = -p1
 Products.DCWorkflow-patches = ${:_profile_base_location_}/../../component/egg-patch/Products.DCWorkflow/workflow_method-2.4.1.patch#ec7bb56a9f1d37fcbf960cd1e96e6e6d
 Products.DCWorkflow-patch-options = -p1
+Products.CMFCore-patches = ${:_profile_base_location_}/../../component/egg-patch/Products.CMFCore/portal_skins_ZMI_find.patch#19ec05c0477c50927ee1df6eb75d1e7f
+Products.CMFCore-patch-options = -p1
 PyPDF2-patches = ${:_profile_base_location_}/../../component/egg-patch/PyPDF2/0001-Custom-implementation-of-warnings.formatwarning-remo.patch#d25bb0f5dde7f3337a0a50c2f986f5c8
 PyPDF2-patch-options = -p1
 python-magic-patches = ${:_profile_base_location_}/../../component/egg-patch/python_magic/magic.patch#de0839bffac17801e39b60873a6c2068
@@ -799,7 +801,7 @@ parso = 0.5.1
 Pillow = 6.2.2
 polib = 1.0.8
 pprofile = 2.0.4
-Products.CMFCore = 2.7.0
+Products.CMFCore = 2.7.0+SlapOSPatched001
 Products.ExternalMethod = 4.7
 Products.GenericSetup = 2.3.0
 Products.MailHost = 4.13
-- 
2.30.9