diff --git a/bt5/erp5_search_rank/bt/template_format_version b/bt5/erp5_search_rank/bt/template_format_version
new file mode 100644
index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de
--- /dev/null
+++ b/bt5/erp5_search_rank/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_search_rank/bt/title b/bt5/erp5_search_rank/bt/title
new file mode 100644
index 0000000000000000000000000000000000000000..603b61e9f43c87c3e6314909f55c3c48f1385162
--- /dev/null
+++ b/bt5/erp5_search_rank/bt/title
@@ -0,0 +1 @@
+erp5_search_rank
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.catalog_keys.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.catalog_keys.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b0fe64af0023d1e8f1c26007d25a81cf482bbf5d
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.catalog_keys.xml
@@ -0,0 +1,5 @@
+<catalog_method>
+ <item key="sql_clear_catalog" type="int">
+  <value>1</value>
+ </item>
+</catalog_method>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.sql b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.sql
new file mode 100644
index 0000000000000000000000000000000000000000..ec6198fb5c14b133ae610dfc5fc88602069f8daf
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS search_rank
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..79c9f37bcd3cd29397f9098b761cedc4c6c57b9d
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_drop_search_rank.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="SQL Method" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>allow_simple_one_argument_traversal</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>arguments_src</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>cache_time_</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>class_file_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>class_name_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_hook</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_id</string> </key>
+            <value> <string>erp5_sql_connection</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>z0_drop_search_rank</string> </value>
+        </item>
+        <item>
+            <key> <string>max_cache_</string> </key>
+            <value> <int>100</int> </value>
+        </item>
+        <item>
+            <key> <string>max_rows_</string> </key>
+            <value> <int>1000</int> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>SQL Method</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>z0_drop_search_rank</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.catalog_keys.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.catalog_keys.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d29d36d9f07b76c1a31ae6bec739102b93101efd
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.catalog_keys.xml
@@ -0,0 +1,5 @@
+<catalog_method>
+ <item key="sql_uncatalog_object" type="int">
+  <value>1</value>
+ </item>
+</catalog_method>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.sql b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.sql
new file mode 100644
index 0000000000000000000000000000000000000000..cd47a5717f7298d2f85b9e369c5f02d0fef7bb14
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.sql
@@ -0,0 +1 @@
+DELETE FROM search_rank WHERE <dtml-sqltest uid op=eq type=int>
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c5a3cc450db47f2efc2b237183b9ad55fd4ed270
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z0_uncatalog_search_rank.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="SQL Method" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>allow_simple_one_argument_traversal</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>arguments_src</string> </key>
+            <value> <string>uid</string> </value>
+        </item>
+        <item>
+            <key> <string>cache_time_</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>class_file_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>class_name_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_hook</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_id</string> </key>
+            <value> <string>erp5_sql_deferred_connection</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>z0_uncatalog_search_rank</string> </value>
+        </item>
+        <item>
+            <key> <string>max_cache_</string> </key>
+            <value> <int>100</int> </value>
+        </item>
+        <item>
+            <key> <string>max_rows_</string> </key>
+            <value> <int>1000</int> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>SQL Method</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.catalog_keys.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.catalog_keys.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c95a68655e4b28b9b03081ca25caf201b2237d18
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.catalog_keys.xml
@@ -0,0 +1,5 @@
+<catalog_method>
+ <item key="sql_catalog_object_list" type="int">
+  <value>1</value>
+ </item>
+</catalog_method>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.sql b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f20c96daddc59c3c61eba4f2cae967bd611bfabf
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.sql
@@ -0,0 +1,8 @@
+INSERT INTO search_rank (uid) VALUES
+    <dtml-in prefix="loop" expr="_.range(_.len(uid))">
+      <dtml-if sequence-start><dtml-else>,</dtml-if>
+(
+  <dtml-sqlvar expr="uid[loop_item]" type="int">
+)
+    </dtml-in>
+  ON DUPLICATE KEY UPDATE uid=VALUES(uid);
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.xml
new file mode 100644
index 0000000000000000000000000000000000000000..38c2854a1943571fdf0713d452678eabed4f9c7c
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_catalog_search_rank_list.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="SQL Method" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>allow_simple_one_argument_traversal</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>arguments_src</string> </key>
+            <value> <string>uid</string> </value>
+        </item>
+        <item>
+            <key> <string>cache_time_</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>class_file_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>class_name_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_hook</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_id</string> </key>
+            <value> <string>erp5_sql_connection</string> </value>
+        </item>
+        <item>
+            <key> <string>expression</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>expression_cache_key</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>filtered</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>z_catalog_search_rank_list</string> </value>
+        </item>
+        <item>
+            <key> <string>max_cache_</string> </key>
+            <value> <int>100</int> </value>
+        </item>
+        <item>
+            <key> <string>max_rows_</string> </key>
+            <value> <int>1000</int> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>SQL Method</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>z_catalog_search_rank_list</string> </value>
+        </item>
+        <item>
+            <key> <string>type</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.catalog_keys.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.catalog_keys.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b0fe64af0023d1e8f1c26007d25a81cf482bbf5d
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.catalog_keys.xml
@@ -0,0 +1,5 @@
+<catalog_method>
+ <item key="sql_clear_catalog" type="int">
+  <value>1</value>
+ </item>
+</catalog_method>
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.sql b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.sql
new file mode 100644
index 0000000000000000000000000000000000000000..7c5e1a2fd80e21959a005a4c2b5c2ffed7626e54
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.sql
@@ -0,0 +1,10 @@
+# Host:
+# Database: test
+# Table: 'search_rank'
+#
+CREATE TABLE `search_rank` (
+  `uid` BIGINT UNSIGNED NOT NULL,
+  `search_rank` DECIMAL UNSIGNED ZEROFILL default 0,
+  PRIMARY KEY `uid` (`uid`),
+  KEY `search_rank` (`search_rank`)
+) ENGINE=InnoDB;
diff --git a/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.xml b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8d2d1e165f536f80ae1efcf513c695e6de31850a
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogMethodTemplateItem/portal_catalog/erp5_mysql_innodb/z_create_search_rank.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="SQL Method" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_col</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>allow_simple_one_argument_traversal</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>arguments_src</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>cache_time_</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>class_file_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>class_name_</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_hook</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>connection_id</string> </key>
+            <value> <string>erp5_sql_connection</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>z_create_search_rank</string> </value>
+        </item>
+        <item>
+            <key> <string>max_cache_</string> </key>
+            <value> <int>100</int> </value>
+        </item>
+        <item>
+            <key> <string>max_rows_</string> </key>
+            <value> <int>1000</int> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>SQL Method</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>z_create_search_rank</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/CatalogResultTableTemplateItem/result_table_list.xml b/bt5/erp5_search_rank_catalog/CatalogResultTableTemplateItem/result_table_list.xml
new file mode 100644
index 0000000000000000000000000000000000000000..16baeb757339d06cb7a900d16f260ca79893c5b5
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/CatalogResultTableTemplateItem/result_table_list.xml
@@ -0,0 +1,3 @@
+<key_list>
+ <key>search_rank</key>
+</key_list>
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/PathTemplateItem/portal_alarms/recalculate_document_search_rank.xml b/bt5/erp5_search_rank_catalog/PathTemplateItem/portal_alarms/recalculate_document_search_rank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6a697266742f7fe63221cecb626e63a15915916d
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/PathTemplateItem/portal_alarms/recalculate_document_search_rank.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Alarm" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>active_sense_method_id</string> </key>
+            <value> <string>Alarm_updateSearchRank</string> </value>
+        </item>
+        <item>
+            <key> <string>alarm_notification_mode</string> </key>
+            <value>
+              <tuple>
+                <string>never</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>automatic_solve</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>This alarms update the search rank of all documents of the site.\n
+\n
+It can take a lot of time currently.\n
+Maybe document without search rank should be dropped?</string> </value>
+        </item>
+        <item>
+            <key> <string>enabled</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>recalculate_document_search_rank</string> </value>
+        </item>
+        <item>
+            <key> <string>periodicity_day_frequency</string> </key>
+            <value> <int>7</int> </value>
+        </item>
+        <item>
+            <key> <string>periodicity_hour</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_minute</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_minute_frequency</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_month</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_month_day</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_start_date</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="DateTime" module="DateTime.DateTime"/>
+                </klass>
+                <tuple>
+                  <none/>
+                </tuple>
+                <state>
+                  <tuple>
+                    <float>1638316800.0</float>
+                    <string>GMT</string>
+                  </tuple>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_week</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_week_day</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>periodicity_week_frequency</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Alarm</string> </value>
+        </item>
+        <item>
+            <key> <string>sense_method_id</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>solve_method_id</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Recalculate Document Search Rank</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank.xml b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..599288dc56d644c4b1cb20f0632e98f7fcae8cd6
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Folder" module="OFS.Folder"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>erp5_search_rank</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Alarm_updateSearchRank.py b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Alarm_updateSearchRank.py
new file mode 100644
index 0000000000000000000000000000000000000000..b2968a5e3d4ba3319c514c9e238e7178f340c2e0
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Alarm_updateSearchRank.py
@@ -0,0 +1,9 @@
+portal = context.getPortalObject()
+
+# How to drop documents in final state?
+
+portal.portal_catalog.searchAndActivate(
+  method_id='Base_updateSearchRank',
+  activate_kw={'tag': tag, 'priority': 4},
+)
+context.activate(after_tag=tag).getId()
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Alarm_updateSearchRank.xml b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Alarm_updateSearchRank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2142fabd422332284b0f0fdec7fa424de5836f2
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Alarm_updateSearchRank.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>tag, fixit, params</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Alarm_updateSearchRank</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_calculateSearchRank.py b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_calculateSearchRank.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4d8434490c23d83cd4d5c6b15e13ee11d69342a
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_calculateSearchRank.py
@@ -0,0 +1,26 @@
+portal = context.getPortalObject()
+portal_catalog = portal.portal_catalog
+# PR(B) = (1-d) + d x ( PR(A1) / N(A1) + ... + PR(An) / N(An) )
+
+if context.getRelativeUrl().startswith('portal_'):
+  # Show module content before tools content (Category)
+  d = 0.80
+else:
+  d = 0.85
+
+decimal_length = 10
+multiplier = pow(10, decimal_length - 5)
+
+rank = 0
+
+# Search all document linking to the context
+for sql_result in portal_catalog(
+  select_list=['search_rank'],
+  **{'category.category_uid': context.getUid()}
+):
+  # In case of acquired category, it is not explicitely defined on the document
+  category_list_length = len(sql_result.getObject().getCategoryList()) or 1
+
+  rank += (float(sql_result.search_rank) / multiplier) / category_list_length
+
+return int(((1 - d) + d * rank) * multiplier)
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_calculateSearchRank.xml b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_calculateSearchRank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b5ed574cfb81bcb3689935a71fba58084c12398c
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_calculateSearchRank.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Base_calculateSearchRank</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_updateSearchRank.py b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_updateSearchRank.py
new file mode 100644
index 0000000000000000000000000000000000000000..67ae44b6130786d5ab2d2ee7c03ad505d9b664aa
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_updateSearchRank.py
@@ -0,0 +1,13 @@
+"""
+This method updates the search rank of a document
+"""
+from zExceptions import Unauthorized
+
+if REQUEST is not None:
+  raise Unauthorized
+
+rank = context.Base_calculateSearchRank()
+context.Base_zUpdateSearchRank(
+  uid=context.getUid(),
+  search_rank=rank
+)
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_updateSearchRank.xml b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_updateSearchRank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..22adcbb9a2c19dde1693cb55e126a913566e88a7
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_updateSearchRank.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>REQUEST=None</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Base_updateSearchRank</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_zUpdateSearchRank.sql b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_zUpdateSearchRank.sql
new file mode 100644
index 0000000000000000000000000000000000000000..16dcc7af8e86b62ba9f5afa5027d783777ea2cc3
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_zUpdateSearchRank.sql
@@ -0,0 +1,3 @@
+UPDATE `search_rank`
+SET `search_rank` = <dtml-sqlvar search_rank type="int">
+WHERE `uid` = <dtml-sqlvar uid type="int">
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_zUpdateSearchRank.xml b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_zUpdateSearchRank.xml
new file mode 100644
index 0000000000000000000000000000000000000000..511dcf7bc78a75c6da8d19d4a4d3160796990364
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/SkinTemplateItem/portal_skins/erp5_search_rank/Base_zUpdateSearchRank.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="SQL" module="Products.ZSQLMethods.SQL"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>arguments_src</string> </key>
+            <value> <string>uid\n
+search_rank</string> </value>
+        </item>
+        <item>
+            <key> <string>connection_id</string> </key>
+            <value> <string>erp5_sql_connection</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Base_zUpdateSearchRank</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_search_rank_catalog/bt/template_catalog_method_id_list b/bt5/erp5_search_rank_catalog/bt/template_catalog_method_id_list
new file mode 100644
index 0000000000000000000000000000000000000000..8e1d7e6737db2444352c5c2526814a886fc0fab9
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/bt/template_catalog_method_id_list
@@ -0,0 +1,4 @@
+erp5_mysql_innodb/z0_drop_search_rank
+erp5_mysql_innodb/z0_uncatalog_search_rank
+erp5_mysql_innodb/z_catalog_search_rank_list
+erp5_mysql_innodb/z_create_search_rank
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/bt/template_catalog_result_table_list b/bt5/erp5_search_rank_catalog/bt/template_catalog_result_table_list
new file mode 100644
index 0000000000000000000000000000000000000000..0fb780b8899a74e42d05638d32f66c3f44174fc4
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/bt/template_catalog_result_table_list
@@ -0,0 +1 @@
+search_rank
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/bt/template_format_version b/bt5/erp5_search_rank_catalog/bt/template_format_version
new file mode 100644
index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/bt/template_path_list b/bt5/erp5_search_rank_catalog/bt/template_path_list
new file mode 100644
index 0000000000000000000000000000000000000000..9e73007fcca7530cc7401f99377f6d26d1dc8c92
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/bt/template_path_list
@@ -0,0 +1 @@
+portal_alarms/recalculate_document_search_rank
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/bt/template_skin_id_list b/bt5/erp5_search_rank_catalog/bt/template_skin_id_list
new file mode 100644
index 0000000000000000000000000000000000000000..603b61e9f43c87c3e6314909f55c3c48f1385162
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/bt/template_skin_id_list
@@ -0,0 +1 @@
+erp5_search_rank
\ No newline at end of file
diff --git a/bt5/erp5_search_rank_catalog/bt/title b/bt5/erp5_search_rank_catalog/bt/title
new file mode 100644
index 0000000000000000000000000000000000000000..a3cbac7b0296a021b4b7d6e92e44d2b55be2de0e
--- /dev/null
+++ b/bt5/erp5_search_rank_catalog/bt/title
@@ -0,0 +1 @@
+erp5_search_rank_catalog
\ No newline at end of file