diff --git a/VERSIONS_WIP/154611 b/VERSIONS_WIP/154611
new file mode 100644
index 0000000000000000000000000000000000000000..1ff9ceb69fdb2430aa8bc08ef143cbbde8288e30
--- /dev/null
+++ b/VERSIONS_WIP/154611
@@ -0,0 +1,5 @@
+ - correctif #154611 : Magasin de thèmes : l'affichage liste paginée a été amélioré.
+                       Il garde maintenant l'affichage sélectionné dans le rendu d'un document.
+		       L'affichage des exemplaires bénéficie également de cette amélioration.
+		       En effet lorsqu'un document a trop de documents l'affichage pouvait passer sur une liste paginée.
+		       Maintenant c'est le mur d'exemplaires qui est paginé.
\ No newline at end of file
diff --git a/application/modules/opac/controllers/IndexController.php b/application/modules/opac/controllers/IndexController.php
index 473c7aae284e738638dfaa2ebaf0a995077d2586..c77fa3e67186e38da6b48de021d32e91108cfbaf 100644
--- a/application/modules/opac/controllers/IndexController.php
+++ b/application/modules/opac/controllers/IndexController.php
@@ -121,11 +121,11 @@ class IndexController extends ZendAfi_Controller_Action {
   public function ajaxPaginatedListAction() {
     session_write_close();
 
-    if (! $helper = Intonation_Library_AjaxPaginatedListHelper::find($this->_getParam('id')))
+    if (! $helper = Intonation_Library_PaginatedCollectionHelper::find($this->_getParam('id')))
       return $this->_helper
         ->ajax(function()
                {
-                 return $this->view->renderAjaxPaginatedList((new Intonation_Library_AjaxPaginatedListHelper)->beDeprecated());
+                 return $this->view->renderPaginatedCollectionHelper((new Intonation_Library_PaginatedCollectionHelper)->beDeprecated());
                });
 
     $callback = function() use ($helper) {
@@ -136,7 +136,7 @@ class IndexController extends ZendAfi_Controller_Action {
       ->setSearchTerm($this->_getParam('search', ''))
       ->setNewOrder($this->_getParam('order', ''));
 
-      return $this->view->renderAjaxPaginatedList($helper);
+      return $this->view->renderPaginatedCollectionHelper($helper);
     };
 
     return $this->_helper->ajax($callback);
diff --git a/application/modules/opac/controllers/NoticeajaxController.php b/application/modules/opac/controllers/NoticeajaxController.php
index f0cc977ca1371a65265e60e8cebe4308c2bb0860..67022735e41ef111e2adf362b2036e1aab3b25f5 100644
--- a/application/modules/opac/controllers/NoticeajaxController.php
+++ b/application/modules/opac/controllers/NoticeajaxController.php
@@ -496,7 +496,7 @@ class NoticeAjaxController extends ZendAfi_Controller_Action {
              {
                $record = new Intonation_Library_Record($this->notice);
                return $this->view
-                 ->RenderRecord_RenderItems($record->getItemsFromSIGB(),
+                 ->renderRecord_RenderItems($record->getItemsFromSIGB(),
                                             $record->getSameWorkItemsFromSIGB());
              });
   }
diff --git a/application/modules/opac/controllers/WorkController.php b/application/modules/opac/controllers/WorkController.php
index b002505570ebf4671500933323db625860b64258..e0e7a5ed7d485baf84779ceeea52f82176441b98 100644
--- a/application/modules/opac/controllers/WorkController.php
+++ b/application/modules/opac/controllers/WorkController.php
@@ -69,7 +69,7 @@ class WorkController extends ZendAfi_Controller_Action {
                $items = array_merge($record->getItemsFromSIGB(),
                                     $record->getSameWorkItemsFromSIGB());
 
-               return $this->view->RenderRecord_RenderItems($items);
+               return $this->view->renderRecord_RenderItems($items);
              });
   }
 
diff --git a/library/templates/Intonation/Assets/css/intonation.css b/library/templates/Intonation/Assets/css/intonation.css
index a72639ff16a5e9ee8134d23d85dbb38001332ab0..1a4942b6aa4ea7088dc28cd8bfb0140de9b04839 100644
--- a/library/templates/Intonation/Assets/css/intonation.css
+++ b/library/templates/Intonation/Assets/css/intonation.css
@@ -352,19 +352,17 @@ pre {
     padding-right: 0;
 }
 
-[id*='resources'] .list-group {
+[id*='resources'] > :not(.ajaxified) > div > .list-group {
     max-height: 300px;
     overflow: auto;
     margin-top: 0.75rem;
 }
 
-
 .record_items [id*='resources'] .list-group {
     max-height: unset;
     overflow: unset;
 }
 
-
 [id*='resources'] .list-group-item {
     padding-top: 0;
 }
diff --git a/library/templates/Intonation/Library/AjaxPaginatedListHelper.php b/library/templates/Intonation/Library/PaginatedCollectionHelper.php
similarity index 71%
rename from library/templates/Intonation/Library/AjaxPaginatedListHelper.php
rename to library/templates/Intonation/Library/PaginatedCollectionHelper.php
index 48147ae02e6c848b2069ede5d19322b49521a66f..a3aab14a610e3868c1180923b54094f69dadab62 100644
--- a/library/templates/Intonation/Library/AjaxPaginatedListHelper.php
+++ b/library/templates/Intonation/Library/PaginatedCollectionHelper.php
@@ -20,19 +20,23 @@
  */
 
 
-class Intonation_Library_AjaxPaginatedListHelper {
+class Intonation_Library_PaginatedCollectionHelper {
   use Trait_Translator;
 
   protected
     $_id,
     $_collection,
+    $_secondary_collection,
     $_collection_ids,
-    $_rendering = 'cardifyHorizontal',
+    $_rendering = 'card-horizontal',
+    $_secondary_rendering = '',
+    $_layout = 'list',
+    $_secondary_layout = 'list',
     $_search,
     $_current_page = 1,
     $_page_size = 10,
     $_custom_page_size = 10,
-    $_page,
+    $_page_cache,
     $_view,
     $_carousel_context,
     $_order,
@@ -50,9 +54,13 @@ class Intonation_Library_AjaxPaginatedListHelper {
 
     $cache = new Class_Entity($cache);
 
-    return (new Intonation_Library_AjaxPaginatedListHelper)
+    return (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection($cache->get('collection'))
+      ->setSecondaryCollection($cache->get('secondary_collection'))
       ->setRendering($cache->get('rendering'))
+      ->setSecondaryRendering($cache->get('secondary_rendering'))
+      ->setLayout($cache->get('layout'))
+      ->setSecondaryLayout($cache->get('secondary_layout'))
       ->setCarouselContext($cache->get('carousel_context'))
       ->setOrder($cache->get('order'))
       ->setId($id)
@@ -62,7 +70,9 @@ class Intonation_Library_AjaxPaginatedListHelper {
 
 
   public function __construct(?Storm_Collection $collection = null) {
-    $this->setCollection($collection ?? new Storm_Collection);
+    $this
+      ->setCollection($collection ?? new Storm_Collection)
+      ->setSecondaryCollection(new Storm_Collection);
   }
 
 
@@ -100,17 +110,18 @@ class Intonation_Library_AjaxPaginatedListHelper {
       return true;
 
     return $this
-      ->_sliceCollection()
+      ->_sliceCollection($this->_collection)
+      ->_sliceCollection($this->_secondary_collection)
       ->_cache();
   }
 
 
-  protected function _sliceCollection() {
+  protected function _sliceCollection(Storm_Collection &$collection) : self {
     $this->_has_been_sliced = true;
-    $total = count($this->_collection);
-    $collection_as_array = $this->_collection->getArrayCopy();
+    $total = count($collection);
+    $collection_as_array = $collection->getArrayCopy();
     $collection_as_array = array_slice($collection_as_array, 0, ($total - 100));
-    $this->_collection = new Storm_Collection($collection_as_array);
+    $collection = new Storm_Collection($collection_as_array);
     return $this;
   }
 
@@ -119,7 +130,11 @@ class Intonation_Library_AjaxPaginatedListHelper {
     return ['id' => $this->_id,
             'has_been_slice' => $this->_has_been_sliced,
             'collection' => $this->getCollection(),
+            'secondary_collection' => $this->getSecondaryCollection(),
             'rendering' => $this->getRendering(),
+            'secondary_rendering' => $this->getSecondaryRendering(),
+            'layout' => $this->getLayout(),
+            'secondary_layout' => $this->getSecondaryLayout(),
             'carousel_context' => $this->getCarouselContext(),
             'custom_page_size' => $this->getCustomPageSize(),
             'order' => $this->getOrder()];
@@ -137,6 +152,17 @@ class Intonation_Library_AjaxPaginatedListHelper {
   }
 
 
+  public function setSecondaryCollection($collection) {
+    $this->_secondary_collection = $collection;
+    return $this;
+  }
+
+
+  public function getSecondaryCollection() {
+    return $this->_secondary_collection;
+  }
+
+
   public function getCollectionIds() {
     if ( $this->_collection_ids)
       return $this->_collection_ids;
@@ -162,6 +188,17 @@ class Intonation_Library_AjaxPaginatedListHelper {
   }
 
 
+  public function setSecondaryRendering($rendering) {
+    $this->_secondary_rendering = $rendering;
+    return $this;
+  }
+
+
+  public function getSecondaryRendering() {
+    return $this->_secondary_rendering;
+  }
+
+
   public function setCurrentPage($current_page) {
     $this->_current_page = $current_page;
     return $this;
@@ -205,28 +242,22 @@ class Intonation_Library_AjaxPaginatedListHelper {
   }
 
 
-  public function getPage($page) {
-    if ($this->_page)
-      return $this->_page;
+  public function getPage(int $page, Storm_Collection $collection) {
+    if ($this->_page_cache)
+      return $this->_page_cache;
 
     $slice = function($collection) use ($page) {
       $sub = array_slice($collection->getArrayCopy(),
                          (($page - 1) * $this->_page_size),
                          $this->_page_size);
-      return $this->_page = ((new Storm_Collection($sub))
-                             ->eachDo(function($wrapper)
-                                      {
-                                        if ($wrapper->getModel())
-                                          return;
-
-                                        $this->_wakeUp($wrapper);
-                                      }));
+      return $this->_page_cache = ((new Storm_Collection($sub))
+                                   ->eachDo(fn($wrapper) => $this->_wakeUp($wrapper)));
     };
 
     if ( ! $search = $this->getSearchTerm())
-      return $slice($this->getCollection());
+      return $slice($collection);
 
-    $result = $this->_search($search, $this->getCollection());
+    $result = $this->_search($search, $collection);
 
     $this->_count_search_result = count($result);
     $this->_cache();
@@ -235,7 +266,6 @@ class Intonation_Library_AjaxPaginatedListHelper {
 
 
   protected function _search($term, $collection) {
-
     $terms = strtolower($term);
     $terms = explode(' ', $terms);
     return $collection->select(function($wrapper) use ($terms)
@@ -253,12 +283,15 @@ class Intonation_Library_AjaxPaginatedListHelper {
 
 
   protected function _wakeUp($wrapper) {
-    if (!$classname = $wrapper->getClassname())
+    if ( ! $classname = $wrapper->getClassname())
       return null;
 
-    return $wrapper
-      ->setView($this->_view)
-      ->setModel(call_user_func([$classname, 'find'], $wrapper->getId()));
+    if ( ! $wrapper->getView())
+      $wrapper->setView($this->_view);
+
+    return $wrapper->getModel()
+      ? $wrapper
+      : $wrapper->setModel(call_user_func([$classname, 'find'], $wrapper->getId()));
   }
 
 
@@ -362,4 +395,42 @@ class Intonation_Library_AjaxPaginatedListHelper {
     asort($options);
     return $options;
   }
+
+
+  public function setLayout(string $layout) : self {
+    $this->_layout = $layout;
+    return $this;
+  }
+
+
+  public function getLayout() : string {
+    return $this->_layout;
+  }
+
+
+  public function setSecondaryLayout(string $layout) : self {
+    $this->_secondary_layout = $layout;
+    return $this;
+  }
+
+
+  public function getSecondaryLayout() : string {
+    return $this->_secondary_layout;
+  }
+
+
+  public function getSubCollection() : Storm_Collection {
+    return $this->getPage($this->getCurrentPage(), $this->getCollection());
+  }
+
+
+  public function getSubSecondaryCollection() : Storm_Collection {
+    return $this->reset()->getPage($this->getCurrentPage(), $this->getSecondaryCollection());
+  }
+
+
+  public function reset() : self {
+    $this->_page_cache = null;
+    return $this;
+  }
 }
diff --git a/library/templates/Intonation/Library/Settings.php b/library/templates/Intonation/Library/Settings.php
index be387452798ff8fa908d95f857cc40683f7b1a54..08285c03b638fac7e5d3e4e8b58f5fde994dac48 100644
--- a/library/templates/Intonation/Library/Settings.php
+++ b/library/templates/Intonation/Library/Settings.php
@@ -317,7 +317,7 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                                                   'span class truncate_list_size' => 'btn btn-sm btn-info',
                                                   'div class truncate_list_size_wrapper' => 'col-12 col-sm-3',
                                                   'div class truncate_list_form_wrapper' => 'col-12 col-sm-9',
-                                                  'div class truncate_list_container' => 'container my-2',
+                                                  'div class truncate_list_container' => 'my-2',
                                                   'div class truncate_list_row' => 'justify-content-start',
                                                   'div class truncate_list_wrapper' => 'col-12 list-group bg-transparent no_border',
                                                   'div class truncate_list_top_tools' => 'col-12',
@@ -326,7 +326,15 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                                                   'span class more_description_data_title' => 'font-italic',
                                                   'span class facet_title' => 'font-weight-bold',
                                                   'span class selection_date_maj' => 'badge-warning',
-                                                  'span class selection_count_records' => 'badge-info'
+                                                  'span class selection_count_records' => 'badge-info',
+                                                  'div class items_map' => 'col-12 mb-3',
+                                                  'div class items_wall' => 'col-12',
+                                                  'div class same_work_items' => 'col-12 mt-3',
+                                                  'div class same_work_items_collection' => 'col-12',
+                                                  'div class paginated_collection' => 'col-12 mt-3 list-group bg-transparent no_border',
+                                                  'div class paginated_secondary_collection' => 'col-12 mt-3 list-group bg-transparent no_border',
+                                                  'div class ajax_paginated_collection' => 'col-12',
+                                                  'div class paginated_collection_pager' => 'col'
                           ],
 
                           'icons_map_doc_types' => [],
diff --git a/library/templates/Intonation/Library/Widget/Carousel/PaginatedCollection.php b/library/templates/Intonation/Library/Widget/Carousel/PaginatedCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fd94f31c3f03fed274cd4b4fcb0a94226909251
--- /dev/null
+++ b/library/templates/Intonation/Library/Widget/Carousel/PaginatedCollection.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright (c) 2012-2022, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Intonation_Library_Widget_Carousel_PaginatedCollection extends Intonation_Library_Widget_Carousel_View {
+
+
+
+  public function setPaginatedCollectionHelper(Intonation_Library_PaginatedCollectionHelper $helper) : self {
+    $this->_pagination_collection_helper = $helper;
+    return $this;
+  }
+
+
+  protected function _findElements() : array {
+    return $this->_pagination_collection_helper
+      ->getSubCollection()
+      ->getArrayCopy();
+  }
+
+
+  public function getSecondaryContent() : string {
+    return $this->_renderElements($this->_pagination_collection_helper
+                                  ->getSubSecondaryCollection()
+                                  ->getArrayCopy());
+  }
+
+
+  protected function _getWrapper() {
+    return null;
+  }
+
+
+  protected function _getLinkToAllTitle() {
+    return '';
+  }
+
+
+  protected function _getRSSUrl() {
+    return '';
+  }
+}
diff --git a/library/templates/Intonation/Library/Widget/Carousel/View.php b/library/templates/Intonation/Library/Widget/Carousel/View.php
index 2b4664a54c93dbbd93f4eb0b3605bac56184f482..07c4e0e651ed4d656de4849a81c81fd5fc9128ba 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/View.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/View.php
@@ -198,6 +198,9 @@ abstract class Intonation_Library_Widget_Carousel_View extends Zendafi_View_Help
 
 
   protected function _wrapElements($elements) {
+    if ( null === ($wrapper = $this->_getWrapper()))
+      return $elements;
+
     return array_map(function($element)
                      {
                        $wrapper = $this->_getWrapper();
@@ -337,7 +340,9 @@ abstract class Intonation_Library_Widget_Carousel_View extends Zendafi_View_Help
 
 
   protected function _emptyListMessage() {
-    return $this->view->tag('p', $this->_('Aucun document'));
+    return $this->view->tag('p',
+                            $this->_('Aucun document'),
+                            ['class' => 'empty_list_message']);
   }
 
 
@@ -403,7 +408,7 @@ abstract class Intonation_Library_Widget_Carousel_View extends Zendafi_View_Help
   }
 
 
-  Abstract protected function _findElements();
+  abstract protected function _findElements();
   abstract protected function _getWrapper();
   abstract protected function _getLinkToAllTitle();
   abstract protected function _getRSSUrl();
diff --git a/library/templates/Intonation/View/Abstract/Layout.php b/library/templates/Intonation/View/Abstract/Layout.php
index aec10ab2847bffcce985718f1b273ad1041378b4..be374b7015a4feca7c10b0192f77a3805d49d484 100644
--- a/library/templates/Intonation/View/Abstract/Layout.php
+++ b/library/templates/Intonation/View/Abstract/Layout.php
@@ -38,13 +38,13 @@ class Intonation_View_Abstract_Layout extends ZendAfi_View_Helper_BaseHelper {
   }
 
 
-  protected function _ajaxifyList(Storm_Collection $collection,
-                                  ?Closure $callback) : string {
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper($collection))
+  protected function _ajaxifyList(Storm_Collection $collection) : string {
+
+    $helper = (new Intonation_Library_PaginatedCollectionHelper($collection))
       ->setView($this->view)
       ->setCarouselContext($this->getRenderingOptions())
       ->setOrder($this->getRenderingOptions()->getOrder());
 
-    return $this->view->renderAjaxPaginatedList($helper, $callback);
+    return $this->view->renderPaginatedCollectionHelper($helper);
   }
 }
diff --git a/library/templates/Intonation/View/Ajax.php b/library/templates/Intonation/View/Ajax.php
index 364fda4eab1add6ed525a2f0e097251f102b9acd..24e5de528bd92900ef87b59c84fe1cbb48696e77 100644
--- a/library/templates/Intonation/View/Ajax.php
+++ b/library/templates/Intonation/View/Ajax.php
@@ -36,6 +36,8 @@ class Intonation_View_Ajax extends Intonation_View_Opac {
       ->beAjax()
       ->addJQueryReady('initializePopups();setupAnchorsTarget();'.  Class_AdminVar_Cookies::manager()->triggers());
 
-    return $this->_body . Class_ScriptLoader::getInstance()->html();
+    $head = $this->_tag('head', Class_ScriptLoader::getInstance()->html());
+
+    return $head . $this->_body;
   }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/View/Notice/Exemplaires.php b/library/templates/Intonation/View/Notice/Exemplaires.php
index 1d0779c681bdc77b363c78d3aaca3f3cae9f86ae..3d2faf5b2e0c2062cda4011fe3b521d5c83b0848 100644
--- a/library/templates/Intonation/View/Notice/Exemplaires.php
+++ b/library/templates/Intonation/View/Notice/Exemplaires.php
@@ -22,6 +22,6 @@
 
 class Intonation_View_Notice_Exemplaires extends ZendAfi_View_Helper_BaseHelper {
   public function Notice_Exemplaires($items) {
-    return $this->view->RenderRecord_RenderItems($items);
+    return $this->view->renderRecord_RenderItems($items);
   }
 }
diff --git a/library/templates/Intonation/View/OsmMap.php b/library/templates/Intonation/View/OsmMap.php
index b8a0cf234b6105d07cdfcfa18039c5d44fee0bac..fba31e5375295b38c93bec42a25a83e9754ccb4f 100644
--- a/library/templates/Intonation/View/OsmMap.php
+++ b/library/templates/Intonation/View/OsmMap.php
@@ -24,11 +24,6 @@ class Intonation_View_OsmMap extends ZendAfi_View_Helper_BaseHelper {
   protected $_wrapper_id, $_map_id;
 
 
-  public function init() {
-    $this->setOSMId(uniqid());
-  }
-
-
   public function setOSMId($id) {
     $this->_wrapper_id = 'osm_wrap_' . $id;
     $this->_map_id = 'osm_map_' . $id;
@@ -43,11 +38,16 @@ class Intonation_View_OsmMap extends ZendAfi_View_Helper_BaseHelper {
     if (!$elements || !($datas = $this->_collectDatas($elements, $html_renderer)))
       return '';
 
+    $datas = json_encode($datas);
+
+    if ( ! $this->_wrapper_id)
+      $this->setOSMId(md5($datas));
+
     $this->renderHeadScriptsOn(Class_ScriptLoader::getInstance());
 
     $map = $this->_div(['id' => $this->_map_id,
                         'class' => 'leaflet_osm',
-                        'data-osm' => json_encode($datas),
+                        'data-osm' => $datas,
                         'data-osm-geojson' => '',
                         'data-osm-layer' => 1,
                         'data-osm-zoom' => 0,
@@ -64,12 +64,18 @@ class Intonation_View_OsmMap extends ZendAfi_View_Helper_BaseHelper {
 
   public function renderHeadScriptsOn($script_loader) {
     $script_loader
+      ->loadJQuery()
+      ->loadJQueryUI()
+      ->addOPACScript('subModal')
+      ->addAdminScripts(['onload_utils', 'global'])
       ->loadLeafletJS()
-      ->addOPACScripts(['openStreetMap/openStreetMap.js', 'openStreetMap/leaflet.markercluster.js'])
+      ->addOPACScripts(['openStreetMap/openStreetMap.js',
+                        'openStreetMap/leaflet.markercluster.js'])
       ->addOPACStyleSheets(['../js/openStreetMap/openStreetMap.css',
                             '../js/openStreetMap/MarkerCluster.css',
                             '../js/openStreetMap/MarkerCluster.Default.css'])
-      ->addJQueryReady('setTimeout(function() {$("#'. $this->_wrapper_id . '").openStreetMap();}, 100);');
+      ->addJQueryReady('$("#'. $this->_wrapper_id . '").openStreetMap();');
+
     return $this;
   }
 
diff --git a/library/templates/Intonation/View/RenderAjaxTruncateList.php b/library/templates/Intonation/View/RenderPaginatedCollection.php
similarity index 51%
rename from library/templates/Intonation/View/RenderAjaxTruncateList.php
rename to library/templates/Intonation/View/RenderPaginatedCollection.php
index 4b1273421897778aa199f45b414abf8e22f74fbb..0f220d149fc240edbb85004e1e2c41669f9173ca 100644
--- a/library/templates/Intonation/View/RenderAjaxTruncateList.php
+++ b/library/templates/Intonation/View/RenderPaginatedCollection.php
@@ -20,26 +20,33 @@
  */
 
 
-class Intonation_View_RenderAjaxTruncateList extends Intonation_View_Abstract_Layout {
+class Intonation_View_RenderPaginatedCollection extends Intonation_View_Abstract_Layout {
 
-  public function renderAjaxTruncateList(Storm_Collection $collection,
-                                         ?Closure $callback = null,
-                                         int $page_size = 0) : string {
+  public function renderPaginatedCollection(Storm_Collection $collection,
+                                            string $layout,
+                                            string $rendering,
+                                            int $page_size = 0,
+                                            ?Storm_Collection $secondary_collection = null,
+                                            string $secondary_layout = '',
+                                            string $secondary_rendering = '') : string {
 
-    $callback
-      ? $callback
-      : fn($item) => $this->view->cardifyHorizontal($item);
-
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
+    $helper = (new Intonation_Library_PaginatedCollectionHelper)
       ->setView($this->view)
       ->setCarouselContext($this->getRenderingOptions())
       ->setCollection($collection)
-      ->setOrder($this->getRenderingOptions()->getOrder());
+      ->setOrder($this->getRenderingOptions()->getOrder())
+      ->setLayout($layout)
+      ->setSecondaryLayout($secondary_layout)
+      ->setRendering($rendering)
+      ->setSecondaryRendering($secondary_rendering);
+
+    if ($secondary_collection)
+      $helper->setSecondaryCollection($secondary_collection);
 
     if (0 != $page_size)
       $helper->setCustomPageSize($page_size)
              ->setPageSize($page_size);
 
-    return $this->view->renderAjaxPaginatedList($helper, $callback);
+    return $this->view->renderPaginatedCollectionHelper($helper);
   }
 }
diff --git a/library/templates/Intonation/View/RenderAjaxPaginatedList.php b/library/templates/Intonation/View/RenderPaginatedCollectionHelper.php
similarity index 73%
rename from library/templates/Intonation/View/RenderAjaxPaginatedList.php
rename to library/templates/Intonation/View/RenderPaginatedCollectionHelper.php
index d33e819d514cb4972fe27092f471f9db1fdadfd2..e192248096e7957649e3406987360e7bb9f2efbd 100644
--- a/library/templates/Intonation/View/RenderAjaxPaginatedList.php
+++ b/library/templates/Intonation/View/RenderPaginatedCollectionHelper.php
@@ -20,59 +20,88 @@
  */
 
 
-class Intonation_View_RenderAjaxPaginatedList extends ZendAfi_View_Helper_BaseHelper {
+class Intonation_View_RenderPaginatedCollectionHelper extends ZendAfi_View_Helper_BaseHelper {
 
-  protected
-    $_id,
-    $_available_orders;
 
-
-  public function renderAjaxPaginatedList(Intonation_Library_AjaxPaginatedListHelper $helper,
-                                          ?Closure $callback = null) {
+  public function renderPaginatedCollectionHelper(Intonation_Library_PaginatedCollectionHelper $helper) : string {
     $this->_id = $helper->getId();
     $this->_available_orders = $helper->getCarouselContext()->getAvailableOrders();
-    $sub_collection = $helper->getPage($helper->getCurrentPage());
+    $sub_collection = $helper->getSubCollection();
     $pager = $this->_renderPager($helper);
 
-    $callback = $callback
-      ? $callback
-      : function($element) use ($helper) {
-        $element->setView($this->view);
-        $element->updateWithModel($element->getModel());
-        return call_user_func_array([$this->view, $helper->getRendering()], [$element]);
-      };
-
     $html_collection =
-      $this->view->div(['class' => 'list-group bg-transparent no_border',
+      $this->view->div(['class' => 'paginated_collection',
                         'data-deprecated' => $helper->isDeprecated()],
-                       $this->view->renderList($sub_collection, $callback));
+                       $this->_renderCollection($helper, $sub_collection));
+
+    if ( $secondary_html_collection = $this->_renderSecondaryCollection($helper, $sub_collection))
+      $html_collection .= $secondary_html_collection;
+
+    $html_collection = $this->view->grid($html_collection);
 
     $html_content = implode([$this->_renderTools($helper, $sub_collection),
                              $pager,
                              $html_collection]);
 
+    $this->_getScripts($helper);
+
     return
-      $this->view->div(['id' => 'ajax_paginated_list_' . $this->_id],
+      $this->view->div(['id' => 'ajax_paginated_list_' . $this->_id,
+                        'class' => 'ajax_paginated_collection'],
                        $this->view->div(['class' => 'ajax_content'],
-                                        $html_content))
-      . $this->_getScripts($helper);
+                                        $html_content));
+  }
+
+
+  protected function _renderCollection(Intonation_Library_PaginatedCollectionHelper $helper,
+                                       Storm_Collection $sub_collection) : string {
+
+    $layout_helper =
+      ((new Intonation_Library_Widget_Carousel_PaginatedCollection($helper->getId(),
+                                                                   ['layout' => $helper->getLayout(),
+                                                                    'rendering' => $helper->getRendering()]))
+       ->setView($this->view)
+       ->setPaginatedCollectionHelper($helper));
+
+    $layout_helper->getHtml();
+    return $layout_helper->getContent();
+  }
+
+
+  protected function _renderSecondaryCollection(Intonation_Library_PaginatedCollectionHelper $helper,
+                                                Storm_Collection $sub_collection) : string {
+    if ( ! $layout = $helper->getSecondaryLayout())
+      return '';
+
+    if ( ! $rendering = $helper->getSecondaryRendering())
+      return '';
+
+    if ( ! $secondary_collection = $helper->getSecondaryCollection())
+      return '';
+
+    $layout_helper =
+      ((new Intonation_Library_Widget_Carousel_PaginatedCollection($helper->getId(),
+                                                                   ['layout' => $layout,
+                                                                    'rendering' => $rendering]))
+       ->setView($this->view)
+       ->setPaginatedCollectionHelper($helper));
+
+    return $this->view->div(['class' => 'paginated_secondary_collection'],
+                            $layout_helper->getSecondaryContent());
   }
 
 
   protected function _getScripts($helper) {
     if ($helper->isDeprecated())
-      return '';
+      return;
 
     $url = Class_Url::relative('/public/opac/js/ajaxifyPaginatedList/ajaxifyPaginatedList.js');
 
-    return Class_ScriptLoader::getInstance()
-
+    Class_ScriptLoader::getInstance()
       ->addJQueryReady(sprintf('if (undefined == $.fn.ajaxifyPaginatedList) {var script = document.createElement("script"); script.type = "text/javascript"; script.src = "%s"; $("head").append(script);}',
                                $url))
-
-      ->addJQueryReady(sprintf('setTimeout(function() {$("#ajax_paginated_list_%s:not(.ajaxified)").ajaxifyPaginatedList();}, 100);',
-                               $this->_id))
-      ->html();
+      ->addJQueryReady(sprintf('$("#ajax_paginated_list_%s:not(.ajaxified)").ajaxifyPaginatedList();',
+                               $this->_id));
 
   }
 
@@ -130,7 +159,7 @@ class Intonation_View_RenderAjaxPaginatedList extends ZendAfi_View_Helper_BaseHe
                                                         'id' => 'next_' . $this->_id,
                                                         'data-disabled' => $next_button_disabled]));
 
-    return $this->view->div([],
+    return $this->view->div(['class' => 'paginated_collection_pager'],
                             implode([$anchor_previous,
 
                                      $this->_tag( 'span' ,
@@ -140,7 +169,7 @@ class Intonation_View_RenderAjaxPaginatedList extends ZendAfi_View_Helper_BaseHe
   }
 
 
-  protected function _renderTools($helper, $sub_collection) {
+  protected function _renderTools($helper, $sub_collection) : string {
     $form = new ZendAfi_Form;
 
     $form
diff --git a/library/templates/Intonation/View/RenderRecord/RenderItems.php b/library/templates/Intonation/View/RenderRecord/RenderItems.php
index 8431d998676f41959df4c4d13d04afc4296d0b9c..3098e79055282d37f31acfa80d69d8348407ec11 100644
--- a/library/templates/Intonation/View/RenderRecord/RenderItems.php
+++ b/library/templates/Intonation/View/RenderRecord/RenderItems.php
@@ -24,104 +24,154 @@ class Intonation_View_RenderRecord_RenderItems extends ZendAfi_View_Helper_BaseH
 
 
   protected
-    $_should_use_ILS_items_threshold;
+    $_should_display_map_cache,
+    $_should_use_ILS_items_threshold_cache,
+    $_should_paginate_cache;
 
 
-  public function RenderRecord_RenderItems($items, $same_work = []) {
-    if (!$items)
+  public function renderRecord_RenderItems(array $items, array $same_work = []) : string {
+    if ( ! $items)
       return '';
 
-    if ( $this->_shouldPaginate($items))
-      return $this->view->renderAjaxTruncateList(new Storm_Collection($this->_getWrappedItems($items)),
-                                                 null,
-                                                 Class_Profil_ItemsSettings::current()->getPaginationThreshold());
-
     $record = new Intonation_Library_Record(reset($items)->getNotice());
 
-    if ($record->isExternalResource())
-      return $this->view->RenderRecord_ExternalUrl($record->getUrl());
+    return $record->isExternalResource()
+      ? $this->view->RenderRecord_ExternalUrl($record->getUrl())
+      : $this->_renderItems($items, $same_work);
+  }
+
 
+  protected function _renderItems(array $items, array $same_work) : string {
     $html = [ $this->_hookForMoreHtml($items) ];
 
-    $html [] = $this->_renderOsmMap($items, $same_work);
+    return ($html = $this->_renderItemsByStrategy($items, $same_work, $html))
+      ? $this->view->grid(implode($html))
+      : '';
+  }
+
 
-    $html [] = $this->view->div(['class' => 'col-12 items_wall'],
-                                $this->_getHtmlItems($items));
+  protected function _renderItemsByStrategy(array $items,
+                                            array $same_work,
+                                            array $html) : array {
+    return $this->_getStrategy($items)->renderItems($items, $same_work, $html);
+  }
 
-    if ($same_work) {
-      $html [] = $this->view->div(['class' => 'col-12 same_work_items'],
-                                  $this->view->tag('h3', $this->_('Exemplaires de la même œuvre'))
-                                  . $this->view->div(['class' => 'col-12'],
-                                                     $this->_getHtmlItems($same_work)));
-    }
 
-    return $this->view->grid(implode($html));
+  protected function _getStrategy(array $items) : Intonation_View_RenderRecord_RenderItemsStrategy {
+    $strategy = $this->_getStrategyClass($items);
+    return new $strategy($this->view);
   }
 
 
-  protected function _getWrappedItems(array $items) : array {
+  protected function _getStrategyClass(array $items) : string {
+    if ($this->_shouldDisplayMap()
+        && $this->_shouldPaginate($items)
+        && $this->_shouldCallILSWs($items))
+      return Intonation_View_RenderRecord_RenderItemsStrategyMapAndILSAndPagination::class;
+
+    if ($this->_shouldDisplayMap()
+        && $this->_shouldPaginate($items))
+      return Intonation_View_RenderRecord_RenderItemsStrategyMapAndPagination::class;
+
+    if ($this->_shouldDisplayMap()
+        && $this->_shouldCallILSWs($items))
+      return Intonation_View_RenderRecord_RenderItemsStrategyMapAndILS::class;
+
+    if ($this->_shouldDisplayMap())
+      return Intonation_View_RenderRecord_RenderItemsStrategyMap::class;
+
+    if ( $this->_shouldPaginate($items) && $this->_shouldCallILSWs($items))
+      return Intonation_View_RenderRecord_RenderItemsStrategyILSAndPagination::class;
+
+    if ($this->_shouldPaginate($items))
+      return Intonation_View_RenderRecord_RenderItemsStrategyPagination::class;
+
     return $this->_shouldCallILSWs($items)
-      ? array_map(fn($item) =>
-                  (new Intonation_Library_View_Wrapper_Item($item,
-                                                            $this->view)),
-                  $items)
-      : array_map(fn($item) =>
-                  (new Intonation_Library_View_Wrapper_ItemWithoutSIGB($item,
-                                                                       $this->view)),
-                  $items);
+      ? Intonation_View_RenderRecord_RenderItemsStrategyILS::class
+      : Intonation_View_RenderRecord_RenderItemsStrategyNoMapNoILSNoPagination::class;
   }
 
 
   protected function _shouldCallILSWs(array $items) : bool {
-    if ( $this->_should_use_ILS_items_threshold )
-      return $this->_should_use_ILS_items_threshold;
+    if ( isset($this->_should_use_ILS_items_threshold_cache))
+      return $this->_should_use_ILS_items_threshold_cache;
 
-    return $this->_should_use_ILS_items_threshold =
+    return $this->_should_use_ILS_items_threshold_cache =
       ((new Intonation_Library_Record_Items([]))
        ->shouldCallSIGB($items));
   }
 
 
+  protected function _shouldDisplayMap() : bool {
+    if ( isset($this->_should_display_map_cache))
+      return $this->_should_display_map_cache;
+
+    return $this->_should_display_map_cache =
+      Class_Profil_ItemsSettings::current()->isAllItemsMap();
+  }
+
+
   protected function _shouldPaginate(array $items) : bool {
-    return count($items) > (int) Class_Profil_ItemsSettings::current()->getPaginationThreshold();
+    if ( isset($this->_should_paginate_cache))
+      return $this->_should_paginate_cache;
+
+    return $this->_should_paginate_cache =
+      (count($items) > (int) Class_Profil_ItemsSettings::current()->getPaginationThreshold());
   }
 
 
-  protected function _renderOsmMap($items, $same_work) {
-    if ( ! Class_Profil_ItemsSettings::current()->isAllItemsMap())
-      return '';
+  protected function _hookForMoreHtml($items) {
+    return '';
+  }
+}
 
-    $wrapper = $this->_shouldCallILSWs($items)
-      ? Intonation_Library_View_Wrapper_ItemForOsm::class
-      : Intonation_Library_View_Wrapper_ItemForOsmWithoutSIGB::class;
 
-    $elements = (new Storm_Collection(array_merge($items, $same_work)))
-      ->collect(function($item) use ($wrapper)
-                {
-                  return new $wrapper($item,
-                                      $this->view);
-                });
 
-    return ($map = $this->view->osmMap($elements))
-      ? $this->view->div(['class' => 'col-12 mb-3 items_map'],
-                         $map)
-      : '';
+
+abstract class Intonation_View_RenderRecord_RenderItemsStrategy {
+
+  use Trait_Translator;
+
+
+  protected $_view;
+
+
+  public function __construct(ZendAfi_Controller_Action_Helper_View $view) {
+    $this->_view = $view;
   }
 
 
-  protected function _getHtmlItems($items) {
-    $items = $this->_sortItems($items);
+  protected function _renderItemsHTML(array $items) : string {
+    return $this->_view->div(['class' => 'items_wall'],
+                             $this->_renderItemsHTMLInner($items));
+  }
+
 
-    $elements = $this->_getWrappedItems($items);
+  protected function _renderItemsHTMLInner(array $items) : string {
+    return ($this->_view->newHelper('RenderWall'))
+      ->renderWall($this->_initCollection($this->_sortItems($items),
+                                          $this->_getItemWrapper()),
+                   fn($element) => $this->_view->cardifyOnlyDescription($element));
+  }
 
-    $helper = $this->view->newHelper('RenderWall');
 
-    return $helper->renderWall(new Storm_Collection($elements),
-                               fn($element) => $this->view->cardifyOnlyDescription($element));
+  protected function _initCollection(array $items, string $wrapper) : Storm_Collection {
+    return (new Storm_Collection($items))
+      ->collect(fn($item) => new $wrapper($item, $this->_view));
   }
 
 
-  protected function _sortItems($items) {
+  protected function _renderSameWorkItemsHTML(array $items) : string {
+    return $items
+      ? $this->_view->div(['class' => 'same_work_items'],
+                          $this->_view->tag('h3', $this->_('Exemplaires de la même œuvre'))
+                          . $this->_view->div(['class' => 'same_work_items_collection'],
+                                              $this->_renderItemsHTML($items)))
+      : '';
+  }
+
+
+  protected function _sortItems(array $items) : array {
     $settings = Class_Profil_ItemsSettings::current();
 
     if ( ! $order = $settings->getOrderBy() )
@@ -134,10 +184,33 @@ class Intonation_View_RenderRecord_RenderItems extends ZendAfi_View_Helper_BaseH
   }
 
 
-  protected function _sortByAvailability($items) {
-    if ( ! $this->_shouldCallILSWs($items))
-      return $items;
+  protected function _sortByAvailability(array $items) : array {
+    return $items;
+  }
+
+
+  protected function _renderMapHTML(array $items, array $same_work) : string {
+    $collection =
+      $this->_initCollection(array_merge($items, $same_work),
+                             $this->_getOsmItemWrapper());
+
+    return $this->_view->div(['class' => 'items_map'],
+                             $this->_view->osmMap($collection));
+  }
+
+
+  protected function _renderPaginatedItemsHTML(array $items) : string {
+    $collection = $this->_initCollection($items, $this->_getItemWrapper());
+
+    return
+      $this->_view->renderPaginatedCollection($collection,
+                                              Intonation_Library_Widget_Carousel_Definition::WALL,
+                                              Intonation_Library_Widget_Carousel_Definition::CARD_DESCRIPTION,
+                                              Class_Profil_ItemsSettings::current()->getPaginationThreshold());
+  }
+
 
+  protected function _sortByILSAvailability(array $items) : array {
     usort($items,
           function($a, $b)
           {
@@ -151,7 +224,253 @@ class Intonation_View_RenderRecord_RenderItems extends ZendAfi_View_Helper_BaseH
   }
 
 
-  protected function _hookForMoreHtml($items) {
-    return '';
+  protected function _renderMapAndItemsPaginated(array $items,
+                                                 array $same_work,
+                                                 array $html) : array {
+    $items = array_merge($items, $same_work);
+    $collection = $this->_initCollection($items, $this->_getOsmItemWrapper());
+    $secondary_collection = $this->_initCollection($items, $this->_getItemWrapper());
+
+    $html [] = $this->_view
+      ->renderPaginatedCollection($collection,
+                                  Intonation_Library_Widget_Carousel_Definition::MAP,
+                                  Intonation_Library_Widget_Carousel_Definition::CARD_DESCRIPTION,
+                                  Class_Profil_ItemsSettings::current()->getPaginationThreshold(),
+                                  $secondary_collection,
+                                  Intonation_Library_Widget_Carousel_Definition::WALL,
+                                  Intonation_Library_Widget_Carousel_Definition::CARD_DESCRIPTION);
+
+    return $html;
+  }
+
+
+  protected function _itemsWithMap(array $items, array $same_work, array $html) : array {
+    $html [] = $this->_renderMapHTML($items, $same_work);
+    return
+      array_merge($html,
+                  $this->_itemsWithoutMap($items, $same_work, $html));
+  }
+
+
+  protected function _itemsWithoutMap(array $items, array $same_work, array $html) : array {
+    $html [] = $this->_renderItemsHTML($items);
+    $html [] = $this->_renderSameWorkItemsHTML($same_work);
+    return array_filter($html);
   }
+
+
+  abstract public function renderItems(array $items,
+                                       array $same_work,
+                                       array $html) : array;
+
+
+  abstract protected function _getItemWrapper() : string;
+
+
+  abstract protected function _getOsmItemWrapper() : string;
 }
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyMap extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    $html [] = $this->_renderMapHTML($items, $same_work);
+    $html [] = $this->_renderItemsHTML($items);
+    $html [] = $this->_renderSameWorkItemsHTML($same_work);
+    return array_filter($html);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemWithoutSIGB::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsmWithoutSIGB::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyPagination extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    $html [] = $this->_renderItemsHTML($items);
+    $html [] = $this->_renderSameWorkItemsHTML($same_work);
+    return array_filter($html);
+  }
+
+
+  protected function _renderItemsHTMLInner(array $items) : string {
+    return $this->_renderPaginatedItemsHTML($items);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemWithoutSIGB::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsmWithoutSIGB::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyILS extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    $html [] = $this->_renderItemsHTML($items);
+    $html [] = $this->_renderSameWorkItemsHTML($same_work);
+    return array_filter($html);
+  }
+
+
+  protected function _sortByAvailability(array $items) : array {
+    return $this->_sortByILSAvailability($items);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_Item::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsm::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyILSAndPagination extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    $html [] = $this->_renderItemsHTML($items);
+    $html [] = $this->_renderSameWorkItemsHTML($same_work);
+    return array_filter($html);
+  }
+
+
+  protected function _sortByAvailability(array $items) : array {
+    return $this->_sortByILSAvailability($items);
+  }
+
+
+  protected function _renderItemsHTMLInner(array $items) : string {
+    return $this->_renderPaginatedItemsHTML($items);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_Item::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsm::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyMapAndILSAndPagination extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    return $this->_renderMapAndItemsPaginated($items, $same_work, $html);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_Item::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsm::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyMapAndPagination extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    return $this->_renderMapAndItemsPaginated($items, $same_work, $html);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemWithoutSIGB::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsmWithoutSIGB::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyNoMapNoILSNoPagination extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    return $this->_itemsWithoutMap($items, $same_work, $html);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemWithoutSIGB::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsmWithoutSIGB::class;
+  }
+}
+
+
+
+
+class Intonation_View_RenderRecord_RenderItemsStrategyMapAndILS extends
+  Intonation_View_RenderRecord_RenderItemsStrategy {
+
+
+  public function renderItems(array $items, array $same_work, array $html) : array {
+    return $this->_itemsWithMap($items, $same_work, $html);
+  }
+
+
+  protected function _getItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_Item::class;
+  }
+
+
+  protected function _getOsmItemWrapper() : string {
+    return Intonation_Library_View_Wrapper_ItemForOsm::class;
+  }
+}
\ No newline at end of file
diff --git a/public/opac/js/ajaxifyPaginatedList/ajaxifyPaginatedList.js b/public/opac/js/ajaxifyPaginatedList/ajaxifyPaginatedList.js
index 76d77e0d5ec9573950ed5c9a6809661d83aa9d08..0089b3aedaeb47b5c0cc6008bc32f0a5f5934b04 100644
--- a/public/opac/js/ajaxifyPaginatedList/ajaxifyPaginatedList.js
+++ b/public/opac/js/ajaxifyPaginatedList/ajaxifyPaginatedList.js
@@ -51,10 +51,14 @@
       
       if (undefined != $.fn.masonry)
 	widget.masonry();
-      
+
+      widget.ajaxifyPaginatedList();
+
+      if (undefined != $.fn.openStreetMap)
+	widget.openStreetMap();
+   
       initializePopups();
       setupAnchorsTarget();
-      widget.ajaxifyPaginatedList();
     };
 
     var links = widget.find("a.ajax_anchor"); 
diff --git a/tests/scenarios/Templates/ChiliItemsTest.php b/tests/scenarios/Templates/ChiliItemsTest.php
index f1eb90605f5862379e5786d76eed73e7acee589c..64b3934346844c54a01ce2b7ede000bf08d791bc 100644
--- a/tests/scenarios/Templates/ChiliItemsTest.php
+++ b/tests/scenarios/Templates/ChiliItemsTest.php
@@ -84,36 +84,41 @@ class ChiliItemsDispatchTest extends AbstractControllerTestCase {
 
   /** @test */
   public function sameWorkItemsTitleShouldBeDisplay() {
-    $this->assertXPathContentContains('//div[contains(@class, "same_work_items")]/h3',
-                                      utf8_encode('Exemplaires de la même œuvre'));
+    $this->assertXPathContentContains('//div[@class="same_work_items col-12 mt-3"]/h3',
+                                      utf8_encode('Exemplaires de la même œuvre'),
+                                      $this->_response->getBody());
   }
 
 
   /** @test */
   public function itemsMasonryIdShouldBeFirstUniqid() {
-    $this->assertXPath('//div[contains(@class, "items_wall")]'
-                       . '//div[@id="' . $this->_uniqids[0] . '"][@class="masonry"]');
+    $this->assertXPath('//div[@class="items_wall col-12"]'
+                       . '//div[@id="' . $this->_uniqids[0] . '"][@class="masonry"]',
+                       $this->_response->getBody());
   }
 
 
   /** @test */
   public function shouldContainsScriptToCallMasonryOnFirstUniqid() {
-    $this->assertContains('setTimeout(function(){$("#' . $this->_uniqids[0] . '").parent().masonry();}',
-                          $this->_response->getBody());
+    $this->assertXPathContentContains('//head//script',
+                                      'setTimeout(function(){$("#'
+                                      . $this->_uniqids[0] . '").parent().masonry();}');
   }
 
 
   /** @test */
   public function sameWorkMasonryIdShouldBeSecondUniqid() {
-    $this->assertXPath('//div[contains(@class, "same_work_items")]'
+    $this->assertXPath('//div[@class="same_work_items col-12 mt-3"]'
+                       . '//div[@class="same_work_items_collection col-12"]'
                        . '//div[@id="' . $this->_uniqids[1] . '"][@class="masonry"]');
   }
 
 
   /** @test */
   public function shouldContainsScriptToCallMasonryOnSecondUniqid() {
-    $this->assertContains('setTimeout(function(){$("#' . $this->_uniqids[1] . '").parent().masonry();}',
-                          $this->_response->getBody());
+    $this->assertXPathContentContains('//head//script',
+                                      'setTimeout(function(){$("#'
+                                      . $this->_uniqids[1] . '").parent().masonry();}');
   }
 }
 
diff --git a/tests/scenarios/Templates/TemplatesAbonneTest.php b/tests/scenarios/Templates/TemplatesAbonneTest.php
index 812e585f9a981bb3e16b5a8e6dbdb23c1e02cae5..400c6c83cb2e116c745db8bc28c2d669fd624ad5 100644
--- a/tests/scenarios/Templates/TemplatesAbonneTest.php
+++ b/tests/scenarios/Templates/TemplatesAbonneTest.php
@@ -296,36 +296,58 @@ class TemplatesDispatchAbonneLoansTest extends TemplatesIntonationAccountTestCas
 
 
 
-class TemplatesDispatchAbonneLoansPaginatedTest extends TemplatesIntonationAccountTestCase {
-  /** @test */
-  public function page2ShouldContainsSearchInputWithMd5Key() {
+abstract class TemplatesAbonnePaginatedCollectionsTestCase extends TemplatesIntonationAccountTestCase {
+
+
+  public function setUp() {
+    parent::setUp();
+
     Storm_Cache::beVolatile();
-    $cards = new Class_User_Cards(Class_Users::getIdentity());
-    $loans = $cards->getLoansWithOutPNB([]);
-    $loans = array_map(function($loan)
-                       {
-                         return (new Intonation_Library_View_Wrapper_Loan)
-                           ->setModel($loan)
-                           ->setView($this->view);
-                       }, $loans->getArrayCopy());
+    $this->_dispatch(((new Intonation_Library_PaginatedCollectionHelper)
+                      ->setCollection(new Storm_Collection($this->_getModels()))));
+  }
+
+
+  protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
+    $this->dispatch('/opac/index/ajax-paginated-list/page/2/id/' . $helper->getId());
+  }
+
+
+  abstract protected function _getModels() : array ;
+}
+
+
 
-    $collection = new Storm_Collection($loans);
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
-      ->setCollection($collection)
-      ->setRendering('cardifyHorizontal');
+class TemplatesAbonnePaginatedLoansPage2Test extends TemplatesAbonnePaginatedCollectionsTestCase {
 
-    $id = $helper->getId();
 
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $id . '/page/2/render/ajax/id_profil/72');
-    $this->assertContains('input_ba399369f4582ca10ca7b1651defce91', $this->_response->getBody());
+  protected function _getModels() : array {
+    $cards = new Class_User_Cards(Class_Users::getIdentity());
+    $loans = $cards->getLoansWithOutPNB([]);
+    return array_map(function($loan)
+                     {
+                       return (new Intonation_Library_View_Wrapper_Loan)
+                         ->setModel($loan)
+                         ->setView($this->view);
+                     }, $loans->getArrayCopy());
   }
 
 
   /** @test */
-  public function page2ReviewsShouldContainsSearchInputWithMd5Key() {
-    Storm_Cache::beVolatile();
-    $this->fixture('Class_AvisNotice',
+  public function shouldContainsSearchInputWithIdInputBa399369f4582ca10ca7b1651defce91() {
+    $this->assertXPath('//div//form//input[@id="input_ba399369f4582ca10ca7b1651defce91"]');
+  }
+}
+
+
+
+
+class TemplatesAbonnePaginatedReviewsPage2Test extends TemplatesAbonnePaginatedCollectionsTestCase {
+
+
+  protected function _getModels() : array {
+    $this->fixture(Class_AvisNotice::class,
                    ['id' => 4,
                     'id_user' => 666,
                     'id_notice' => 2,
@@ -335,8 +357,7 @@ class TemplatesDispatchAbonneLoansPaginatedTest extends TemplatesIntonationAccou
                     'avis' => 'Le Roi des cons sur son throne',
                     'source_author' => null]);
 
-
-    $this->fixture('Class_AvisNotice',
+    $this->fixture(Class_AvisNotice::class,
                    ['id' => 5,
                     'id_user' => 666,
                     'id_notice' => 3,
@@ -346,98 +367,133 @@ class TemplatesDispatchAbonneLoansPaginatedTest extends TemplatesIntonationAccou
                     'avis' => 'Le Roi des cons avec sa couronne',
                     'source_author' => null]);
 
-    $this->fixture('Class_Notice',
+    $this->fixture(Class_Notice::class,
                    ['id' => 2,
-                    'clef_oeuvre' => 'PSYKO',
-                   ]);
+                    'clef_oeuvre' => 'PSYKO']);
 
-    $this->fixture('Class_Notice',
+    $this->fixture(Class_Notice::class,
                    ['id' => 3,
-                    'clef_oeuvre' => 'PSYKOTIC',
-                   ]);
+                    'clef_oeuvre' => 'PSYKOTIC']);
 
-
-    $reviews = Class_AvisNotice::groupByRecords(Class_AvisNotice::findAll());
-    $reviews = array_map(function($review)
+    return array_map(function($review)
                          {
                            return (new Intonation_Library_View_Wrapper_ReviewsByRecord)
                              ->setModel($review)
                              ->setView($this->view);
-                         }, $reviews);
+                         }, Class_AvisNotice::groupByRecords(Class_AvisNotice::findAll()));
+  }
 
-    $collection = new Storm_Collection($reviews);
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
-      ->setCollection($collection)
-      ->setRendering('cardifyHorizontal');
+  protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
+    $this->dispatch('/opac/index/ajax-paginated-list/page/2/size/1/search/roi/id/'
+                    . $helper->getId());
+  }
 
-    $id = $helper->getId();
 
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $id . '/page/2/render/ajax/id_profil/72/size/1/search/roi');
-    $this->assertContains('input_db436b32a1026df5398c4c8e32b1c51b', $this->_response->getBody());
-    $this->assertContains('avec sa couronne', $this->_response->getBody());
+  /** @test */
+  public function shouldContainsSearchInputWithIdInputD751713988987e9331980363e24189ce() {
+    $this->assertXPath('//div//input[@id="input_db436b32a1026df5398c4c8e32b1c51b"]');
   }
 
 
   /** @test */
-  public function loansShouldContainsDrHouseWithAllowExtendsAndReturnLoan() {
-    Storm_Cache::beVolatile();
+  public function pageSizeSelectedShouldEqualToSizeUrlParam() {
+    $this->assertXPath('//div//form//select/option[@label="1"][@value=1][@selected]');
+  }
 
-    $cards = new Class_User_Cards(Class_Users::getIdentity());
 
+  /** @test */
+  public function inputSearchShouldHaveValueEqualToSearchUrlParam() {
+    $this->assertXPath('//div//form//input[contains(@class, "ajax_search")][@value="roi"]');
+  }
+
+
+  /** @test */
+  public function shouldContainsReviewWithContentAvecSaCouronne() {
+    $this->assertXPathContentContains('//div[contains(@class, "list-group-item")]//div[contains(@class, "card_body")]//p', 'avec sa couronne');
+  }
+
+
+  /** @test */
+  public function defaultRenderingShouldBeList() {
+    $this->assertXPath('//div[@class="list-group bg-transparent no_border"]');
+  }
+
+
+  /** @test */
+  public function defaultLayoutShouldBeCardHorizontal() {
+    $this->assertXPath('//div[@class="list-group bg-transparent no_border"]//div[@class="cardify_horizontal_img col-12 col-sm-3 px-3 px-sm-0"]');
+  }
+}
+
+
+
+
+class TemplatesAbonnePaginatedLoansPage1AndSearchTest extends TemplatesAbonnePaginatedCollectionsTestCase {
+
+
+  protected function _getModels() : array {
+    $cards = new Class_User_Cards(Class_Users::getIdentity());
     $loans = $cards->getPNBLoans([]);
+    return array_map(function($loan)
+                     {
+                       return (new Intonation_Library_View_Wrapper_PNBLoan)
+                         ->setModel($loan)
+                         ->setView($this->view);
+                     }, $loans->getArrayCopy());
+  }
 
-    $loans = array_map(function($loan)
-                       {
-                         return (new Intonation_Library_View_Wrapper_PNBLoan)
-                           ->setModel($loan)
-                           ->setView($this->view);
-                       }, $loans->getArrayCopy());
 
-    $collection = new Storm_Collection($loans);
+  protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
+    $this->dispatch('/opac/index/ajax-paginated-list/page/1/search/house/size/10/id/' . $helper->getId());
+  }
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
-      ->setCollection($collection)
-      ->setRendering('cardifyHorizontal');
 
+  /** @test */
+  public function loanTitleShouldBeAnAnchorToViewnoticeWithDrHouse() {
+    $this->assertXPathContentContains('//div[@class="card-title card_title card_title_Intonation_Library_View_Wrapper_PNBLoan"]/a[@href= "/recherche/viewnotice/clef/DRHOUSE------101/id/20091/page/1"]',
+                                      'Dr House');
+  }
 
-    $id = $helper->getId();
 
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $id . '/page/1/id_profil/72/search/house/size/10');
-    $this->assertXPathContentContains('//div//a', 'Dr House');
-    $this->assertXPathContentContains('//div//a[contains(@href, "/bib-numerique/return-pnb-loan/id/ec2c17cefacacad7f25f875ae87956c1/page/1/id_profil/72/search/house/size/10/loan_id/666_3")]', 'Retour anticip', $this->_response->getBody());
-    $this->assertXPathContentContains('//div//a[contains(@href, "/bib-numerique/extends-pnb-loan/id/ec2c17cefacacad7f25f875ae87956c1/page/1/id_profil/72/search/house/size/10/loan_id/666_3")]', 'Prolonger');
+  /** @test */
+  public function linkToReturnPnbLoanShouldBePresent() {
+    $this->assertXPathContentContains('//div[@class="card_action col col-sm-12 p-1 m-1"]/a[@href= "/bib-numerique/return-pnb-loan/page/1/search/house/size/10/id/ec2c17cefacacad7f25f875ae87956c1/loan_id/666_3"]',
+                                      utf8_encode('Retour anticipé'));
   }
 
 
   /** @test */
-  public function loansListShouldCountShouldBeNoElement() {
-    Storm_Cache::beVolatile();
+  public function linkToExtendPnbLoanShouldBePresent() {
+    $this->assertXPathContentContains('//div[@class="card_action col col-sm-12 p-1 m-1"]/a[contains(@href, "/bib-numerique/extends-pnb-loan/page/1/search/house/size/10/id/ec2c17cefacacad7f25f875ae87956c1/loan_id/666_3")]',
+                                      'Prolonger');
+  }
+}
 
-    $cards = new Class_User_Cards(Class_Users::getIdentity());
 
-    $loans = $cards->getPNBLoans([]);
 
-    $loans = array_map(function($loan)
-                       {
-                         return (new Intonation_Library_View_Wrapper_PNBLoan)
-                           ->setModel($loan)
-                           ->setView($this->view);
-                       }, $loans->getArrayCopy());
 
-    $collection = new Storm_Collection($loans);
+class TemplateAbonnePaginatedCollectionWithNoResultTest extends TemplatesAbonnePaginatedLoansPage2Test {
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
-      ->setCollection($collection)
-      ->setRendering('cardifyHorizontal');
 
+  protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
+    $this->dispatch('/opac/index/ajax-paginated-list/size/1/page/1/search/no+data/id/'
+                    . $helper->getId());
+  }
 
-    $id = $helper->getId();
 
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $id . '/page/1/id_profil/72/search/no+data/size/1');
-    $this->assertXPathContentContains('//div[@class="truncate_list_size_wrapper col-12 col-sm-3"]//span[@class="truncate_list_size btn btn-sm btn-info"]',
+  /** @test */
+  public function noElementMessageShouldBePresentInSizeToolbar() {
+    $this->assertXPathContentContains('//div[@class="truncate_list_size_wrapper col-12 col-sm-3"]/span[@class="truncate_list_size btn btn-sm btn-info"]',
                                       utf8_encode('Pas d\'élément'));
   }
+
+
+  /** @test */
+  public function noElementMessageShouldBePresentInCollectionContent() {
+    $this->assertXPathContentContains('//div[@class="paginated_collection col-12 mt-3 list-group bg-transparent no_border"]/p[@class="empty_list_message text-warning px-4"]',
+                                      'Aucun document');
+  }
 }
 
 
@@ -1927,101 +1983,51 @@ class TemplatesAbonneCacheSuggestionsTest extends TemplatesAbonneCacheTestCase {
 
 
 
-class TemplatesAbonneSearchAjaxInReview extends TemplatesIntonationAccountTestCase {
-  protected $_storm_default_to_volatile = true,
-    $_id;
+class TemplatesAbonnePaginatedReviewsSearchConsRoiTest extends TemplatesAbonnePaginatedReviewsPage2Test {
 
 
-  public function setUp() {
-    parent::setUp();
-    Storm_Cache::beVolatile();
-    $this->fixture('Class_AvisNotice',
-                   ['id' => 4,
-                    'id_user' => 666,
-                    'id_notice' => 2,
-                    'clef_oeuvre' => 'PSYKO',
-                    'note' => '4',
-                    'entete' => 'Le Roi',
-                    'avis' => 'Le Roi des cons sur son throne',
-                    'source_author' => null]);
-
-    $this->fixture('Class_AvisNotice',
-                   ['id' => 5,
-                    'id_user' => 666,
-                    'id_notice' => 3,
-                    'clef_oeuvre' => 'PSYKO',
-                    'note' => '4',
-                    'entete' => 'Le Roi des cons avec sa couronne',
-                    'avis' => 'Le Roi des cons avec sa couronne',
-                    'source_author' => null]);
-
-    $this->fixture('Class_AvisNotice',
-                   ['id' => 6,
-                    'id_user' => 666,
-                    'id_notice' => 3,
-                    'clef_oeuvre' => 'PSYKO',
-                    'note' => '4',
-                    'entete' => 'les cons avec sa couronne',
-                    'avis' => 'les cons avec sa couronne',
-                    'source_author' => null]);
-
-    $this->fixture('Class_Notice',
-                   ['id' => 2,
-                    'clef_oeuvre' => 'PSYKO',
-                   ]);
-
-    $this->fixture('Class_Notice',
-                   ['id' => 3,
-                    'clef_oeuvre' => 'PSYKOTIC',
-                   ]);
-
-    $reviews = Class_AvisNotice::groupByRecords(Class_AvisNotice::findAll());
-    $reviews = array_map(function($review)
-    {
-      return (new Intonation_Library_View_Wrapper_ReviewsByRecord)
-        ->setModel($review)
-        ->setView($this->view);
-    }, $reviews);
+  protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
+    $this->dispatch('/opac/index/ajax-paginated-list/page/1/render/ajax/size/3/search/cons+roi/id/' . $helper->getId());
+  }
 
 
-    $collection = new Storm_Collection($reviews);
+  /** @test */
+  public function pageSizeSelectedShouldEqualToSizeUrlParam() {
+    $this->assertXPath('//div//form//select/option[@label="3"][@value=3][@selected]');
+  }
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
-      ->setCollection($collection)
-      ->setRendering('cardifyHorizontal');
 
-    $this->_id = $helper->getId();
+  /** @test */
+  public function inputSearchShouldHaveValueEqualToSearchUrlParam() {
+    $this->assertXPath('//div//form//input[contains(@class, "ajax_search")][@value="cons roi"]');
   }
 
 
   /** @test */
   public function searchTermConRoiShouldReturn2Reviews() {
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $this->_id . '/page/1/render/ajax/id_profil/72/size/3/search/cons+roi');
     $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 2);
   }
 
 
   /** @test */
   public function nextAnchorUrlShouldContainsSearchTermConsRoi() {
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $this->_id . '/page/1/render/ajax/id_profil/72/size/3/search/cons+roi');
     $this->assertXPath('//a[contains(@class, "next_ajax_anchor")][contains(@href, "/search/cons+roi")]');
   }
+}
 
 
-  /** @test */
-  public function searchTermConRoiShouldReturnReviewAtPageTwo() {
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $this->_id . '/page/2/render/ajax/id_profil/72/size/1/search/cons+roi');
 
-    $this->assertXPathContentContains('//div','avec sa couronne', $this->_response->getBody());
-  }
 
+class TemplatesAbonnePaginatedReviewsSearchConsRoiPage2Test extends TemplatesAbonnePaginatedReviewsPage2Test {
 
-  /** @test */
-  public function searchInputShouldBePresentWithExpectedHash() {
-    $this->dispatch('/opac/index/ajax-paginated-list/id/' . $this->_id . '/page/2/render/ajax/id_profil/72/size/1/search/cons+roi');
 
-    $this->assertContains('input_7e2bd926b5277b4a85b9bb18b72a431a', $this->_response->getBody());
-    $this->assertContains('avec sa couronne', $this->_response->getBody());
+  protected function _dispatch(Intonation_Library_PaginatedCollectionHelper $helper) {
+    $this->dispatch('/opac/index/ajax-paginated-list/page/2/render/ajax/size/1/search/cons+roi/id/' . $helper->getId());
+  }
+
 
+  /** @test */
+  public function inputSearchShouldHaveValueEqualToSearchUrlParam() {
+    $this->assertXPath('//input[@value="cons roi"]');
   }
 }
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesAjaxPaginatedListTest.php b/tests/scenarios/Templates/TemplatesAjaxPaginatedListTest.php
index efb30c0fdaaf55774105e44557efedd14905a044..da538c5547ecd18ecea5a2ce59c81c4a9482015a 100644
--- a/tests/scenarios/Templates/TemplatesAjaxPaginatedListTest.php
+++ b/tests/scenarios/Templates/TemplatesAjaxPaginatedListTest.php
@@ -71,9 +71,8 @@ abstract class TemplatesAjaxPaginatedListTestCase extends AbstractControllerTest
     $this->_view_renderer = new ZendAfi_Controller_Action_Helper_ViewRenderer;
     $this->_view_renderer->preDispatch();
 
-    $this->_ajax_paginated_list_helper = (new Intonation_Library_AjaxPaginatedListHelper)
-      ->setCollection($this->_getCollection())
-      ->setRendering('cardifyHorizontal');
+    $this->_ajax_paginated_list_helper = (new Intonation_Library_PaginatedCollectionHelper)
+      ->setCollection($this->_getCollection());
 
     $this->_ajax_paginated_list_helper_id = $this->_ajax_paginated_list_helper->getId();
 
@@ -331,7 +330,7 @@ class TemplatesAjaxPaginatedListWithLoanTest extends TemplatesAjaxPaginatedListT
     $data = $this->_ajax_paginated_list_helper->getDataToCache();
     $serialized = serialize($data);
     $size = mb_strlen($serialized);
-    $this->assertTrue(2048 > $size);
+    $this->assertTrue(2248 > $size);
   }
 }
 
@@ -605,7 +604,8 @@ class TemplatesAjaxPaginatedListWithRssItemTest extends TemplatesAjaxPaginatedLi
     $data = $this->_ajax_paginated_list_helper->getDataToCache();
     $serialized = serialize($data);
     $size = mb_strlen($serialized);
-    $this->assertTrue(1524 > $size);
+
+    $this->assertTrue(1600 > $size);
   }
 }
 
@@ -757,7 +757,7 @@ class TemplatesAjaxPaginatedListWithLotsOfRecordsTest extends TemplatesAjaxPagin
     $serialized = serialize($data);
     $size = mb_strlen($serialized);
 
-    $this->assertEquals('191,37 ko', number_format(($size / 1024), 2, ',', ' ') . ' ko');
+    $this->assertEquals('191,55 ko', number_format(($size / 1024), 2, ',', ' ') . ' ko');
   }
 
 
@@ -906,7 +906,7 @@ class TemplatesAjaxPaginatedListWithLoanAndSearchTest extends TemplatesAjaxPagin
     $data = $this->_ajax_paginated_list_helper->getDataToCache();
     $serialized = serialize($data);
     $size = mb_strlen($serialized);
-    $this->assertTrue(2048 > $size);
+    $this->assertTrue(2248 > $size);
   }
 }
 
@@ -926,11 +926,11 @@ class TemplatesAjaxPaginatedListWithSameCollectionIdsTest extends AbstractContro
     $items = [$this->fixture(Class_Exemplaire::class, ['id' => 1]),
                 $this->fixture(Class_Exemplaire::class, ['id' => 2])];
 
-    $key_1 = (new Intonation_Library_AjaxPaginatedListHelper)
+    $key_1 = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection($records))
       ->getId();
 
-    $key_2 = (new Intonation_Library_AjaxPaginatedListHelper)
+    $key_2 = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection($items))
       ->getId();
 
@@ -955,11 +955,11 @@ class TemplatesAjaxPaginatedListWithSameCollectionIdsTest extends AbstractContro
     $card_operation_decorator_1 = new Class_User_CardsOperationDecorator($loan_1, $user);
     $card_operation_decorator_2 = new Class_User_CardsOperationDecorator($loan_2, $user);
 
-    $key_1 = (new Intonation_Library_AjaxPaginatedListHelper)
+    $key_1 = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection([new Intonation_Library_View_Wrapper_Loan($card_operation_decorator_1)]))
       ->getId();
 
-    $key_2 = (new Intonation_Library_AjaxPaginatedListHelper)
+    $key_2 = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection([new Intonation_Library_View_Wrapper_Loan($card_operation_decorator_2)]))
       ->getId();
 
@@ -991,7 +991,7 @@ class TemplatesAjaxPaginatedListWithCustomPageSizeTest extends AbstractControlle
     $this->_view_renderer = new ZendAfi_Controller_Action_Helper_ViewRenderer;
     $this->_view_renderer->preDispatch();
 
-    $this->_ajax_paginated_list_helper = (new Intonation_Library_AjaxPaginatedListHelper)
+    $this->_ajax_paginated_list_helper = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection($this->_getCollection())
       ->setCustomPageSize(12)
       ->setRendering('cardifyHorizontal');
@@ -1025,4 +1025,66 @@ class TemplatesAjaxPaginatedListWithCustomPageSizeTest extends AbstractControlle
   public function ajaxSelectValue12ShouldBeAvailable() {
     $this->assertXPath('//div//select[contains(@id,"select_")]//option[@value="12"]');
   }
+}
+
+
+
+
+class TemplatesAjaxPaginatedWallTest extends AbstractControllerTestCase {
+
+
+  protected
+    $_storm_default_to_volatile = true,
+    $_view_renderer,
+    $_ajax_paginated_list_helper,
+    $_ajax_paginated_list_helper_id,
+    $_collection_cache;
+
+
+  public function setUp() {
+    parent::setUp();
+
+    Storm_Cache::beVolatile();
+
+    $this->_buildTemplateProfil(['id' => '34']);
+
+    $this->_view_renderer = new ZendAfi_Controller_Action_Helper_ViewRenderer;
+    $this->_view_renderer->preDispatch();
+
+    $this->_ajax_paginated_list_helper = (new Intonation_Library_PaginatedCollectionHelper)
+      ->setCollection($this->_getCollection())
+      ->setRendering('card-description')
+      ->setLayout('wall');
+
+    $this->_ajax_paginated_list_helper_id = $this->_ajax_paginated_list_helper->getId();
+
+    $this->dispatch('/opac/index/ajax-paginated-list/page/2/size/10/id/' . $this->_ajax_paginated_list_helper_id);
+  }
+
+
+  public function tearDown() {
+    Storm_Cache::setDefaultZendCache(null);
+    return parent::tearDown();
+  }
+
+
+  protected function _getCollection() : Storm_Collection {
+    $models = [];
+    for ($i = 1 ; $i <= 36 ; $i ++)
+      $models [] = $this->fixture(Class_Exemplaire::class,
+                                  ['id' => $i,
+                                   'id_notice' => 8908]);
+
+    $models =
+      array_map(fn($model) => new Intonation_Library_View_Wrapper_Item($model), $models);
+
+    return new Storm_Collection($models);
+  }
+
+
+  /** @test */
+  public function shouldDisplay10ItemsInWallHasCardDescription() {
+    $this->assertXPathCount('//div[@class="masonry"]//div[@class="masonry-brick"]//div[contains(@class, "card card_template")]//div[@class ="card-body card_body card_body_Intonation_Library_View_Wrapper_Item"]',
+                            10);
+  }
 }
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesItemsPaginatedTest.php b/tests/scenarios/Templates/TemplatesItemsPaginatedTest.php
index 2ab12995c84ecaf3ed01fa5594e28330187072b5..20528c6a0f7bf99e93997383830b4f8482bf80e3 100644
--- a/tests/scenarios/Templates/TemplatesItemsPaginatedTest.php
+++ b/tests/scenarios/Templates/TemplatesItemsPaginatedTest.php
@@ -95,7 +95,7 @@ abstract class TemplateItemsPaginatedTestCase  extends AbstractControllerTestCas
 
   /** @test */
   public function shouldOnlyDisplay10Items() {
-    $this->assertXPathCount('//div[contains(@class,"list-group-item")]', 10);
+    $this->assertXPathCount('//div[contains(@class,"masonry-brick")]', 10);
   }
 
 
diff --git a/tests/scenarios/Templates/TemplatesRssTest.php b/tests/scenarios/Templates/TemplatesRssTest.php
index 9561c70cc123105114c7a12c8c7498927610d91f..00d0c9e62f69d6e22db0be61e3b2e160929d36ca 100644
--- a/tests/scenarios/Templates/TemplatesRssTest.php
+++ b/tests/scenarios/Templates/TemplatesRssTest.php
@@ -144,35 +144,20 @@ class TemplatesRssWidgetWithPaginatedListTest extends AbstractControllerTestCase
   public function setUp() {
     parent::setUp();
 
-    Class_WebService_Abstract::setHttpClient($this
-                                             ->mock()
-                                             ->whenCalled('open_url')
-                                             ->with('https://rss.lemonde.fr/c/205/f/3050/index.rss')
-                                             ->answers(RssFixtures::lemondeRSS())
-                                             ->beStrict());
-
-
     Storm_Cache::beVolatile();
 
-    $profile = $this->_buildTemplateProfil(['id' => 2890,
-                                            'template' => 'MUSCLE']);
+    $http_client_mock = $this
+      ->mock()
+      ->whenCalled('open_url')->with('https://rss.lemonde.fr/c/205/f/3050/index.rss')
+      ->answers(RssFixtures::lemondeRSS())
+      ->beStrict();
 
-    $params = ['rendering' => 'card',
-               'order' => Class_CriteresRecherche::SORT_RANDOM,
-               'layout' => Intonation_Library_Widget_Carousel_Definition::LISTING_WITH_OPTIONS];
+    Class_WebService_Abstract::setHttpClient($http_client_mock);
 
-    $profile_patcher = (new Class_Template_ProfilePatcher(null))
-      ->setProfile($profile)
-      ->addWidget(Intonation_Library_Widget_Carousel_Record_Definition::CODE,
-                  Class_Profil::DIV_MAIN,
-                  $params);
-
-    $widget = (new Class_Systeme_Widget_Widget())
-      ->setId(1)
-      ->setProfileId(2890)
-      ->load();
+   $profile = $this->_buildTemplateProfil(['id' => 2890,
+                                            'template' => 'MUSCLE']);
 
-    $rss = $this->fixture('Class_Rss',
+    $rss = $this->fixture(Class_Rss::class,
                           ['id' => 1,
                            'titre' => 'Flux RSS lemonde',
                            'url' => 'https://rss.lemonde.fr/c/205/f/3050/index.rss',
@@ -181,16 +166,15 @@ class TemplatesRssWidgetWithPaginatedListTest extends AbstractControllerTestCase
 
     $rss_items = $rss->getFeedItems();
 
-    $rss_items = array_map(function($element)
-                       {
-                         return
-                           new Intonation_Library_View_Wrapper_RssItem($element,
-                                                                       $this->mock()
-                                                                       ->whenCalled('renderBadges')
-                                                                       ->answers(''));
-                       }, $rss_items);
+    $rss_items =
+      array_map(fn($element) =>
+                new Intonation_Library_View_Wrapper_RssItem($element,
+                                                            $this->mock()
+                                                            ->whenCalled('renderBadges')
+                                                            ->answers('')),
+                $rss_items);
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
+    $helper = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection($rss_items));
 
     $id = $helper->getId();
diff --git a/tests/scenarios/Templates/TemplatesSearchItemsTest.php b/tests/scenarios/Templates/TemplatesSearchItemsTest.php
index 225003d66c9f0045ce20cd2eb479b7175b3d2f21..e94de22d4259cb6f694cfe7eb48a3321c932ff1b 100644
--- a/tests/scenarios/Templates/TemplatesSearchItemsTest.php
+++ b/tests/scenarios/Templates/TemplatesSearchItemsTest.php
@@ -291,8 +291,8 @@ class TemplatesSearchItems15ItemsPaginationThreshold5AndAvailabilityKohaLimit9Te
 
 
   /** @test */
-  public function shouldDisplay5Items() {
-    $this->assertXPathCount('//div[contains(@class,"card-title card_title")]',
+  public function shouldDisplay5ItemsInWallHasCardDescription() {
+    $this->assertXPathCount('//div[@class="masonry"]//div[@class="masonry-brick"]//div[contains(@class, "card card_template")]//div[contains(@class,"card-title card_title")]',
                             5);
   }
 
@@ -905,3 +905,196 @@ class TemplatesSearchItemsWithoutILSDITest extends TemplatesSearchItemsKohaThres
     $this->assertNotXPath('//span[contains(@class, "item_hold_rank")]');
   }
 }
+
+
+
+
+class TemplatesSearchItems15ItemsPaginationThreshold12AndAvailabilityKohaLimit16AndMapTests
+  extends TemplatesSearchItemsKohaThresholdsTestCase {
+
+  protected
+    $_items_threshold = 12,
+    $_koha_threshold = 16,
+    $_number_of_items = 15,
+    $_items_map = 1;
+
+
+  protected function _setWebServiceKoha(){
+    $params = ['url_serveur' => 'https://monsuperkoha.org',
+               'restful' => '1',
+               'disable_items_availability_threshold' => $this->_koha_threshold,
+               'id_bib' => 10,
+               'type' => Class_IntBib::COM_KOHA];
+
+    $service = Class_WebService_SIGB_Koha::getService($params);
+
+    $this->fixture(Class_IntBib::class,
+                   ['id' => 10,
+                    'comm_sigb' => Class_IntBib::COM_KOHA,
+                    'comm_params' => $params]);
+
+
+    $mock_web_client = $this
+      ->mock()
+      ->whenCalled('open_url')
+      ->answers('');
+
+    $service->setWebClient($mock_web_client);
+  }
+
+
+  /** @test */
+  public function shouldContainsPage2() {
+    $this->assertXPath('//a[contains(@href,"page/2")]');
+  }
+
+
+  /** @test */
+  public function shouldDisplay12Items() {
+    $this->assertXPathCount('//div[@class="card-title card_title card_title_Intonation_Library_View_Wrapper_Item"]',
+                            12);
+  }
+
+
+  /** @test */
+  public function ajaxSelectValueSelectedShouldBeTwelve() {
+    $this->assertXPath('//div//select[contains(@id,"select_")]//option[@value="12"][@selected]');
+  }
+
+
+  /** @test */
+  public function mapShouldBePresent() {
+    $this->assertXPath('//div[@class="container-fluid"]//div[contains(@class,"row no-gutters")]//div[@data-osm]');
+  }
+}
+
+
+
+
+class TemplatesSearchItems15ItemsPaginationThreshold12AndAvailabilityKohaLimit1AndMapTests
+  extends TemplatesSearchItemsKohaThresholdsTestCase {
+
+  protected
+    $_items_threshold = 12,
+    $_koha_threshold = 1,
+    $_number_of_items = 15,
+    $_items_map = 1;
+
+
+  protected function _setWebServiceKoha(){
+    $params = ['url_serveur' => 'https://monsuperkoha.org',
+               'restful' => '1',
+               'disable_items_availability_threshold' => $this->_koha_threshold,
+               'id_bib' => 10,
+               'type' => Class_IntBib::COM_KOHA];
+
+    $service = Class_WebService_SIGB_Koha::getService($params);
+
+    $this->fixture(Class_IntBib::class,
+                   ['id' => 10,
+                    'comm_sigb' => Class_IntBib::COM_KOHA,
+                    'comm_params' => $params]);
+
+
+    $mock_web_client = $this
+      ->mock()
+      ->whenCalled('open_url')
+      ->answers('');
+
+    $service->setWebClient($mock_web_client);
+  }
+
+
+  /** @test */
+  public function shouldContainsPage2() {
+    $this->assertXPath('//a[contains(@href,"page/2")]');
+  }
+
+
+  /** @test */
+  public function shouldDisplay12ItemsWithouILS() {
+    $this->assertXPathCount('//div[@class="card-title card_title card_title_Intonation_Library_View_Wrapper_ItemWithoutSIGB"]',
+                            12);
+  }
+
+
+  /** @test */
+  public function ajaxSelectValueSelectedShouldBeTwelve() {
+    $this->assertXPath('//div//select[contains(@id,"select_")]//option[@value="12"][@selected]');
+  }
+
+
+  /** @test */
+  public function paginatedMasonryShouldBePresent() {
+    $this->assertXPath('//div[@class="container-fluid"]/div[@class="row no-gutters"]/div[@class="paginated_secondary_collection col-12 mt-3 list-group bg-transparent no_border"]/div[contains(@class, "masonry")]');
+  }
+
+
+  /** @test */
+  public function paginatedMapShouldPresent() {
+    $this->assertXPath('//div[@class="container-fluid"]/div[@class="row no-gutters"]/div[@class="paginated_collection col-12 mt-3 list-group bg-transparent no_border"]//div[@data-osm]');
+  }
+}
+
+
+
+
+
+class TemplatesSearchItems15ItemsPaginationThreshold20AndAvailabilityKohaLimit20AndMapTests
+  extends TemplatesSearchItemsKohaThresholdsTestCase {
+
+  protected
+    $_items_threshold = 20,
+    $_koha_threshold = 20,
+    $_number_of_items = 15,
+    $_items_map = 1;
+
+
+  protected function _setWebServiceKoha(){
+    $params = ['url_serveur' => 'https://monsuperkoha.org',
+               'restful' => '1',
+               'disable_items_availability_threshold' => $this->_koha_threshold,
+               'id_bib' => 10,
+               'type' => Class_IntBib::COM_KOHA];
+
+    $service = Class_WebService_SIGB_Koha::getService($params);
+
+    $this->fixture(Class_IntBib::class,
+                   ['id' => 10,
+                    'comm_sigb' => Class_IntBib::COM_KOHA,
+                    'comm_params' => $params]);
+
+
+    $mock_web_client = $this
+      ->mock()
+      ->whenCalled('open_url')
+      ->answers('');
+
+    $service->setWebClient($mock_web_client);
+  }
+
+
+  /** @test */
+  public function shouldNotContainsPage2() {
+    $this->assertNotXPath('//a[contains(@href,"page/2")]');
+  }
+
+
+  /** @test */
+  public function shouldDisplay15Items() {
+    $this->assertXPathCount('//div[@class="card-title card_title card_title_Intonation_Library_View_Wrapper_Item"]',
+                            15);
+  }
+
+
+  /** @test */
+  public function ajaxSelectShouldNotPresent() {
+    $this->assertNotXPath('//div//select[contains(@id,"select_")]');
+  }
+
+
+  /** @test */
+  public function mapShouldBePresent() {
+    $this->assertXPath('//div//div[contains(@class,"items_map")]');
+  }
+}
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesWebsitesTest.php b/tests/scenarios/Templates/TemplatesWebsitesTest.php
index 5f63027d340b57880f6cb9b8289670e7b8635dfd..c5fd83057375cc5e5d202500cf2b6e740457204b 100644
--- a/tests/scenarios/Templates/TemplatesWebsitesTest.php
+++ b/tests/scenarios/Templates/TemplatesWebsitesTest.php
@@ -425,7 +425,7 @@ class TemplatesWebsitesDispatchPaginatedTest extends TemplatesWebsitesFixturesTe
     foreach (Class_Sitotheque::getSitesCategorie(8) as $website)
       $melted_websites [] = new Intonation_Library_View_Wrapper_Website($smeltery->meltWebsite($website), $view_renderer->view);
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
+    $helper = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection($melted_websites))
       ->setRendering('cardifyHorizontal');
 
diff --git a/tests/scenarios/Templates/TemplatesWidgetTest.php b/tests/scenarios/Templates/TemplatesWidgetTest.php
index 3ac1b6077e866617d5363541ef4d1b3844da63ac..a45d52b6040a567a0071f938eee1a3b6655f182c 100644
--- a/tests/scenarios/Templates/TemplatesWidgetTest.php
+++ b/tests/scenarios/Templates/TemplatesWidgetTest.php
@@ -1646,7 +1646,7 @@ class TemplatesWidgetWithPaginatedListTest extends AbstractControllerTestCase {
       ->setView(new Zend_View([]))
       ->setTemplateContext($widget);
 
-    $helper = (new Intonation_Library_AjaxPaginatedListHelper)
+    $helper = (new Intonation_Library_PaginatedCollectionHelper)
       ->setCollection(new Storm_Collection($records))
       ->setCarouselContext($carousel_context)
       ->setRendering('cardifyHorizontal');