diff --git a/VERSIONS_WIP/59734 b/VERSIONS_WIP/59734
new file mode 100644
index 0000000000000000000000000000000000000000..79e8b903b4b8b4faa00fc97ee86c394eca2a92a7
--- /dev/null
+++ b/VERSIONS_WIP/59734
@@ -0,0 +1,2 @@
+ - ticket #59734 : Administration ;: migration des formulaires d'édition de profil et de page vers le mode onglet
+ 
\ No newline at end of file
diff --git a/application/modules/admin/controllers/ProfilController.php b/application/modules/admin/controllers/ProfilController.php
index c9fbbeec69fb5689133db5632ca2d6909e3fa51f..ab2ebd00a724aa6513cfa0cb748347121f305989 100644
--- a/application/modules/admin/controllers/ProfilController.php
+++ b/application/modules/admin/controllers/ProfilController.php
@@ -181,41 +181,34 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
   }
 
 
-  private function _parseSaveContentString($cfg_module) {
-    $enreg = ['modules' => []];
-    if(0 == count($cfg_module))
-      return $enreg;
+  protected function _parseSaveContentString() {
+    $modules = ['modules' => []];
     $profil = Class_Profil::find($this->id_profil);
-    // Decoupage des modules
-    $modules = array_filter(explode(';box',$cfg_module));
-    foreach ($modules as $module) {
-      $elem = explode('|', $module);
-      $division=substr($elem[0],-1);
+    for($division = 1; $division <= Class_Profil::DIV_FLOTANTTE; $division++)
+      $this->_divisionParser($profil, $division, $modules);
 
-      $id_module=$elem[1];
+    return $modules;
+  }
 
-      // permet de ne pas écraser un module existant,
-      // on réaffecte un id si c'est un nouveau module
-      if ($id_module == 'new') {
-        $id_module = $profil->createNewModuleAccueilId();
-      }
 
-      $type_module=$elem[2];
-      $str_preferences=trim($elem[3]);
+  protected function _divisionParser($profil, $division, &$modules) {
+    if(!$widgets = $this->_getParam('division' . $division))
+      return;
+
+    $widgets = array_filter(explode(';', $widgets));
+    foreach($widgets as $widget) {
+      list($type, $id) =  explode('-', $widget);
+      $params = $profil->getModulePref($id);
 
-      $preferences = array();
-      if(strlen($str_preferences) > 0) {
-        $props=explode(Class_Profil::PROPERTIES_DELIMITER, $str_preferences);
-        foreach($props as $prop) {
-          $names_vals=$this->_splitArg($prop);
-          $preferences[$names_vals[0]]=$names_vals[1];
-        }
+      if($id == 0) {
+        $id = $profil->createNewModuleAccueilId();
+        $params = $profil->getDefautBoite($type);
       }
-      $enreg["modules"][$id_module]=compact("division",
-                                            "type_module",
-                                            "preferences");
+
+      $modules['modules'][$id] = array_merge(['division' => $division,
+                                              'type_module' => $type,
+                                              'preferences' => $params]);
     }
-    return $enreg;
   }
 
 
@@ -262,15 +255,12 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
 
 
   protected function updateAccueil($profil) {
-    $profil->setLibelle($this->_getParam('libelle',
-                                         $profil->getLibelle()));
-
-    $cfg_module = urldecode($this->_getParam('saveContent'));
-    $enreg = $this->_parseSaveContentString($cfg_module);
-
+    $enreg = $this->_parseSaveContentString();
     $enreg["use_parent_css"] = $this->_getParam('use_parent_css', $profil->getUseParentCss());
     $enreg['sitemap'] = $this->_getParam('sitemap');
-    $enreg["page_css"]=$this->_getParam('page_css');
+    $enreg["page_css"] = $this->_getParam('page_css');
+
+    $profil->setLibelle($this->_getParam('libelle', $profil->getLibelle()));
     $profil->setRewriteUrl($this->_getParam('rewrite_url'));
 
     foreach($enreg["modules"] as $id_module => $module_config) {
@@ -342,100 +332,18 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
 
   public function accueilAction() {
     $this->view->titre = $this->_('Configuration de la page: ') . $this->_profil->getLibelle();
+    $params = array_merge($this->_profil->toArray(),
+                          $this->_profil->getCfgSiteAsArray(),
+                          $this->_profil->getCfgAccueilAsArray());
 
-    $profil = Class_Profil::find($this->id_profil);
+    $this->view->form = ZendAfi_Form_Configuration_Profile_Page::newWith($params);
+    $this->view->form->setAction($this->view->url());
 
-    $class_module = new Class_Systeme_ModulesAccueil();
-    $liste_module = $class_module->getModules();
-
-    if ($this->_request->isPost())
-      $this->updateAccueil($profil);
-
-    // Html des modules sélectionnés triés par divisions
-    $box = [1 => '',
-            2 => '',
-            3 => '',
-            4 => '',
-            5 => ''];
-
-    foreach($box as $division => $content)
-      $box[$division] = $this->_getHTMLForProfilModulesDivision($profil, $division);
-
-    $groupes = $class_module->getGroupes();
-    $box_dispo = [];
-
-    foreach($groupes as $groupe => $libelle) {
-      if (!array_key_exists($groupe, $box_dispo))
-        $box_dispo[$groupe] = '';
-      $box_dispo[$groupe].= '<div><p>'.$libelle.'</p><ul id="allItems" style="height:300px;">';
-    }
-
-    foreach($liste_module as $type_module => $module) {
-      if (!$module->isVisibleForProfil($profil))
-        continue;
-
-      $box_dispo[$module->getGroup()].= $this->_getItemModule($type_module,$module);
-    }
-
-    foreach($groupes as $groupe => $libelle)
-      $box_dispo[$groupe].='</ul></div>';
-
-    $this->view->nb_divisions = $profil->getNbDivisions();
-
-    $this->view->module_info = $box_dispo[Class_Systeme_ModulesAccueil::GROUP_INFO];
-    $this->view->module_rech = $box_dispo[Class_Systeme_ModulesAccueil::GROUP_RECH];
-    $this->view->module_site = $box_dispo[Class_Systeme_ModulesAccueil::GROUP_SITE];
-    $this->view->module_abonne = $box_dispo[Class_Systeme_ModulesAccueil::GROUP_ABONNE];
-    $this->view->box1 = $box[1];
-    $this->view->box2 = $box[2];
-    $this->view->box3 = $box[3];
-    $this->view->box4 = $box[4];
-    $this->view->box5 = $box[5];
-  }
-
-
-  protected function _getHTMLForProfilModulesDivision($profil, $division) {
-    $html = '';
-    $modules = $profil->getBoitesDivision($division);
-
-    foreach($modules as $id_module => $module)
-      $html .= $this->_getItemModule($module['type_module'],
-                                     Class_Systeme_ModulesAccueil::moduleByCode($module['type_module']),
-                                     $module['preferences'],
-                                     $id_module);
-    return $html;
+    if ($this->_request->isPost() && $this->view->form->isValid($this->_request->getPost()))
+      return $this->updateAccueil($this->_profil);
   }
 
 
-  protected function _getItemModule($type_module, $module, $preferences = '', $id_module = 0) {
-    $properties = [];
-    if ($preferences) {
-      foreach($preferences as $clef => $valeur)
-        $properties[] = $clef . "=" . $valeur;
-    }
-
-    $properties = urlencode(implode(Class_Profil::PROPERTIES_DELIMITER, $properties));
-
-    if($id_module)
-      $display="block";
-    else
-      $display="none";
-
-    $anchor = $this->view->tagAnchor($this->view->url(['module' => 'admin',
-                                                       'controller' => 'widget',
-                                                       'action' => 'edit-widget',
-                                                       'id' => $id_module,
-                                                       'id_profil' => $this->_getParam('id_profil')], null, true),
-      '<img src="'.URL_ADMIN_IMG.'ico/fonctions_admin.png" title="propriétés" style="display:'.$display.'" alt="Propriétés"/>',
-                                     ['data-popup' => 'true']);
-
-    $item='<li id="'.$type_module.'" id_module="'.$id_module.'" proprietes="'.$properties.'"><table width="97%"><tr>';
-    $item.='<td align="left" class="cfg_accueil">'.$module->getLibelle().'</td>';
-    $item.='<td align="right">' . $anchor . '</td>';
-    $item.='</tr></table></li>';
-    return $item;
-  }
-
 
   public function genresAction() {
     if ($this->_request->isPost())
@@ -460,6 +368,16 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
     $profil = Class_Profil::getLoader()->find(1)->copy();
     $profil->setHeaderCss('');
 
+    $params = array_merge($profil->toArray(),
+                          $profil->getCfgSiteAsArray());
+
+    $params['boite_recherche_simple_in_banniere'] = $profil->getBoiteRechercheSimpleInBanniere();
+    $params['boite_login_in_banniere'] = $profil->getBoiteLoginInBanniere();
+
+    $this->view->form = ZendAfi_Form_Configuration_Profile::newWith($params);
+    $this->view->form->setAction($this->view->url());
+
+
     if ($this->_postProfil($profil))
       $this->_redirect('admin/profil/edit/id_profil/'.$profil->getId());
 
@@ -473,6 +391,10 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
     if (!$this->_request->isPost())
       return false;
 
+    if(!$this->view->form->isValidModelAndArray($profil->updateAttributes($this->_request->getPost()),
+                                                $this->_request->getPost()))
+      return false;
+
     $post = ZendAfi_Filters_Post::filterStatic($this->_request->getPost());
     if ($result = $profil->updateAttributes($post)->save()) {
       Class_Profil::setCurrentProfil($profil);
@@ -485,12 +407,20 @@ class Admin_ProfilController extends ZendAfi_Controller_Action {
 
   public function editAction() {
     $profil = Class_Profil::find($this->id_profil);
+    $params = array_merge($profil->toArray(),
+                          $profil->getCfgSiteAsArray());
+
+    $params['boite_recherche_simple_in_banniere'] = $profil->getBoiteRechercheSimpleInBanniere();
+    $params['boite_login_in_banniere'] = $profil->getBoiteLoginInBanniere();
+
+    $this->view->form = ZendAfi_Form_Configuration_Profile::newWith($params);
+    $this->view->form->setAction($this->view->url());
+
     $this->_postProfil($profil);
 
-    // Action
     $this->view->profil = $profil;
     $this->view->action = 'edit';
-    $this->view->titre = 'Modifier le profil: '.$profil->getLibelle();
+    $this->view->titre = $this->view->_('Modifier le profil: %s', $profil->getLibelle());
   }
 
 
diff --git a/application/modules/admin/views/scripts/profil/_formProfil.phtml b/application/modules/admin/views/scripts/profil/_formProfil.phtml
index d48f3a0c2c55f1e883eac6fa92245a920bd9a28c..02d4a40204b095bb15204015e8ff1ca671bc28ba 100644
--- a/application/modules/admin/views/scripts/profil/_formProfil.phtml
+++ b/application/modules/admin/views/scripts/profil/_formProfil.phtml
@@ -1,478 +1,7 @@
 <?php
-Class_ScriptLoader::getInstance()
-->loadColorPicker()
-->addJqueryReady('
-$(".colorpicker").attachColorPicker();
-formSelectToggleVisibilityForElement("#browser", ".only_browser", "opac");
-checkBoxToggleVisibilityForElement("#barre_nav_on", $("#display_current_profil_on_breadcrumb").closest("tr"), true);
-toggleVisibilityForElement("#access_level", $("#login_page").closest("tr"), function(element) { return element.val() != "-1"; });
-checkBoxToggleVisibilityForElement("#header_img_cycle", "input[name=header_img]", false);
-');
+if(!$this->isPopup())
+  echo $this->partial('profil/_profil_panel.phtml',
+                      ['profil' => $this->profil]);
 
-echo $this->partial('profil/_profil_panel.phtml',
-                    ['profil' => $this->profil]); ?>
-
-<div class="form" align="center" >
-  <form name="form" action="<?php print(BASE_URL.'/admin/profil/'.$this->action.'/id_profil/'.$this->profil->getId()) ?>" method="post">
-
-    <fieldset>
-      <legend><?php echo $this->traduire('Profil'); ?> </legend>
-      <?php
-      if($this->profil->hasErrors())  {
-        echo '<ul class="errors">';
-        foreach($this->profil->getErrors() as $erreur)
-          echo '<li>'.$erreur.'</li>';
-        echo '</ul>';
-      }
-      ?>
-      <table>
-        <tr>
-          <td class="droite"><?php echo $this->traduire('Libelle'); ?></td>
-          <td class="gauche"><input type="text" name="libelle" style="width:100%" onkeypress="if (event.keyCode == 13) {javascript:PicToolbarOver( getElementById('menu_item975'), 'menu_item975');this.form.submit();return false;}" value="<?php echo $this->escape(trim($this->profil->getLibelle()));?>" maxlength="50"/></td>
-        </tr>
-
-        <tr>
-          <td align="right"><?php echo $this->traduire("Type d'interface"); ?></td>
-          <td class="gauche"><?php echo $this->formSelect('browser',
-                                                          $this->profil->getBrowser(),
-                                                          array("onchange" => "changeBrowser(this.value)"),
-                                                          array("opac" => "ordinateur",
-                                                                "telephone" => "téléphone")) ?></td>
-        </tr>
-
-
-        <tr>
-          <td align="right" style="width:20%"><?php echo $this->traduire("Niveau d'accès requis"); ?></td>
-          <td class="gauche"><?php echo $this->formSelect('access_level',
-                                                          $this->profil->getAccessLevel(),
-                                                          null,
-                                                          $this->profil->getAllAccessLevels()); ?></td>
-        </tr>
-
-        <tr>
-          <td align="right" style="width:20%"><?php echo $this->_("Page d'authentification"); ?></td>
-          <td class="gauche">
-            <?php
-
-            echo $this->getHelper('ComboProfils')
-                      ->setTagId('login_page')
-                      ->setTagName('login_page')
-                      ->addEmptyOption()
-                      ->comboProfils('ALL', 'ALL', $this->profil->getLoginPage())
-                      ;
-            ?>
-        </tr>
-
-        <tr>
-          <td class="droite"><?php echo $this->traduire('E-mail du Webmestre'); ?></td>
-          <td class="gauche"><input type="text" style="width:100%" name="mail_site" value="<?php echo $this->escape(trim($this->profil->getMailSite()));?>" maxlength="150"/></td>
-        </tr>
-
-        <tr>
-          <td class="droite"><?php echo $this->traduire('E-mail de réception des suggestions d\'achat'); ?></td>
-          <td class="gauche"><input type="text" style="width:100%" name="mail_suggestion_achat" value="<?php echo $this->escape(trim($this->profil->getMailSuggestionAchat()));?>" maxlength="150"/></td>
-        </tr>
-        <tr>
-          <td class="droite"><?php echo $this->traduire('URL du profil'); ?></td>
-          <td class="gauche"><input type="text" style="width:100%" name="rewrite_url" value="<?php echo $this->escape(trim($this->profil->getRewriteUrl()));?>" maxlength="150"/></td>
-        </tr>
-      </table>
-    </fieldset>
-
-    <fieldset>
-      <legend><?php echo $this->traduire('Bannière'); ?> </legend>
-      <table>
-        <tr>
-          <td align="right"><?php echo $this->traduire('Image de fond'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php
-              echo $this->coreFiveFileInput('header_img', $this->profil->getHeaderImg(), 'bannieres');
-            ?>
-          </td>
-        </tr>
-
-
-        <tr>
-          <td align="right"><?php echo $this->traduire('Défilement des images'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php
-              echo $this->formCheckbox(  'header_img_cycle',
-                                         null,
-                                         array('checked' => $this->profil->getHeaderImgCycle()));
-            ?>
-          </td>
-        </tr>
-
-        <tr>
-          <td align="right"><?php echo $this->traduire('Icône du navigateur'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php echo $this->coreFiveFileInput('favicon', $this->profil->getFavicon(), 'bannieres') ?>
-          </td>
-        </tr>
-
-
-        <tr>
-          <td align="right"><?php echo $this->traduire('Logo gauche'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php echo $this->coreFiveFileInput('logo_gauche_img', $this->profil->getLogoGaucheImg(), 'bannieres') ?>
-          </td>
-        </tr>
-
-
-        <tr>
-          <td align="right"><?php echo $this->traduire('Lien logo gauche'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <input type="text" class="normal" name="logo_gauche_link" size="50" value="<?php echo $this->profil->getLogoGaucheLink()?>">
-          </td>
-        </tr>
-
-
-        <tr>
-          <td align="right"><?php echo $this->traduire('Logo droite'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php echo $this->coreFiveFileInput('logo_droite_img', $this->profil->getLogoDroiteImg(), 'bannieres') ?>
-          </td>
-        </tr>
-
-
-        <tr>
-          <td align="right"><?php echo $this->traduire('Lien logo droite'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <input type="text" class="normal" name="logo_droite_link" size="50" value="<?php echo $this->profil->getLogoDroiteLink()?>">
-          </td>
-        </tr>
-
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Hauteur'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <input type="text" class="normal" id="hauteur_banniere" name="hauteur_banniere" size="3" maxlength="3" value="<?php echo $this->profil->getHauteurBanniere()?>">pixels
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Couleur du texte'); ?></td>
-          <td class="gauche">
-            <input type="text" class="colorpicker" id="couleur_texte_bandeau" name="couleur_texte_bandeau" size="7" maxlength="7" value="<?php echo $this->profil->getCouleurTexteBandeau()?>">
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Couleur des liens'); ?></td>
-          <td class="gauche">
-            <input type="text" class="colorpicker" id="couleur_lien_bandeau" name="couleur_lien_bandeau" size="7" maxlength="7" value="<?php echo $this->profil->getCouleurLienBandeau()?>">
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td class="droite"><?php echo $this->traduire('Boite de recherche'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox( 'boite_recherche_simple_in_banniere',
-                                         null,
-                                         array('checked' => $this->profil->getBoiteRechercheSimpleInBanniere()));
-            ?>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td class="droite"><?php echo $this->traduire('Boite de connexion'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox( 'boite_login_in_banniere',
-                                         null,
-                                         array('checked' => $this->profil->getBoiteLoginInBanniere()));
-            ?>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Réseaux sociaux et contact'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox(  'header_social_network',
-                                         null,
-                                         array('checked' => $this->profil->getHeaderSocialNetwork()));
-            ?>
-          </td>
-        </tr>
-      </table>
-    </fieldset>
-
-
-    <fieldset>
-      <legend><?php echo $this->traduire('Aspect du site'); ?> </legend>
-      <table border="0" cellpadding="5" cellspacing="0">
-        <tr>
-          <td class="droite"><?php echo $this->traduire('Thème'); ?></td>
-          <td class="gauche">
-            <?php
-                echo $this->formSelect('skin',
-                                       $this->profil->getSkin(),
-                                       null,
-                                       $this->profil->getAvailableSkins());
-            ?>
-          </td>
-        </tr>
-
-        <tr>
-          <td class="droite"><?php echo $this->traduire('CSS'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php echo $this->coreFiveFileInput('header_css', $this->profil->getHeaderCss(), 'css', 'File') ?>
-          </td>
-        </tr>
-
-
-        <tr>
-          <td class="droite"><?php echo $this->traduire('Javascript'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php echo $this->coreFiveFileInput('header_js', $this->profil->getHeaderJs(), 'js', 'File') ?>
-          </td>
-        </tr>
-
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->_('Activer la mise en page responsive').' - '.$this->tag('span',
-                                                                                                      $this->_('nécessite un thème compatible'),
-                                                                                                      ['style' => 'font-weight: bold']); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox(  'responsive',
-                                         null,
-                                         ['checked' => $this->profil->isResponsive()]);
-            ?>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right" style="width:25%"><?php echo $this->traduire('Largeur totale du site'); ?></td>
-          <td>
-            <input type="text" name="largeur_site" size="4" maxlength="4" value="<?php print($this->profil->getLargeurSite()) ?>" style="width:40px">
-            <span class="info" style="color:#575757">
-              <select name="size_site_scale">
-                <option value="px" <?php if ($this->profil->getSizeSiteScale() == "px") echo 'selected="selected"'; ?>>pixels</option>
-                <option value="percent" <?php if ($this->profil->getSizeSiteScale() == "percent") echo 'selected="selected"'; ?>>%</option>
-              </select>
-
-            </span>
-          </td>
-        </tr>
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Nombre de divisons'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <select id="nb_divisions" name="nb_divisions">
-              <option value="1"  <?php if($this->profil->getNbDivisions() == 1) echo 'selected="selected"';?>>1 Division</option>
-              <option value="2"  <?php if($this->profil->getNbDivisions() == 2) echo 'selected="selected"';?>>2 Divisions</option>
-              <option value="3"  <?php if($this->profil->getNbDivisions() == 3) echo 'selected="selected"';?>>3 Divisions</option>
-            </select>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Ordre des divisons'); ?></td>
-          <td class="gauche" style="padding-left:5px">
-            <?php
-            echo $this->formRadioButtons("ordre_divisions",
-                                         $this->profil->getOrdreDivisions(),
-                                         ["1 (toujours visible) - 2 (remplacée par le contenu)- 3 (seulement page accueil)",
-                                          "3  (seulement page accueil) - 2 (remplacée par le contenu) - 1 (toujours visible)"]);
-            ?>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td colspan="2">
-            <div style="width:300px;margin-left:139px">
-              <table>
-                <tr>
-                  <td>&nbsp;</td>
-                  <td colspan="2"><span class="info">Largeur</span></td>
-                  <td colspan="2"><span class="info">Marge interne</span></td>
-                  <td>&nbsp;</td>
-
-                </tr>
-                <tr>
-                  <td align="right">Divison 1</td>
-                  <td width="10px"><input type="text" class="normal" name="largeur_division1" size="4" maxlength="4" value="<?php echo $this->profil->getLargeurDivision1()?>"></td><td class="normal" width="10px">
-                    <select name="width_division1_scale">
-                      <option value="px" <?php if ($this->profil->getWidthDivision1Scale() == "px") echo 'selected="selected"'; ?>>pixels</option>
-                      <option value="percent" <?php if ($this->profil->getWidthDivision1Scale() == "percent") echo 'selected="selected"'; ?>>%</option>
-              </select>
-                  </td>
-                  <td width="10px"><input type="text" class="normal" name="marge_division1" size="2" maxlength="2" value="<?php echo $this->profil->getMargeDivision1()?>"></td><td class="normal">pixels</td>
-                  <td>&nbsp;</td>
-
-                </tr>
-                <tr>
-                  <td align="right">Divison 2</td>
-                  <td width="10px"><input type="text" class="normal" name="largeur_division2" size="4" maxlength="4" value="<?php echo $this->profil->getLargeurDivision2()?>"></td><td class="normal" width="10px">
-
-                    <select name="width_division2_scale">
-                      <option value="px" <?php if ($this->profil->getWidthDivision2Scale() == "px") echo 'selected="selected"'; ?>>pixels</option>
-                      <option value="percent" <?php if ($this->profil->getWidthDivision2Scale() == "percent") echo 'selected="selected"'; ?>>%</option>
-              </select>
-
-</td>
-                  <td width="10px"><input type="text" class="normal" name="marge_division2" size="2" maxlength="2" value="<?php echo $this->profil->getMargeDivision2()?>"></td><td class="normal">
-pixels&nbsp;                  </td>
-                  <td>&nbsp;</td>
-
-                </tr>
-                <tr>
-                  <td align="right">Divison 3</td>
-                  <td width="10px"><input type="text" class="normal" name="largeur_division3" size="4" maxlength="4" value="<?php echo $this->profil->getLargeurDivision3()?>"></td><td class="normal" width="10px">
-
-                    <select name="width_division3_scale">
-                      <option value="px" <?php if ($this->profil->getWidthDivision3Scale() == "px") echo 'selected="selected"'; ?>>pixels</option>
-                      <option value="percent" <?php if ($this->profil->getWidthDivision3Scale() == "percent") echo 'selected="selected"'; ?>>%</option>
-              </select>
-
-</td>
-                  <td width="10px"><input type="text" class="normal" name="marge_division3" size="2" maxlength="2" value="<?php echo $this->profil->getMargeDivision3()?>"></td><td class="normal">pixels</td>
-                  <td style="white-space:nowrap">
-                    <?php echo $this->formCheckbox('division_three_always_visible',
-                                                   null,
-                                                   ['checked' => $this->profil->getDivisionThreeAlwaysVisible(),
-                                                    'style' => 'vertical-align: middle']);
-                    ?>
-                    Toujours visible
-                  </td>
-                </tr>
-              </table>
-            </div>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td class="droite"><?php echo $this->traduire('Afficher le menu horizontal'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox(  'menu_haut_on',
-                                         null,
-                                         array('checked' => $this->profil->getMenuHautOn()));
-            ?>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td class="droite"><?php echo $this->traduire('Afficher la barre de navigation'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox( 'barre_nav_on',
-                                         null,
-                                        array('checked' => $this->profil->getBarreNavOn()));
-            ?>
-          </td>
-        </tr>
-
-
-        <tr class="only_browser">
-          <td class="droite"><?php echo $this->traduire('Afficher le profil courant dans la barre de navigation'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox( 'display_current_profil_on_breadcrumb',
-                                         null,
-                                        ['checked' => $this->profil->getDisplayCurrentProfilOnBreadcrumb()]);
-            ?>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Interdire les liens sortants'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox( 'liens_sortants_off',
-                                         null,
-                                        array('checked' => $this->profil->getLiensSortantsOff()));
-            ?>
-            <span class="info">&nbsp; Sert à interdire d'aller sur internet pour les Opac internes à la bibliothèque.</span>
-          </td>
-        </tr>
-
-        <tr class="only_browser">
-          <td align="right"><?php echo $this->traduire('Activer les outils d\'accessibilité'); ?></td>
-          <td class="gauche">
-            <?php
-              echo $this->formCheckbox(  'accessibilite_on',
-                                         null,
-                                         array('checked' => $this->profil->getAccessibiliteOn()));
-            ?>
-          </td>
-        </tr>
-      </table>
-    </fieldset>
-
-
-    <fieldset>
-      <legend><?php echo $this->traduire('Référencement'); ?> </legend>
-      <table>
-        <tr>
-          <td class="droite" valign="top"><?php echo $this->traduire('Commentaire'); ?></td>
-          <td class="gauche">
-            <TEXTAREA name="commentaire" rows="2" cols="42" title="<?php echo $this->traduire('Ceci apparaîtra sous le nom de votre site dans les moteurs de recherche');?>"><?php echo $this->escape(trim($this->profil->getCommentaire()));?>
-            </TEXTAREA>
-          </td>
-        </tr>
-        <tr>
-          <td>&nbsp;</td>
-          <td class="info"><?php echo $this->traduire('Entrez la liste des mots-clef et expressions qui caractérisent votre site séparés par des virgules.');?></td>
-        </tr>
-        <tr>
-          <td class="droite" valign="top"><?php echo $this->traduire('Mots-clef'); ?></td>
-          <td class="gauche" style="align:left">
-            <TEXTAREA name="ref_tags" rows="1" cols="42" title="<?php echo $this->traduire("Facilite l'indexation de votre site dans les moteurs de recherche");?>"><?php echo $this->escape(trim($this->profil->getRefTags()));?>
-            </TEXTAREA>
-          </td>
-        </tr>
-      </table>
-    </fieldset>
-
-
-
-    <fieldset>
-      <legend><?php echo $this->traduire('Filtrage des données'); ?> </legend>
-      <table>
-
-        <tr>
-          <td class="droite" style="width:130px;"><?php echo $this->traduire('Bibliothèque'); ?></td>
-          <td class="gauche">
-            <?php
-            $class_bib = new Class_Bib();
-            $combo_bib = $class_bib->getComboBib($this->profil->getIdSite(), $this->id_zone, true, 'id_site');
-            $user_login = Class_Users::getIdentity();
-            if ($user_login->ROLE_LEVEL <=4)
-            {
-              $bib = $this->profil->getBib();
-              echo '<select disabled="disabled"><option selected="selected" value="'.$user_login->ID_SITE.'">'.$bib->getLibelle().'</option></select><input type="hidden" value="'.$user_login->ID_SITE.'" name="id_site" id="id_site"/>';
-            }
-            else echo $combo_bib;
-            ?>
-          </td>
-        </tr>
-
-        <tr>
-          <td class="droite" valign="top"><?php echo $this->traduire('Sites (annexes)'); ?></td>
-          <td class="gauche"><?php echo $this->TagListeCoches("annexe","sel_annexe",$this->profil->getSelAnnexe()); ?></td>
-        </tr>
-
-        <tr>
-          <td class="droite" valign="top"><?php echo $this->traduire('Sections'); ?></td>
-          <td class="gauche"><?php echo $this->TagListeCoches("section","sel_section",$this->profil->getSelSection()); ?></td>
-        </tr>
-
-        <tr>
-          <td class="droite" valign="top"><?php echo $this->traduire('Types de documents'); ?></td>
-          <td class="gauche"><?php echo $this->TagListeCoches("type_doc","sel_type_doc",$this->profil->getSelTypeDoc()); ?></td>
-        </tr>
-
-      </table>
-    </fieldset>
-
-    <table>
-      <tr>
-        <td align="right" style="padding-right:5px;"><?php echo $this->Button_Submit(); ?> </td>
-        <td align="left" style="padding-left:5px;"> <?php echo $this->Button_Back(); ?></td>
-      </tr>
-    </table>
-  </form>
-</div>
+echo $this->renderForm($this->form);
+?>
diff --git a/application/modules/admin/views/scripts/profil/accueil.phtml b/application/modules/admin/views/scripts/profil/accueil.phtml
index 4bb42cf045fc79950ae9df47f30cff46621da49c..20a1932d3a9a2fe362dae2c3bcd1fb3592d0e383 100644
--- a/application/modules/admin/views/scripts/profil/accueil.phtml
+++ b/application/modules/admin/views/scripts/profil/accueil.phtml
@@ -1,142 +1,5 @@
-<script type="text/javascript" src="<?php echo URL_ADMIN_JS?>common.js"> </script>
-<script type="text/javascript" src="<?php echo URL_ADMIN_JS?>config_accueil.js"> </script>
-<script type="text/javascript" src="<?php echo URL_ADMIN_JS?>controle_maj.js"> </script>
-<link rel="stylesheet" type="text/css" media="screen" href="<?php echo URL_ADMIN_CSS?>config_accueil.css" />
-
-<?php echo $this->partial('profil/_profil_panel.phtml',
-                          array('profil' => $this->profil)); ?>
-
-
-
-<div class="form">
-  <form name="form" action="<?php echo BASE_URL.'/admin/profil/accueil/id_profil/'.$this->profil->getid() ?>#drag_and_drop_modules" method="post">
-      <?php
-      if($this->profil->hasErrors())  {
-        echo '<ul class="errors">';
-        foreach($this->profil->getErrors() as $erreur)
-          echo '<li>'.$erreur.'</li>';
-        echo '</ul>';
-      }
-      ?>
-      <fieldset>
-        <legend>Page</legend>
-        <table border="0" cellpadding="5" cellspacing="0">
-          <tr>
-            <td class="droite"><?php echo $this->traduire('Libelle'); ?></td>
-            <td class="gauche"><input type="text" name="libelle" value="<?php echo $this->escape(trim($this->profil->getLibelle()));?>" maxlength="50"/></td>
-          </tr>
-          <tr>
-   <td class="droite"><?php echo $this->_("Utiliser le css du profil");echo "</br>". basename($this->profil->getHeaderCss()); ?></td>
-            <td class="gauche">
-              <?php echo $this->formCheckbox('use_parent_css',
-                                             $this->profil->getUseParentCss(),
-                                             null,
-                                             array('1', '0')) ?>
-            </td>
-          </tr>
-          <tr>
-            <td class="droite">
-              <?php echo $this->_("Ajouter au plan du site"); ?>
-            </td>
-            <td class="gauche">
-              <?php echo $this->formCheckbox('sitemap',
-                                             $this->profil->getCfgAccueilParam('sitemap'),
-                                             null,
-                                             array('1', '0')) ?>
-            </td>
-          </tr>
-          <tr>
-            <td class="droite"><?php echo $this->traduire('Page css:'); ?></td>
-            <td class="gauche" style="padding-left:5px">
-<?php echo $this->coreFiveFileInput('page_css', $this->profil->getPageCss(), 'css', 'File') ?>
-            </td>
-          </tr>
-        <tr>
-          <td class="droite"><?php echo $this->traduire('URL de la page'); ?></td>
-          <td class="gauche"><input type="text" style="width:100%" name="rewrite_url" value="<?php echo $this->escape(trim($this->profil->getRewriteUrl()));?>" maxlength="150"/></td>
-        </tr>
-        </table>
-      </fieldset>
-      <a name="drag_and_drop_modules"></a>
-      <fieldset><legend>Modules</legend>
-        <div>Modules disponibles</div>
-        <div id="dhtmlgoodies_dragDropContainer">
-          <div id="dhtmlgoodies_listOfItems">
-            <table>
-              <tr>
-                <td style="width:25%;"><?php echo $this->module_info; ?></td>
-                <td style="width:25%;"><?php echo $this->module_rech; ?></td>
-                <td style="width:25%;"><?php echo $this->module_site; ?></td>
-                <td style="width:25%;"><?php echo $this->module_abonne; ?></td>
-              </tr>
-            </table>
-          </div>
-
-          <br/>
-
-          <div>Modules installés</div>
-          <div id="dhtmlgoodies_mainContainer">
-            <table>
-              <?php
-              $width_col = "98%";
-              if($this->nb_divisions == 2) $width_col = "48%";
-              if($this->nb_divisions == 3) $width_col = "33%";
-
-              echo('<tr><td style="width:'.$width_col.';">
-                        <div style="width:100%;background-color:#E2EBED">
-                        <p>1ere division</p>
-                        <ul id="box1">'.$this->box1.'</ul>
-                </div></td>');
-              if($this->nb_divisions > 1)
-              {
-                echo('<td style="width:'.$width_col.'"><div style="width:100%;background-color:#E2EBED">
-                <p>2eme division</p>
-                <ul id="box2">'.$this->box2.'</ul>
-                </div></td>');
-              }
-              if($this->nb_divisions > 2)
-              {
-                echo('<td style="width:'.$width_col.'">
-                <div style="width:100%;background-color:#E2EBED">
-                <p>3eme division</p>
-                <ul id="box3">'.$this->box3.'</ul>
-                </div></td>');
-              }
-              ?>
-            </tr>
-            <?php if (Class_AdminVar::isMenuBoiteEnabled()) { ?>
-            <tr>
-               <td colspan="<?php echo $this->nb_divisions ?>">
-                 <div style="width:100%;background-color:#E2EBED">
-                   <p>Bannière</p>
-                   <ul id="box4"><?php echo $this->box4 ?></ul>
-                 </div>
-               </td>
-             </tr>
-             <?php } ?>
-             <tr>
-               <td colspan="<?php echo $this->nb_divisions ?>">
-                 <div style="width:100%;background-color:#E2EBED">
-                   <p>Flottant</p>
-                   <ul id="box5"><?php echo $this->box5 ?></ul>
-                 </div>
-               </td>
-             </tr>
-            </table>
-          </div>
-        </div>
-      </fieldset>
-
-      <ul id="dragContent"></ul>
-      <div id="dragDropIndicator"><img src="<?php echo URL_ADMIN_IMG; ?>insert.gif" alt='insérer' /></div>
-      <textarea id="saveContent" name="saveContent" style="display:none;" rows="30" cols="10"></textarea>
-      <br/>
-      <div  align="center" style="width:100%">
-        <?php
-        echo $this->Button_Submit();
-        echo $this->Button_Back((new Class_Entity())
-                                ->setUrl($this->url(['action' => 'edit'])));
-        ?>
-      </div>
-    </form>
-  </div>
+<?php
+echo $this->partial('profil/_profil_panel.phtml',
+                    ['profil' => $this->profil]);
+echo $this->renderForm($this->form);
+?>
diff --git a/cosmogramme/VERSIONS_WIP/59734 b/cosmogramme/VERSIONS_WIP/59734
new file mode 100644
index 0000000000000000000000000000000000000000..4ada07b063377e5ae779f6b736b02f654a1b56ef
--- /dev/null
+++ b/cosmogramme/VERSIONS_WIP/59734
@@ -0,0 +1 @@
+ - ticket #59734 : ZendAfi_Form Profil & page
\ No newline at end of file
diff --git a/library/Class/Profil.php b/library/Class/Profil.php
index 7a36ba3238c0b03bb4af7a47fa930250facb61bb..871b055aadcdd3b1b9f7c61464e729b1e35e0732 100644
--- a/library/Class/Profil.php
+++ b/library/Class/Profil.php
@@ -143,9 +143,11 @@ class ProfilLoader extends Storm_Model_Loader {
 
 
 class Class_Profil extends Storm_Model_Abstract {
-  use Trait_StaticFileSystem;
-  use Trait_StaticFileWriter;
-  use Trait_TreeNode;
+  use
+    Trait_StaticFileSystem,
+    Trait_StaticFileWriter,
+    Trait_TreeNode,
+    Trait_Translator;
 
   const DIV_BANNIERE = 4;
   const DIV_FLOTANTTE = 5;
@@ -269,7 +271,9 @@ class Class_Profil extends Storm_Model_Abstract {
                               'header_social_network',
                               'mail_suggestion_achat',
                               'division_three_always_visible',
-                              'responsive'
+                              'responsive',
+                              'boite_recherche_simple_in_banniere',
+                              'boite_login_in_banniere'
       ];
     return self::$CFG_SITE_KEYS;
 
@@ -335,7 +339,7 @@ class Class_Profil extends Storm_Model_Abstract {
     if (!isset(self::$DEFAULT_VALUES))
       self::$DEFAULT_VALUES =
         ['cfg_site' => '',
-         'cfg_accueil' => ZendAfi_Filters_Serialize::serialize([ 'page_css' => null,
+         'cfg_accueil' => ZendAfi_Filters_Serialize::serialize(['page_css' => null,
                                                                 'use_parent_css' => true,
                                                                 'modules' => [],
                                                                 'sitemap' => 1]),
@@ -980,6 +984,7 @@ class Class_Profil extends Storm_Model_Abstract {
   public function getCfgSiteAsArray() {
     if (!isset($this->_cfg_site_array))
       $this->_cfg_site_array = $this->_getCfgAsArrayNamed('Site');
+
     return $this->_cfg_site_array;
   }
 
@@ -1326,33 +1331,57 @@ class Class_Profil extends Storm_Model_Abstract {
    * @return Class_Profil
    */
   public function validate() {
-    if ($this->getNbDivisions() < 3)  $this->setLargeurDivision3(0);
-    if ($this->getNbDivisions() < 2)  $this->setLargeurDivision2(0);
-    $this->check($this->getLibelle(), 'Le libellé est obligatoire.');
-    $this->check($this->getSizeSiteScale()!="px" or $this->getLargeurSite() >= 800 and $this->getLargeurSite() <= 2000,
-                 'La largeur du site doit être comprise entre 800 et 2000 pixels.');
-    $this->check($this->getSizeSiteScale()!="px" or
-                 ($this->getLargeurDivision1() +
-                  $this->getLargeurDivision2() +
-                  $this->getLargeurDivision3() <= $this->getLargeurSite()),
-                 'La somme des largeurs des divisions ne doit pas excéder la largeur du site.');
-
-    $this->check($this->getLargeurDivision1(), 'Il manque la largeur de la division 1.');
-    $this->check($this->getLargeurDivision2() or $this->getNbDivisions() < 2,
-                 'Il manque la largeur de la division 2.');
-    $this->check($this->getLargeurDivision3() or $this->getNbDivisions() < 3,
-                 'Il manque la largeur de la division 3.');
-    $this->check($this->getMargeDivision1() < 20
-                 and $this->getMargeDivision2() < 20
-                 and $this->getMargeDivision3() < 20,
-                 'Une marge interne de division ne peut pas excéder 20 pixels.');
-
-
-    $this->check($this->_isCSSColorValid($this->getCouleurTexteBandeau()),
-                 'La couleur du texte bandeau doit être au format #001122');
-
-    $this->check($this->_isCSSColorValid($this->getCouleurLienBandeau()),
-                 'La couleur des liens du bandeau doit être au format #001122');
+    if($this->getNbDivisions() < 3)
+      $this->setLargeurDivision3(0);
+
+    if($this->getNbDivisions() < 2)
+      $this->setLargeurDivision2(0);
+
+    $this->checkAttribute('libelle',
+                          $this->getLibelle(), $this->_('Le libellé est obligatoire.'));
+
+    $this->checkAttribute('size_site_scale',
+                          $this->getSizeSiteScale()!="px" or $this->getLargeurSite() >= 800 and $this->getLargeurSite() <= 2000,
+                          $this->_('La largeur du site doit être comprise entre 800 et 2000 pixels.'));
+
+    $this->checkAttribute('nb_divisions',
+                          $this->getSizeSiteScale()!="px" or
+                          ($this->getLargeurDivision1() +
+                           $this->getLargeurDivision2() +
+                           $this->getLargeurDivision3() <= $this->getLargeurSite()),
+                          $this->_('La somme des largeurs des divisions ne doit pas excéder la largeur du site.'));
+
+    $this->checkAttribute('largeur_division1',
+                          $this->getLargeurDivision1(),
+                          $this->_('Il manque la largeur de la division 1.'));
+
+    $this->checkAttribute('largeur_division2',
+                          $this->getLargeurDivision2() or $this->getNbDivisions() < 2,
+                          $this->_('Il manque la largeur de la division 2.'));
+
+    $this->checkAttribute('largeur_division3',
+                          $this->getLargeurDivision3() or $this->getNbDivisions() < 3,
+                          $this->_('Il manque la largeur de la division 3.'));
+
+    $this->checkAttribute('marge_division1',
+                          $this->getMargeDivision1() < 20,
+                          $this->_('Une marge interne de division ne peut pas excéder 20 pixels.'));
+
+    $this->checkAttribute('marge_division2',
+                          $this->getMargeDivision2() < 20,
+                          $this->_('Une marge interne de division ne peut pas excéder 20 pixels.'));
+
+    $this->checkAttribute('marge_division3',
+                          $this->getMargeDivision3() < 20,
+                          $this->_('Une marge interne de division ne peut pas excéder 20 pixels.'));
+
+    $this->checkAttribute('couleur_texte_bandeau',
+                          $this->_isCSSColorValid($this->getCouleurTexteBandeau()),
+                          $this->_('La couleur du texte bandeau doit être au format #001122'));
+
+    $this->checkAttribute('couleur_lien_bandeau',
+                          $this->_isCSSColorValid($this->getCouleurLienBandeau()),
+                          $this->_('La couleur des liens du bandeau doit être au format #001122'));
 
 
     $validator = new ZendAfi_Validate_ProfilRewriteUrl();
diff --git a/library/ZendAfi/Form.php b/library/ZendAfi/Form.php
index 0b706baa4b1cec544672eec102d70d1a52234657..8bb6a90490fd58b0e461534cba64b4ffbbb61dd8 100644
--- a/library/ZendAfi/Form.php
+++ b/library/ZendAfi/Form.php
@@ -89,22 +89,12 @@ class ZendAfi_Form extends Zend_Form {
   }
 
 
-  /**
-   * @param $name string
-   * @return Zend_Form_Element
-   */
   public function addRequiredTextNamed($name) {
     $this->addElement('text', $name, array('required' => true, 'allowEmpty' => false));
     return $this->getElement($name);
   }
 
 
-  /**
-   * Validate the form
-   *
-   * @param  mixed $data
-   * @return boolean
-   */
   public function isValid($array_or_model) {
 
     if (is_array($array_or_model))
@@ -112,13 +102,11 @@ class ZendAfi_Form extends Zend_Form {
 
     $valid = parent::isValid($array_or_model->toArray()) & $array_or_model->isValid();
     $this->addModelErrors($array_or_model);
-
-
-
     $this->_errorsExist = !$valid;
     return $valid;
   }
 
+
   public function isValidModelAndArray($model, $array) {
     $valid = parent::isValid($array) && $model->isValid();
     $this->addModelErrors($model);
diff --git a/library/ZendAfi/Form/Configuration/Profile.php b/library/ZendAfi/Form/Configuration/Profile.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce470a6f5479a63ddb6c89b8ebbb3a4fc91b5661
--- /dev/null
+++ b/library/ZendAfi/Form/Configuration/Profile.php
@@ -0,0 +1,396 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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 ZendAfi_Form_Configuration_Profile extends ZendAfi_Form {
+
+  public function init() {
+    parent::init();
+
+    Class_ScriptLoader::getInstance()
+      ->loadColorPicker()
+      ->addJqueryReady('
+$(".colorpicker").attachColorPicker();
+checkBoxToggleVisibilityForElement("#barre_nav_on", $("#display_current_profil_on_breadcrumb").closest("tr"), true);
+checkBoxToggleVisibilityForElement("#header_img_cycle", $("input[name=header_img]").closest("tr"), false);
+formSelectToggleVisibilityForElement("#access_level", $("#login_page").closest("tr"), ["0","2","3","4","5","6"]);
+formSelectToggleVisibilityForElement("#browser", $(".only_browser").closest("tr"), "opac");
+');
+
+
+    $this
+      ->addElement('text',
+                   'libelle',
+                   ['label' => $this->_('Libelle'),
+                    'required' => true,
+                    'allowEmpty' => false])
+
+      ->addElement('select',
+                   'browser',
+                   ['label' => $this->_('Type d\'interface'),
+                    'multiOptions' => ['opac' => $this->_('Ordinateur'),
+                                       'telephone' => $this->_('Mobile')]])
+
+      ->addElement('select',
+                   'access_level',
+                   ['label' => $this->_('Niveau d\'accès requis'),
+                    'multiOptions' => (new Class_Profil())->getAllAccessLevels(),
+                    'value' => '-1'])
+
+      ->addElement('ComboProfils',
+                   'login_page',
+                   ['label' => $this->_('Page d\'authentification'),
+                    'value' => 1,
+                    'empty_option' => true])
+
+      ->addElement('email',
+                   'mail_site',
+                   ['label' => $this->_('E-mail du webmestre')])
+
+      ->addElement('email',
+                   'mail_suggestion_achat',
+                   ['label' => $this->_('E-mail de réception des suggestions d\'achat')])
+
+      ->addElement('text',
+                   'rewrite_url',
+                   ['label' => $this->_('URL du profil'),
+                    'validators' => [new ZendAfi_Validate_ProfilRewriteUrl()]])
+
+      ->addElement('userfile',
+                   'header_img',
+                   ['label' => $this->_('Image de fond'),
+                    'rubrique' => 'bannieres'])
+
+      ->addElement('checkbox',
+                   'header_img_cycle',
+                   ['label' => $this->_('Défilement des images')])
+
+      ->addElement('userfile',
+                   'favicon',
+                   ['label' => $this->_('Icône du navigateur'),
+                    'rubrique' => 'bannieres'])
+
+      ->addElement('userfile',
+                   'logo_gauche_img',
+                   ['label' => $this->_('Logo gauche'),
+                    'class' => 'only_browser',
+                    'rubrique' => 'bannieres'])
+
+      ->addElement('text',
+                   'logo_gauche_link',
+                   ['label' => $this->_('Lien logo gauche'),
+                    'class' => 'only_browser'])
+
+      ->addElement('userfile',
+                   'logo_droite_img',
+                   ['label' => $this->_('Logo droite'),
+                    'rubrique' => 'bannieres',
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'logo_droite_link',
+                   ['label' => $this->_('Lien logo droite'),
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'hauteur_banniere',
+                   ['label' => $this->_('Hauteur de la bannière en pixels'),
+                    'value' => 100,
+                    'class' => 'only_browser',
+                    'size' => 4])
+
+      ->addElement('text',
+                   'couleur_texte_bandeau',
+                   ['class' => 'colorpicker',
+                    'class' => 'only_browser',
+                    'label' => $this->_('Couleur du texte')])
+
+      ->addElement('text',
+                   'couleur_lien_bandeau',
+                   ['class' => 'colorpicker only_browser',
+                    'label' => $this->_('Couleur des liens')])
+
+      ->addElement('checkbox',
+                   'boite_recherche_simple_in_banniere',
+                   ['label' => $this->_('Boite de recherche'),
+                    'class' => 'only_browser',])
+
+      ->addElement('checkbox',
+                   'boite_login_in_banniere',
+                   ['label' => $this->_('Boite de connexion'),
+                    'class' => 'only_browser'])
+
+      ->addElement('checkbox',
+                   'header_social_network',
+                   ['label' => $this->_('Réseaux sociaux et contact'),
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'skin',
+                   ['label' => $this->_('Thème'),
+                    'multiOptions' => (new Class_Profil())->getAvailableSkins()])
+
+      ->addElement('userfile',
+                   'header_css',
+                   ['label' => $this->_('CSS'),
+                    'rubrique' => 'css'])
+
+      ->addElement('userfile',
+                   'header_js',
+                   ['label' => $this->_('Javascript'),
+                    'rubrique' => 'js'])
+
+      ->addElement('checkbox',
+                   'responsive',
+                   ['label' => $this->_('Activer la mise en page responsive'),
+                    'class' => 'only_browser'])
+
+      ->addElement('info',
+                   'responsive_requirement',
+                   ['value' => $this->_('nécessite un thème compatible'),
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'largeur_site',
+                   ['label' => $this->_('Largeur du site'),
+                    'size' => 4,
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'size_site_scale',
+                   ['label' => $this->_('Unité de mesure'),
+                    'multiOptions' => ['px' => $this->_('pixels'),
+                                       'percent' => $this->_('pourcentage')],
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'nb_divisions',
+                   ['label' => $this->_('Nombre de divisions'),
+                    'multiOptions' => [1 => 1,
+                                       2 => 2,
+                                       3 => 3],
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'ordre_divisions',
+                   ['label' => $this->_('Ordre des divisions'),
+                    'multiOptions' => [$this->_('1 (toujours visible) - 2 (remplacée par le contenu)- 3 (seulement page accueil)'),
+                                       $this->_('3  (seulement page accueil) - 2 (remplacée par le contenu) - 1 (toujours visible)')],
+                    'class' => 'only_browser'])
+
+      ->addElement('checkbox',
+                   'division_three_always_visible',
+                   ['label' => $this->_('Division 3 toujours visible'),
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'largeur_division1',
+                   ['size' => 4,
+                    'label' => $this->_('Largeur division 1'),
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'width_division1_scale',
+                   ['label' => $this->_('Unité de mesure'),
+                    'multiOptions' => ['px' => $this->_('pixels'),
+                                       'percent' => $this->_('pourcentage')],
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'marge_division1',
+                   ['size' => 4,
+                    'label' => $this->_('Marge division 1'),
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'largeur_division2',
+                   ['size' => 4,
+                    'label' => $this->_('Largeur division 2'),
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'width_division2_scale',
+                   ['label' => $this->_('Unité de mesure'),
+                    'multiOptions' => ['px' => $this->_('pixels'),
+                                       'percent' => $this->_('pourcentage')],
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'marge_division2',
+                   ['size' => 4,
+                    'label' => $this->_('Marge division 2'),
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'largeur_division3',
+                   ['size' => 4,
+                    'label' => $this->_('Largeur division 3'),
+                    'class' => 'only_browser'])
+
+      ->addElement('select',
+                   'width_division3_scale',
+                   ['label' => $this->_('Unité de mesure'),
+                    'multiOptions' => ['px' => $this->_('pixels'),
+                                       'percent' => $this->_('pourcentage')],
+                    'class' => 'only_browser'])
+
+      ->addElement('text',
+                   'marge_division3',
+                   ['size' => 4,
+                    'label' => $this->_('Marge division 3'),
+                    'class' => 'only_browser'])
+
+
+      ->addElement('checkbox',
+                   'menu_haut_on',
+                   ['label' => $this->_('Menu horizontal'),
+                    'class' => 'only_browser'])
+
+      ->addElement('checkbox',
+                   'barre_nav_on',
+                   ['label' => $this->_('Barre de navigation'),
+                    'class' => 'only_browser'])
+
+      ->addElement('checkbox',
+                   'display_current_profil_on_breadcrumb',
+                   ['label' => $this->_('Profil courant dans la barre de navigation'),
+                    'class' => 'only_browser'])
+
+      ->addElement('checkbox',
+                   'liens_sortants_off',
+                   ['label' => $this->_('Interdire les liens sortants')])
+
+      ->addElement('info',
+                   'liens_sortants_off_description',
+                   ['value' => $this->_('Sert à interdire d\'aller sur internet pour les Opac internes à la bibliothèque')])
+
+      ->addElement('checkbox',
+                   'accessibilite_on',
+                   ['label' => $this->_('Outils d\'accessibilité'),
+                    'value' => 1,
+                    'class' => 'only_browser'])
+
+      ->addElement('textarea',
+                   'commentaire',
+                   ['label' => $this->_('Commentaire'),
+                    'cols' => 40,
+                    'rows' => 2])
+
+      ->addElement('textarea',
+                   'ref_tags',
+                   ['label' => $this->_('Mots-clef'),
+                    'cols' => 40,
+                    'rows' => 1])
+
+      ->addElement('info',
+                   'tags_info',
+                   ['value' => $this->_('Entrez la liste des mots-clef et expressions qui caractérisent votre site séparés par des virgules.')])
+
+      ->addElement('comboLibraries',
+                   'id_site',
+                   ['label' => $this->_('Bibliothèque')])
+
+      ->addElement('cochesSuggestion',
+                   'sel_annexe',
+                   ['label' => $this->_('Sites (annexes)'),
+                    'rubrique' => 'annexe'])
+
+      ->addElement('cochesSuggestion',
+                   'sel_section',
+                   ['rubrique' => 'section',
+                    'label' => $this->_('Sections')])
+
+      ->addElement('cochesSuggestion',
+                   'sel_type_doc',
+                   ['rubrique' => 'type_doc',
+                    'label' => $this->_('Types de documents')])
+
+      ->addToHeadGroup(['libelle',
+                        'rewrite_url'])
+
+      ->addDisplayGroup(['browser',
+                         'skin',
+                         'header_css',
+                         'header_js',
+                         'responsive',
+                         'responsive_requirement',
+                         'largeur_site',
+                         'size_site_scale',
+                         'nb_divisions',
+                         'ordre_divisions',
+                         'largeur_division1',
+                         'width_division1_scale',
+                         'marge_division1',
+                         'largeur_division2',
+                         'width_division2_scale',
+                         'marge_division2',
+                         'largeur_division3',
+                         'width_division3_scale',
+                         'marge_division3',
+                         'division_three_always_visible'],
+                        'profil_display_settings',
+                        ['legend' => $this->_('Affichage')])
+
+      ->addDisplayGroup(['hauteur_banniere',
+                         'couleur_texte_bandeau',
+                         'couleur_lien_bandeau',
+                         'header_img_cycle',
+                         'header_img',
+                         'favicon',
+                         'logo_gauche_img',
+                         'logo_gauche_link',
+                         'logo_droite_img',
+                         'logo_droite_link',
+                         'boite_recherche_simple_in_banniere',
+                         'boite_login_in_banniere',
+                         'menu_haut_on',
+                         'barre_nav_on',
+                         'display_current_profil_on_breadcrumb',
+                         'accessibilite_on',
+                         'header_social_network'],
+                        'banner_group',
+                        ['legend' => $this->_('Banniere')])
+
+      ->addDisplayGroup(['commentaire',
+                         'ref_tags',
+                         'tags_info'],
+                        'referencement_group',
+                        ['legend' => $this->_('Référencement')])
+
+      ->addDisplayGroup(['id_site',
+                         'sel_annexe',
+                         'sel_section',
+                         'sel_type_doc'],
+                        'filters_group',
+                        ['legend' => $this->_('Filtrage du contenu')])
+
+      ->addDisplayGroup(['access_level',
+                         'login_page',
+                         'mail_site',
+                         'mail_suggestion_achat',
+                         'liens_sortants_off',
+                         'liens_sortants_off_description'],
+                        'admin_group',
+                        ['legend' => $this->_('Administration')])
+      ;
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Configuration/Profile/Page.php b/library/ZendAfi/Form/Configuration/Profile/Page.php
new file mode 100644
index 0000000000000000000000000000000000000000..ade8e0c239cda2a2e03d3a49d725e9dbde99a324
--- /dev/null
+++ b/library/ZendAfi/Form/Configuration/Profile/Page.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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 ZendAfi_Form_Configuration_Profile_Page extends ZendAfi_Form {
+  public function init() {
+    parent::init();
+
+    $this
+      ->addElement('text',
+                   'libelle',
+                   ['label' => $this->_('Libelle'),
+                    'required' => true,
+                    'allowEmpty' => false])
+
+      ->addElement('text',
+                   'rewrite_url',
+                   ['label' => $this->_('URL de la page'),
+                    'validators' => [new ZendAfi_Validate_ProfilRewriteUrl()]])
+
+      ->addElement('checkbox',
+                   'use_parent_css',
+                   ['label' => $this->_('Utiliser le fichier CSS du profil'),
+                    'value' => 1])
+
+      ->addElement('userfile',
+                   'page_css',
+                   ['label' => $this->_('Fichier CSS'),
+                    'folder' => 'css'])
+
+      ->addElement('profileComposition',
+                   'profile_composition')
+
+      ->addElement('checkbox',
+                   'sitemap',
+                   ['label' => $this->_('Ajouter un plan du site'),
+                    'value' => 1])
+
+      ->addToHeadGroup(['libelle',
+                        'rewrite_url',
+                        'sitemap'])
+
+      ->addDisplayGroup(['profile_composition'],
+                        'profile_composition_group',
+                        ['legend' => $this->_('Composition')])
+
+      ->addDisplayGroup(['use_parent_css',
+                         'page_css'],
+                        'display_group',
+                        ['legend' => $this->_('Affichage')]);
+      }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Decorator/ComboLibraries.php b/library/ZendAfi/Form/Decorator/ComboLibraries.php
index 0023badf73ac79084d2d1af75759d25c22dc4e8e..f42df8997fb75d5964f2ba5ae36b7c63f2cfae4a 100644
--- a/library/ZendAfi/Form/Decorator/ComboLibraries.php
+++ b/library/ZendAfi/Form/Decorator/ComboLibraries.php
@@ -24,7 +24,7 @@ class ZendAfi_Form_Decorator_ComboLibraries extends Zend_Form_Decorator_Abstract
   public function render($content) {
     return $content
       .$this->_element->getView()
-                      ->comboLibraries($this->_element->getLibrary());
+                      ->comboLibraries($this->_element->getLibrary(), $this->_element->getName());
   }
 }
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Decorator/Info.php b/library/ZendAfi/Form/Decorator/Info.php
index 5e589774c5d8200987d37076885c97f5181cce1e..336f62913091dac5ede412010fd0b16ca3249dc2 100644
--- a/library/ZendAfi/Form/Decorator/Info.php
+++ b/library/ZendAfi/Form/Decorator/Info.php
@@ -22,7 +22,7 @@
 
 class ZendAfi_Form_Decorator_Info extends Zend_Form_Decorator_Abstract {
   public function render($content) {
-    return $this->_element->getView()->tag('td', $this->_element->getValue());
+    return $this->_element->getView()->tag('td', $this->_element->getValue(), $this->_element->getAttribs());
   }
 }
 ?>
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Decorator/ProfileComposition.php b/library/ZendAfi/Form/Decorator/ProfileComposition.php
new file mode 100644
index 0000000000000000000000000000000000000000..9982b2e36dc20bc33752dd83d1bf6dc3704a6c6f
--- /dev/null
+++ b/library/ZendAfi/Form/Decorator/ProfileComposition.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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 ZendAfi_Form_Decorator_ProfileComposition extends Zend_Form_Decorator_Abstract {
+  public function render($content) {
+    return $this->_element->getView()->profileComposition($this->_element->getName(),
+                                                          $this->_element->getValue(),
+                                                          $this->_element->getAttribs());
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Decorator/Userfile.php b/library/ZendAfi/Form/Decorator/Userfile.php
index 735f1400be7445ab84baadcd2040d4c546f566cc..988a49c07e62984b18304e27ebb0b9bdd49440e7 100644
--- a/library/ZendAfi/Form/Decorator/Userfile.php
+++ b/library/ZendAfi/Form/Decorator/Userfile.php
@@ -25,6 +25,8 @@ class ZendAfi_Form_Decorator_Userfile extends Zend_Form_Decorator_Abstract {
   public function render($content) {
     return $this->_element->getView()->coreFiveFileInput($this->_element->getName(),
                                                          $this->_element->getValue(),
-                                                         $this->_element->getFolder());
+                                                         $this->_element->getFolder(),
+                                                         null,
+                                                         $this->_element->getAttribs());
   }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Form/Element/ProfileComposition.php b/library/ZendAfi/Form/Element/ProfileComposition.php
new file mode 100644
index 0000000000000000000000000000000000000000..85626e9abfe2c6774f74e25ddb8b9242d3244d18
--- /dev/null
+++ b/library/ZendAfi/Form/Element/ProfileComposition.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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 ZendAfi_Form_Element_ProfileComposition extends Zend_Form_Element {
+  public function __construct($spec, $options = null) {
+    parent::__construct($spec, $options);
+
+    $decorators = $this->_decorators;
+    $this->_decorators = ['Userfile' => new ZendAfi_Form_Decorator_ProfileComposition()];
+
+    foreach ($decorators as $name => $value)
+      $this->_decorators[$name] = $value;
+    $this->removeDecorator('ViewHelper');
+  }
+}
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/Validate/ProfilRewriteUrl.php b/library/ZendAfi/Validate/ProfilRewriteUrl.php
index 0c9b37c9fe01a2d172a9297f6b946a1226255d11..316d8ddb2a6f1025b028c176a91109ca19288fa7 100644
--- a/library/ZendAfi/Validate/ProfilRewriteUrl.php
+++ b/library/ZendAfi/Validate/ProfilRewriteUrl.php
@@ -33,7 +33,17 @@ class ZendAfi_Validate_ProfilRewriteUrl extends Zend_Validate_Abstract {
 
 
   public function isValid($profil) {
-    $this->_setValue($url = trim((string)$profil->getRewriteUrl()));
+    $url = $profil;
+
+    if($profil instanceof Class_Profil)
+      $url = trim( (string) $profil->getRewriteUrl());
+
+    if(!$profil instanceof Class_Profil) {
+      $profil = Class_Profil::getCurrentProfil();
+      $profil->setRewriteUrl($url);
+    }
+
+    $this->_setValue($url);
 
     if (!$url)
       return true;
@@ -55,30 +65,30 @@ class ZendAfi_Validate_ProfilRewriteUrl extends Zend_Validate_Abstract {
     if (!$this->checkPageWithSameUrlAsAPageWithoutRewriteUrl($profil))
       return false;
 
-     if (!$this->checkOtherModelsUrl($profil))
-       return false;
+    if (!$this->checkOtherModelsUrl($profil))
+      return false;
 
-     return true;
-   }
+    return true;
+  }
 
 
-   protected function checkOtherModelsUrl($profil) {
-     $validator = new ZendAfi_Validate_RewriteUrl(['Class_Profil']);
-     if ($validator->isValid($profil))
-       return true;
+  protected function checkOtherModelsUrl($profil) {
+    $validator = new ZendAfi_Validate_RewriteUrl(['Class_Profil']);
+    if ($validator->isValid($profil))
+      return true;
 
-     foreach($validator->getMessages() as $key => $message) {
-       $this->_errors[]= $key;
-       $this->_messages[$key] = $message;
-     }
+    foreach($validator->getMessages() as $key => $message) {
+      $this->_errors[]= $key;
+      $this->_messages[$key] = $message;
+    }
 
-     return false;
-   }
+    return false;
+  }
 
 
-   protected function checkProfilWithSameUrlAsAnotherProfil($profil) {
-     if ($profil->hasParentProfil())
-       return true;
+  protected function checkProfilWithSameUrlAsAnotherProfil($profil) {
+    if ($profil->hasParentProfil())
+      return true;
 
     $others = Class_Profil::findAllBy(['rewrite_url' => $profil->getRewriteUrl(),
                                        'parent_id' => null]);
@@ -105,13 +115,13 @@ class ZendAfi_Validate_ProfilRewriteUrl extends Zend_Validate_Abstract {
     $profils = Class_Profil::findAllBy(['rewrite_url' => $profil->getRewriteUrl()]);
     $profils = array_filter($profils,
                             function ($model) {
-                                return $model->hasParentProfil()
-                                  && (!$model->getParent()->getRewriteUrl());});
+                                                 return $model->hasParentProfil()
+                                                   && (!$model->getParent()->getRewriteUrl());});
 
     if (empty($profils))
       return true;
 
-    $this->setPageError($profils[0]);
+    $this->setPageError(array_shift($profils));
     return false;
   }
 
@@ -124,10 +134,10 @@ class ZendAfi_Validate_ProfilRewriteUrl extends Zend_Validate_Abstract {
 
     $profils = array_filter($profils,
                             function ($model) use ($page) {
-                                return $model->hasParentProfil()
-                                  && ($model->getId() !== $page->getId())
-                                  && ($model->getParent()->getRewriteUrl() == $page->getParent()->getRewriteUrl());
-                            });
+                                                             return $model->hasParentProfil()
+                                                             && ($model->getId() !== $page->getId())
+                                                             && ($model->getParent()->getRewriteUrl() == $page->getParent()->getRewriteUrl());
+                                                           });
 
     if (empty($profils))
       return true;
diff --git a/library/ZendAfi/View/Helper/ComboLibraries.php b/library/ZendAfi/View/Helper/ComboLibraries.php
index fcedcf02df588ad8cbf50ee6ee75a27443c731e3..e22acdf7594e745b57d7bfe64225cca2b6817ee7 100644
--- a/library/ZendAfi/View/Helper/ComboLibraries.php
+++ b/library/ZendAfi/View/Helper/ComboLibraries.php
@@ -22,9 +22,9 @@
 class ZendAfi_View_Helper_ComboLibraries extends Zend_View_Helper_HtmlElement {
   use Trait_Translator;
 
-  public function comboLibraries($current) {
+  public function comboLibraries($current, $name = 'id_bib') {
     return $this->view->tag('select', $this->_getLibraries($current),
-                            ['name' => 'id_bib', 'id' => 'id_bib']);
+                            ['name' => $name, 'id' => $name]);
   }
 
 
diff --git a/library/ZendAfi/View/Helper/CoreFiveFileInput.php b/library/ZendAfi/View/Helper/CoreFiveFileInput.php
index 93a11ae0ec6f05bb6ef970bbe3765baa0786910f..8633e7ba73378a892b298b0ec00bf7c84f92070e 100644
--- a/library/ZendAfi/View/Helper/CoreFiveFileInput.php
+++ b/library/ZendAfi/View/Helper/CoreFiveFileInput.php
@@ -22,7 +22,7 @@
 
 class ZendAfi_View_Helper_CoreFiveFileInput extends ZendAfi_View_Helper_BaseHelper {
 
-  public function CoreFiveFileInput($name, $value, $folder, $type = 'Images') {
+  public function CoreFiveFileInput($name, $value, $folder, $type = 'Images', $attribs = []) {
     $banniere_dir = USERFILESPATH."/$folder/";
     if (!is_dir($banniere_dir))
       mkdir($banniere_dir);
@@ -40,7 +40,7 @@ class ZendAfi_View_Helper_CoreFiveFileInput extends ZendAfi_View_Helper_BaseHelp
       "}".
       "</script>";
 
-    return $html.= $this->view->formText($name, $value) .
+    return $html.= $this->view->formText($name, $value, $attribs) .
       $this->view->Button((new Class_Entity())
                           ->setText($this->_('Explorer le serveur'))
                           ->setAttribs(['onclick' => "openFileManagerFor_$name();return false;"]));
diff --git a/library/ZendAfi/View/Helper/ProfileComposition.php b/library/ZendAfi/View/Helper/ProfileComposition.php
new file mode 100644
index 0000000000000000000000000000000000000000..88e7b6c050758e423c74072b98bcc7f2e4cf1227
--- /dev/null
+++ b/library/ZendAfi/View/Helper/ProfileComposition.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, 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 ZendAfi_View_Helper_ProfileComposition extends ZendAfi_View_Helper_BaseHelper {
+  public function ProfileComposition($name, $entity, $attribs = []) {
+    Class_ScriptLoader::getInstance()
+      ->addOPACScript('input_connect_list/input_connect_list')
+      ->addJQueryReady('$(".profile_composition").draggableComposition();')
+      ->addAdminStyleSheet('config_accueil');
+
+    return $this->_tag('div',
+                       $this->_dragDropContainers(),
+                       ['class' => 'profile_composition']);
+  }
+
+
+  protected function _dragDropContainers() {
+    $html = [$this->_availableItems(),
+             $this->_mainContainer()];
+
+    return $this->_tag('div',
+                       implode($html));
+  }
+
+
+  protected function _availableItems() {
+    $blocks = [];
+    foreach((new Class_Systeme_ModulesAccueil)->getGroupes() as $groupe => $libelle)
+      $blocks[$groupe] = $this->_tag('div',
+                                     $this->_tag('h5', $libelle) .
+                                     $this->_tag('ul',
+                                                 $this->_getAvailableWidgetsFor($libelle),
+                                                 ['class' => 'source_list']));
+
+    return $this->_tag('div',
+                       $this->_tag('h4', $this->_('Boites disponibles')).
+                       implode($blocks),
+                       ['class' => 'drag_drop_container']);
+  }
+
+
+  protected function _getAvailableWidgetsFor($group) {
+    $widgets = (new Class_Systeme_ModulesAccueil)->getWidgets();
+    if(!isset($widgets[$group]))
+      return '';
+
+    $widgets = $widgets[$group];
+
+    $lis = [];
+    foreach($widgets as $type => $label)
+      $lis[] = $this->_getItemModule($type, $label);
+
+    return implode($lis);
+  }
+
+
+  protected function _getItemModule($type_module, $module, $preferences = '', $id_module = 0) {
+    $anchor = '';
+
+    if($id_module)
+      $anchor = $this->view->tagAnchor($this->view->url(['module' => 'admin',
+                                                         'controller' => 'widget',
+                                                         'action' => 'edit-widget',
+                                                         'id' => $id_module,
+                                                         'id_profil' => Class_Profil::getCurrentProfil()->getId()], null, true),
+                                       Class_Admin_Skin::current()->renderActionIconOn('edit',
+                                                                                       $this->view,
+                                                                                       ['alt' => $this->_('Propriétés')]),
+                                       ['title' => $this->_('Propriétés'),
+                                        'data-popup' => 'true']);
+
+    return $this->_tag('li', $module . $anchor, ['data-value' => $type_module . '-' . $id_module]);
+  }
+
+
+  protected function _mainContainer() {
+    return
+      $this->_tag('h4', $this->_('Boites installées')) .
+      $this->_tag('div', implode($this->_mainContainerComposition()), ['class' => 'drag_drop_container']);
+  }
+
+
+  protected function _mainContainerComposition() {
+    if(Class_Profil::getCurrentProfil()->isTelephone())
+      return [$this->_getDivisionColumn(1, $this->_('Division téléphone'))];
+
+    return[$this->_getSideColumn(),
+           $this->_getBannerColumn(),
+           $this->_getDivionsColumns()];
+  }
+
+
+  protected function _getBannerColumn() {
+    return $this->_getDivisionColumn(4, $this->_('Banniere'));
+  }
+
+
+  protected function _getSideColumn() {
+    return $this->_getDivisionColumn(5, $this->_('Division flottante'));
+  }
+
+
+  protected function _getDivionsColumns() {
+    $nb_divisions = Class_Profil::getCurrentProfil()->getNbDivisions();
+    $columns = [];
+    for($i = 1; $i <= $nb_divisions; $i++)
+      $columns[] = $this->_getDivisionColumn($i, $this->_('Division %d', $i));
+
+    return implode($columns);
+  }
+
+
+  protected function _getDivisionColumn($column, $label) {
+    return
+      $this->_tag('div',
+                  $this->_tag('h5', $label) .
+                  $this->_tag('input', null, ['type' => 'hidden', 'name' => 'division' . $column]) .
+                  $this->_tag('ul',
+                              $this->_getHTMLForDivision($column),
+                              ['class' => 'container_list']),
+                  ['data-division' => $column,
+                   'data-divisions' => Class_Profil::getCurrentProfil()->getNbDivisions()]);
+  }
+
+
+  protected function _getHTMLForDivision($division) {
+    $profil = Class_Profil::getCurrentProfil();
+    $html = '';
+    $modules = $profil->getBoitesDivision($division);
+
+    foreach($modules as $id_module => $module)
+      $html .= $this->_getItemModule($module['type_module'],
+                                     Class_Systeme_ModulesAccueil::moduleByCode($module['type_module'])->getLibelle(),
+                                     $module['preferences'],
+                                     $id_module);
+    return $html;
+  }
+}
\ No newline at end of file
diff --git a/public/admin/css/config_accueil.css b/public/admin/css/config_accueil.css
index 9f8e2d9bbab3d7ea6023efd43845d1ae7a72ade1..8c221d237dddf9ff9f40b51e30d6e3bf6edb7f77 100644
--- a/public/admin/css/config_accueil.css
+++ b/public/admin/css/config_accueil.css
@@ -1,109 +1,89 @@
-/*
- * Boite drag and drop profil/portail
- */
+.modules .profile_composition {
+    font-size: 0.8em !important;
+}
 
-.modules td.cfg_accueil{font-size:10pt;color:#FF6600;}
-#footer{
-    clear:both;
+.profile_composition h4,
+.profile_composition h5 {
+    text-align: center;
+    margin: 0;
+    padding: 0;
+    text-transform: uppercase;
 }
-#footer form{
-    margin:0px;
-    margin-top:2px;
+
+.profile_composition ul {
+    margin: 0.5em;
+    padding: 0.2em;
+    box-shadow: 1px 1px 5px var(--widget-shadow);
 }
-#dhtmlgoodies_dragDropContainer ul{	/* General rules for all <ul> */
-    margin-top:0px;
-    margin-left:0px;
-    margin-bottom:0px;
-    padding:4px;
+
+.profile_composition li {
+    padding: 0.2em;
+    margin: 0.2em;
+    box-shadow: 1px 1px 5px var(--widget-shadow);
+    background-color: var(--widget-background);
 }
 
-#dhtmlgoodies_dragDropContainer li,#dragContent li,li#indicateDestination{	/* Movable items, i.e. <LI> */
+.profile_composition li {
     list-style-type:none;
-    background-color:#FFFFFF;
-    border:1px solid #738EAD;
-    padding:2px;
-    margin-bottom:2px;
     cursor:pointer;
-    font-size:0.9em;
 }
 
-li#indicateDestination{	/* Box indicating where content will be dropped - i.e. the one you use if you don't use arrow */
-    border:1px solid #738EAD;	
-    background-color:#FFF;
+.profile_composition ul {
+    min-height: 100px;
 }
 
-div#dhtmlgoodies_listOfItems div{
-    width: 100%;	/* IE 5.x */
-    border: 1px solid #738EAD;
+.profile_composition .drag_drop_container {
+    text-align: center;
 }
 
-#dhtmlgoodies_listOfItems div p{	/* Heading above left column */
-    margin:0px;	
-    font-weight:bold;
-    padding-left:12px;
-    background-color:#738EAD;	
-    color:#FFF;
-    margin-bottom:5px;
+.profile_composition .drag_drop_container > div {
+    display: inline-block;
+    text-align: left;
+    vertical-align: top;
+    width: 25%;
 }
-/* END LEFT COLUMN CSS */
 
-#dhtmlgoodies_dragDropContainer .mouseover{	/* Mouse over effect DIV box in right column */
-    border:1px solid #738EAD;
+.profile_composition .drag_drop_container > [data-division="1"][data-divisions="3"],
+.profile_composition .drag_drop_container > [data-division="3"][data-divisions="3"] {
+    width: 25%;
 }
 
-/* Start main container CSS */
-
-#dhtmlgoodies_mainContainer div{	/* Parent <div> of small boxes */
-    margin-bottom:10px;
-    margin-top:0px;
-    border:1px solid #738EAD;
+.profile_composition .drag_drop_container > [data-division="1"][data-divisions="2"],
+.profile_composition .drag_drop_container > [data-division="5"] {
+    width: 33%;
 }
 
-#dhtmlgoodies_mainContainer div p{	/* Heading above small boxes */
-    margin:0px;
-    padding:0px;
-    padding-left:12px;
-    font-weight:bold;
-    background-color:#738EAD;	
-    color:#FFF;	
-    margin-bottom:5px;
+.profile_composition .drag_drop_container > [data-division="2"][data-divisions="2"],
+.profile_composition .drag_drop_container > [data-division="4"] {
+    width: 66%;
 }
 
-#dhtmlgoodies_mainContainer ul{	/* Small box in right column ,i.e <ul> */
-    height:80px;	
-    border:0px;	
-    margin-bottom:0px;
-    overflow:hidden;
-    
+.profile_composition .drag_drop_container > [data-division="2"][data-divisions="3"] {
+    width: 50%;
 }
 
-#dragContent{	/* Drag container */
-    position:absolute;
-    width:180px;
-    height:20px;
-    display:none;
-    margin:0px;
-    padding:0px;
-    z-index:2000;
+.profile_composition .drag_drop_container > [data-division="1"][data-divisions="1"] {
+    width: 100%;
 }
 
-#dragDropIndicator{	/* DIV for the small arrow */
-    position:absolute;
-    width:7px;
-    height:10px;
-    display:none;
-    z-index:1000;
-    margin:0px;
-    padding:0px;
+.profile_composition .drag_drop_container > div a {
+    padding-left: 1em;
 }
 
+.profile_composition .drag_drop_container > div a img {
+    width: 12px;
+    height: 12px;
+}
 
-#dhtmlgoodies_mainContainer ul {
-    min-height: 300px;
-    height: auto;
+.profile_composition > div > div {
+    margin-bottom: 1em;
 }
 
+.profile_composition .source_list .placeholder {
+    display: none;
+}
 
-#dhtmlgoodies_mainContainer tr + tr ul {
-    min-height: 100px;
+.profile_composition .placeholder {
+    background: var(--anchor);
+    height: 1em;
 }
\ No newline at end of file
diff --git a/public/admin/css/global.css b/public/admin/css/global.css
index d64c0eb2f86bb3a7df2045819903d01deca1c596..07ebce1ee20d2a970918ee9ada184110504f7070 100644
--- a/public/admin/css/global.css
+++ b/public/admin/css/global.css
@@ -1544,6 +1544,11 @@ tr.modified > td + td + td {
     background-color: var(--previous-version-background);
 }
 
+body .required:after,
+body .error,
+body .errors,
+body .errors *,
+body .error *,
 tr.modified label,
 .modules a.modified {
     color: var(--error-text);
diff --git a/public/admin/js/config_accueil.js b/public/admin/js/config_accueil.js
deleted file mode 100644
index 50b554a3c1456871d78a939c2c947bacccfcf1b1..0000000000000000000000000000000000000000
--- a/public/admin/js/config_accueil.js
+++ /dev/null
@@ -1,388 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// OPAC 3 - Drag & drop page d'accueil config
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////		
-
-// VARIABLES YOU COULD MODIFY
-var boxSizeArray = [12,12,12,12,12,12,12,12];	// Array indicating how many items there is rooom for in the right column ULs
-
-var arrow_offsetX = -5;	// Offset X - position of small arrow
-var arrow_offsetY = 0;	// Offset Y - position of small arrow
-
-var arrow_offsetX_firefox = -6;	// Firefox - offset X small arrow
-var arrow_offsetY_firefox = -13; // Firefox - offset Y small arrow
-
-var verticalSpaceBetweenListItems = 3;	// Pixels space between one <li> and next
-var indicateDestionationByUseOfArrow = true;	// Display arrow to indicate where object will be dropped(false = use rectangle)
-
-var cloneSourceItems = true;	// Items picked from main container will be cloned(i.e. "copy" instead of "cut").
-var cloneAllowDuplicates = true;	// Allow multiple instances of an item inside a small box(example: drag Student 1 to team A twice
-var indicateDestinationBox = false; // La petite fleche 
-var nIdModuleMax=0  // Indice max pour affecter un id_module aux nouveaux objets
-
-// VARIABLES YOU SHOULD NOT MODIFY
-var dragDropTopContainer = false;
-var dragTimer = -1;
-var dragContentObj = false;
-var contentToBeDragged = false;	// Reference to dragged <li>
-var contentToBeDragged_src = false;	// Reference to parent of <li> before drag started
-var contentToBeDragged_next = false; 	// Reference to next sibling of <li> to be dragged
-var destinationObj = false;	// Reference to <UL> or <LI> where element is dropped.
-var dragDropIndicator = false;	// Reference to small arrow indicating where items will be dropped
-var ulPositionArray = new Array();
-var mouseoverObj = false;	// Reference to highlighted DIV
-var MSIE = navigator.userAgent.indexOf('MSIE')>=0?true:false;
-var navigatorVersion = navigator.appVersion.replace(/.*?MSIE (\d\.\d).*/g,'$1')/1;
-
-function getTopPos(inputObj)
-{		
-  var returnValue = inputObj.offsetTop;
-  while((inputObj = inputObj.offsetParent) != null){
-    if(inputObj.tagName!='HTML')returnValue += inputObj.offsetTop;
-  }
-  return returnValue;
-}
-
-function getLeftPos(inputObj)
-{
-  var returnValue = inputObj.offsetLeft;
-  while((inputObj = inputObj.offsetParent) != null){
-    if(inputObj.tagName!='HTML')returnValue += inputObj.offsetLeft;
-  }
-  return returnValue;
-}
-
-function cancelEvent()
-{
-  return false;
-}
-
-//--------------------------------------------------------------------------	
-// Mise a jour des proprietes
-//--------------------------------------------------------------------------	
-function majProprietes(oImg,sUrl,nLargeur,nHauteur)
-{
-  // Rechercher l'objet pere de type <li>
-  oParent=oImg;
-  while(true)
-  {
-    oParent=oParent.parentNode;
-    if(!oParent) { alert("Erreur javascript : config_accueil - Fonction : majProprietes"); return; }
-    if(oParent.nodeName =="LI") break;
-  }
-  // Completer l'url avec l'id_module et les proprietes
-  sUrl+='&type_module='+ oParent.id +'&id_module=' + oParent.getAttribute("id_module") + '&proprietes=' + oParent.getAttribute("proprietes") + '&render=popup';
-  opacDialogFromUrl(sUrl);
-}
-
-//--------------------------------------------------------------------------	
-// Retour de mise a jour des proprietes
-//--------------------------------------------------------------------------	
-function retourMajProprietes(nIdModule,sProprietes)
-{
-  setFlagMaj(true);
-  var listItems = dragDropTopContainer.getElementsByTagName('LI');	
-  for(var no=0;no<listItems.length;no++)
-  {
-    if(listItems[no].getAttribute("id_module") == nIdModule)
-    {
-      listItems[no].setAttribute("proprietes",sProprietes);
-      return;
-    }
-  }
-}
-
-//--------------------------------------------------------------------------	
-// Debut du drag
-//--------------------------------------------------------------------------	
-function initDrag(e)
-{
-  // Si click sur le bouton proprietes on laisse faire le onclick
-  if(e.target.src)
-  { 
-    return false;
-  }
-  if(document.all)e = event;
-  var st = Math.max(document.body.scrollTop,document.documentElement.scrollTop);
-  var sl = Math.max(document.body.scrollLeft,document.documentElement.scrollLeft);
-  dragTimer = 0;
-  dragContentObj.style.left = e.clientX + sl + 'px';
-  dragContentObj.style.top = e.clientY + st + 'px';
-  contentToBeDragged = this;
-  contentToBeDragged_src = this.parentNode;
-  contentToBeDragged_next = false;
-  if(this.nextSibling)
-  {
-    contentToBeDragged_next = this.nextSibling;
-    if(!this.tagName && contentToBeDragged_next.nextSibling)contentToBeDragged_next = contentToBeDragged_next.nextSibling;
-  }
-  timerDrag();
-  return false;
-}
-
-function timerDrag()
-{
-  if(dragTimer>=0 && dragTimer<10){
-    dragTimer++;
-    setTimeout('timerDrag()',10);
-    return;
-  }
-  if(dragTimer==10){
-
-    if(cloneSourceItems && contentToBeDragged.parentNode.id=='allItems'){
-      newItem = contentToBeDragged.cloneNode(true);
-      newItem.onmousedown = contentToBeDragged.onmousedown;
-      contentToBeDragged = newItem;
-    }
-    dragContentObj.style.display='block';
-    dragContentObj.appendChild(contentToBeDragged);
-  }
-}
-
-function moveDragContent(e)
-{
-  if(dragTimer<10)
-  {
-    if(contentToBeDragged)
-    {
-      if(contentToBeDragged_next) contentToBeDragged_src.insertBefore(contentToBeDragged,contentToBeDragged_next);
-      else contentToBeDragged_src.appendChild(contentToBeDragged);
-    }
-    return;
-  }
-  if(document.all)e = event;
-  var st = Math.max(document.body.scrollTop,document.documentElement.scrollTop);
-  var sl = Math.max(document.body.scrollLeft,document.documentElement.scrollLeft);
-
-  dragContentObj.style.left = e.clientX + sl + 'px';
-  dragContentObj.style.top = e.clientY + st + 'px';
-
-  if(mouseoverObj) mouseoverObj.className='';
-  destinationObj = false;
-  dragDropIndicator.style.display='none';
-  if(indicateDestinationBox)indicateDestinationBox.style.display='none';
-  var x = e.clientX + sl;
-  var y = e.clientY + st;
-  var width = dragContentObj.offsetWidth;
-  var height = dragContentObj.offsetHeight;
-
-  var tmpOffsetX = arrow_offsetX;
-  var tmpOffsetY = arrow_offsetY;
-  if(!document.all){
-    tmpOffsetX = arrow_offsetX_firefox;
-    tmpOffsetY = arrow_offsetY_firefox;
-  }
-
-  for(var no=0;no<ulPositionArray.length;no++){
-    var ul_leftPos = ulPositionArray[no]['left'];
-    var ul_topPos = ulPositionArray[no]['top'];
-    var ul_height = ulPositionArray[no]['height'];
-    var ul_width = ulPositionArray[no]['width'];
-
-    if((x+width) > ul_leftPos && x<(ul_leftPos + ul_width) && (y+height)> ul_topPos && y<(ul_topPos + ul_height)){
-      var noExisting = ulPositionArray[no]['obj'].getElementsByTagName('LI').length;
-      if(indicateDestinationBox && indicateDestinationBox.parentNode==ulPositionArray[no]['obj'])noExisting--;
-      if(noExisting<boxSizeArray[no-1] || no==0){
-	dragDropIndicator.style.left = ul_leftPos + tmpOffsetX + 'px';
-	var subLi = ulPositionArray[no]['obj'].getElementsByTagName('LI');
-
-	var clonedItemAllreadyAdded = false;
-	if(cloneSourceItems && !cloneAllowDuplicates){
-	  for(var liIndex=0;liIndex<subLi.length;liIndex++){
-	    if(contentToBeDragged.id == subLi[liIndex].id)clonedItemAllreadyAdded = true;
-	  }
-	  if(clonedItemAllreadyAdded)continue;
-	}
-
-	for(var liIndex=0;liIndex<subLi.length;liIndex++){
-	  var tmpTop = getTopPos(subLi[liIndex]);
-	  if(!indicateDestionationByUseOfArrow){
-	    if(y<tmpTop){
-	      destinationObj = subLi[liIndex];
-	      indicateDestinationBox.style.display='block';
-	      subLi[liIndex].parentNode.insertBefore(indicateDestinationBox,subLi[liIndex]);
-	      break;
-	    }
-	  }else{
-	    if(y<tmpTop){
-	      destinationObj = subLi[liIndex];
-	      dragDropIndicator.style.top = tmpTop + tmpOffsetY - Math.round(dragDropIndicator.clientHeight/2) + 'px';
-	      dragDropIndicator.style.display='block';
-	      break;
-	    }
-	  }
-	}
-
-	if(!indicateDestionationByUseOfArrow){
-	  if(indicateDestinationBox.style.display=='none'){
-	    indicateDestinationBox.style.display='block';
-	    ulPositionArray[no]['obj'].appendChild(indicateDestinationBox);
-	  }
-
-	}else{
-	  if(subLi.length>0 && dragDropIndicator.style.display=='none'){
-	    dragDropIndicator.style.top = getTopPos(subLi[subLi.length-1]) + subLi[subLi.length-1].offsetHeight + tmpOffsetY + 'px';
-	    dragDropIndicator.style.display='block';
-	  }
-	  if(subLi.length==0){
-	    dragDropIndicator.style.top = ul_topPos + arrow_offsetY + 'px'
-	    dragDropIndicator.style.display='block';
-	  }
-	}
-
-	if(!destinationObj)destinationObj = ulPositionArray[no]['obj'];
-	mouseoverObj = ulPositionArray[no]['obj'].parentNode;
-	mouseoverObj.className='mouseover';
-	return;
-      }
-    }
-  }
-}
-
-//--------------------------------------------------------------------------
-// Drop element ou retour a l'envoyeur
-//--------------------------------------------------------------------------	
-function dragDropEnd(e)
-{
-  if(dragTimer==-1)return;
-  if(dragTimer<10)
-  {
-    dragTimer = -1;
-    return;
-  }
-  dragTimer = -1;
-  if(document.all)e = event;
-  if(cloneSourceItems && !destinationObj && contentToBeDragged_src.id.substr(0,3)!="box" || (destinationObj && destinationObj.id=='allItems') || (destinationObj && destinationObj.parentNode.id=='allItems'))
-  {
-    contentToBeDragged.parentNode.removeChild(contentToBeDragged);
-  }
-  else
-  {
-    if(destinationObj)
-    {
-      setFlagMaj(true);
-      // Affecter un identifiant si nouvel element
-      if(contentToBeDragged_src.id == "allItems")
-      {
-	nIdModuleMax++;
-	contentToBeDragged.setAttribute("id_module",nIdModuleMax);
-	contentToBeDragged.setAttribute("new_module",true);
-        $(contentToBeDragged).mousedown(initDrag);
-	
-	// Afficher le picto pour les proprietes
-	oImg=contentToBeDragged;
-	while(true)
-	{
-	  oImg=oImg.lastChild;
-	  if(!oImg) { alert("Erreur javascript : config_accueil - Fonction : dragDropEnd"); return; }
-	  if(oImg.nodeName == "IMG") break;
-	}
-	oImg.style.display="block";
-      }
-      if(destinationObj.tagName=='UL') destinationObj.appendChild(contentToBeDragged);
-      else destinationObj.parentNode.insertBefore(contentToBeDragged,destinationObj);
-      mouseoverObj.className='';
-      destinationObj = false;
-      dragDropIndicator.style.display='none';
-      if(indicateDestinationBox)
-      {
-	indicateDestinationBox.style.display='none';
-	document.body.appendChild(indicateDestinationBox);
-      }
-      contentToBeDragged = false;
-      setFlagMaj(false);saveDragDropNodes();var form=$('div.form form');form.submit();
-      return;
-    }
-    if(contentToBeDragged_next) contentToBeDragged_src.insertBefore(contentToBeDragged,contentToBeDragged_next);
-    else contentToBeDragged_src.appendChild(contentToBeDragged);
-    setFlagMaj(false);saveDragDropNodes();var form=$('div.form form');form.submit();
-  }
-  contentToBeDragged = false;
-  dragDropIndicator.style.display='none';
-  if(indicateDestinationBox)
-  {
-    indicateDestinationBox.style.display='none';
-    document.body.appendChild(indicateDestinationBox);
-  }
-  setFlagMaj(false);saveDragDropNodes();var form=$('div.form form');form.submit();
-  mouseoverObj = false;
-}
-
-//--------------------------------------------------------------------------
-// Recup des donnees (bas�e sur la balise UL)
-//--------------------------------------------------------------------------
-function saveDragDropNodes()
-{
-  var saveString = "";
-  var uls = dragDropTopContainer.getElementsByTagName('UL');
-  for(var no=0;no<uls.length;no++)
-  {
-    var lis = uls[no].getElementsByTagName('LI');
-    for(var no2=0;no2<lis.length;no2++)
-    {
-      if(saveString.length>0)saveString = saveString + ";";
-      if(uls[no].id !="allItems") {
-	var id_module = lis[no2].getAttribute("id_module");
-	if (lis[no2].getAttribute("new_module") == 'true') id_module = 'new';
-	saveString = saveString + uls[no].id + '|' + id_module + "|" + lis[no2].id + "|" + lis[no2].getAttribute('proprietes');
-      }
-    }
-  }
-  document.getElementById('saveContent').innerHTML = saveString;
-}
-
-//--------------------------------------------------------------------------
-// Initialisation des evenements 
-//--------------------------------------------------------------------------	
-function initDragDropScript()
-{
-  dragContentObj = document.getElementById('dragContent');
-  dragDropIndicator = document.getElementById('dragDropIndicator');
-  dragDropTopContainer = document.getElementById('dhtmlgoodies_dragDropContainer');
-  document.documentElement.onselectstart = cancelEvent;
-  
-  // Get objets <li>
-  var listItems = dragDropTopContainer.getElementsByTagName('LI');	
-  var itemHeight = false;
-
-  //pour bug IE 7 & 8
-  $('#dhtmlgoodies_dragDropContainer LI').mousedown(initDrag);
-
-  for(var no=0;no<listItems.length;no++)
-  {
-    //		listItems[no].onmousedown = initDrag;
-    listItems[no].onselectstart = cancelEvent;
-    if(!itemHeight) itemHeight = listItems[no].offsetHeight;
-    if(MSIE && navigatorVersion/1<6) listItems[no].style.cursor='hand';
-    // Indice max
-    if(listItems[no].getAttribute("id_module") > nIdModuleMax) nIdModuleMax=listItems[no].getAttribute("id_module");
-  }
-  var mainContainer = document.getElementById('dhtmlgoodies_mainContainer');
-  var uls = mainContainer.getElementsByTagName('UL');
-  var leftContainer = document.getElementById('dhtmlgoodies_listOfItems');
-  var itemBox = leftContainer.getElementsByTagName('UL')[0];
-
-  document.documentElement.onmousemove = moveDragContent;	// Mouse move event - moving draggable div
-  document.documentElement.onmouseup = dragDropEnd;	// Mouse move event - moving draggable div
-
-  var ulArray = dragDropTopContainer.getElementsByTagName('UL');
-  for(var no=0;no<ulArray.length;no++)
-  {
-    ulPositionArray[no] = new Array();
-    ulPositionArray[no]['left'] = getLeftPos(ulArray[no]);
-    ulPositionArray[no]['top'] = getTopPos(ulArray[no]);
-    ulPositionArray[no]['width'] = ulArray[no].offsetWidth;
-    ulPositionArray[no]['height'] = ulArray[no].clientHeight;
-    ulPositionArray[no]['obj'] = ulArray[no];
-  }
-  if(!indicateDestionationByUseOfArrow)
-  {
-    indicateDestinationBox = document.createElement('LI');
-    indicateDestinationBox.id = 'indicateDestination';
-    indicateDestinationBox.style.display='none';
-    document.body.appendChild(indicateDestinationBox);
-  }
-}
-
-// Initialiser les objets au form load
-$(document).ready(initDragDropScript);
-
diff --git a/public/admin/js/global.js b/public/admin/js/global.js
index d40e4aba022ecdda7a7aa7c7a2811b41d2bcfd54..73060bc86da94d7679edd016884ccb24549de5ea 100644
--- a/public/admin/js/global.js
+++ b/public/admin/js/global.js
@@ -172,41 +172,44 @@ function getElementsByClassName(strClass, strTag, objContElm) {
 }
 
 
-function formSelectToggleVisibilityForElement(eventSourceSelector, objectToShowSelector, visibleForValues) {
-  if (!(visibleForValues instanceof Array)) visibleForValues = [visibleForValues];
-  toggleVisibilityForElement(eventSourceSelector, 
-			     objectToShowSelector, 
-			     function(element) {return ($.inArray(element.val(),visibleForValues) >= 0)} );
+function formSelectToggleVisibilityForElement(element, toggle, value) {
+  if (!(value instanceof Array))
+    value = [value];
+  
+  return toggleVisibilityForElement(element, 
+				    toggle, 
+				    function(element) {
+				      return 0 <= $.inArray(element.val(), value);
+				    });
 }
 
 
 
 function checkBoxToggleVisibilityForElement(eventSourceSelector, objectToShowSelector, visibleWhenChecked) {
-  toggleVisibilityForElement(eventSourceSelector, 
-			     objectToShowSelector, 
-			     function(element) {
-			       return visibleWhenChecked == ($(element).attr('checked') == 'checked');
-			     });
+  return toggleVisibilityForElement(eventSourceSelector, 
+				    objectToShowSelector, 
+				    function(element) {
+				      return visibleWhenChecked == ($(element).attr('checked') == 'checked');
+				    });
 }
 
 
 
 function toggleVisibilityForElement(eventSourceSelector, objectToShowSelector, testingAlgorithm) {
   var objectToShow = $(objectToShowSelector);
+  var source_object = $(eventSourceSelector);
   
-  var toggleVisibility = function(element) {
-    if (element.length == 0) return;
-    if (testingAlgorithm(element))
-      objectToShow.fadeIn();
-    else 
-      objectToShow.fadeOut();
+  var toggleVisibility = function() {
+    return testingAlgorithm(source_object)
+      ? objectToShow.fadeIn()
+      : objectToShow.fadeOut();
   }
 
-  toggleVisibility($(eventSourceSelector));
-  toggleVisibility($(eventSourceSelector+':checked'));
-  $(eventSourceSelector).change(function(event){
-    toggleVisibility($(event.target));
+  $(source_object).change(function() {
+    return toggleVisibility();
   });
+
+  source_object.change();
 }
 
 
diff --git a/public/admin/skins/bokeh74/global.css b/public/admin/skins/bokeh74/global.css
index d81b22f230892a3c8cb65c8b9b544e43111010f0..edc3817f05af177b0c2ac337c1ea3c062fbe2c5b 100755
--- a/public/admin/skins/bokeh74/global.css
+++ b/public/admin/skins/bokeh74/global.css
@@ -8,9 +8,11 @@ body {
     color: var(--nav-text);
 }
 
-.required:after,
-.error,
-.errors {
+body .required:after,
+body .error,
+body .errors,
+body .errors *,
+body .error * {
     color: var(--error-text);
 }
 
diff --git a/public/admin/skins/retro/global.css b/public/admin/skins/retro/global.css
index 2539f9c8f82770da387eb54ee6a1d7f2bbd7925b..d782284e4afc1cb670a11107c55e39709fa18f18 100755
--- a/public/admin/skins/retro/global.css
+++ b/public/admin/skins/retro/global.css
@@ -791,6 +791,11 @@ tr.modified > td + td + td {
     background-color: var(--previous-version-background);
 }
 
+body .required:after,
+body .error,
+body .errors,
+body .errors *,
+body .error *,
 tr.modified label,
 .modules a.modified {
     color: var(--error-text);
diff --git a/public/opac/js/input_connect_list/input_connect_list.js b/public/opac/js/input_connect_list/input_connect_list.js
index 787bce4da41f8cbd62e8c3b63f3607029b50c1e5..313da3f237d14de8f3de027ec671efde9050135a 100644
--- a/public/opac/js/input_connect_list/input_connect_list.js
+++ b/public/opac/js/input_connect_list/input_connect_list.js
@@ -99,3 +99,37 @@
     });
   };
 } (jQuery));
+
+
+(function ($) {
+  $.fn.draggableComposition = function(options) {
+    var widget = $(this);
+
+    var sources = widget.find('ul.source_list');
+    var containers = widget.find('ul.container_list');
+    var fixed = sources.html();
+    var lists = widget.find('ul');
+
+    containers.each(function() {
+      var values = "";
+      $(this).find('li').each(function() {
+	values +=  $(this).data("value") + ";";
+      });
+	$(this).closest('div').find('input').val(values)
+    });
+    
+    lists.sortable({
+      connectWith: 'ul',
+      placeholder: 'placeholder',
+      update: function(event, ui) {
+	var values = "";
+	$(event.target).closest('div').find('ul.container_list li').each(function() {
+	  values +=  $(this).data("value") + ";";
+	});
+	$(event.target).closest('div').find('input').val(values)
+	$(event.target).closest('form').submit();
+      }
+    });
+  };
+} (jQuery));
+
diff --git a/tests/application/modules/admin/controllers/ProfilControllerPageAccueilTest.php b/tests/application/modules/admin/controllers/ProfilControllerPageAccueilTest.php
index 19b11eb59072bb346d2ee6ca3ca9e15f6744d9fa..b4bedd19106f349831e8201ed069b2ab728ab7d2 100644
--- a/tests/application/modules/admin/controllers/ProfilControllerPageAccueilTest.php
+++ b/tests/application/modules/admin/controllers/ProfilControllerPageAccueilTest.php
@@ -112,7 +112,7 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
 
   /** @test **/
   public function boxFiveFlotantShouldBePresent() {
-    $this->assertXPath('//ul[@id="box5"]');
+    $this->assertXPath('//div[@data-division="5"]');
   }
 
 
@@ -124,72 +124,73 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
 
   /** @test **/
   public function boitePanierShouldBeInDivisionFive() {
-    $this->assertXPath('//ul[@id="box5"]/li[@id="PANIER"][@id_module="99"]//a[contains(@href, "admin/widget/edit-widget/id/99/id_profil/7")]');
+    $this->assertXPath('//div[@data-division="5"]//li[contains(@data-value, "PANIER-99")]//a[contains(@href, "admin/widget/edit-widget/id/99/id_profil/7")]');
   }
 
 
   /** @test */
   public function boitePretsShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="PRETS"]','prêts');
+    $this->assertXPathContentContains('//ul[@class="source_list"]/li[@data-value="PRETS-0"]','prêts');
   }
 
 
   /** @test */
   public function domainBrowserModuleShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="DOMAIN_BROWSER"]','domaines');
+    $this->assertXPathContentContains('//li','domaines');
   }
 
+
   /** @test */
   public function boitePretsShouldBeInDivisionOne() {
-    $this->assertXPath('//ul[@id="box1"]/li[@id="PRETS"][@id_module="9"]//a[contains(@href,"admin/widget/edit-widget/id/9/id_profil/7")]');
+    $this->assertXPath('//div[@data-division="1"]//li[contains(@data-value, "PRETS")]//a[contains(@href,"admin/widget/edit-widget/id/9/id_profil/7")]');
   }
 
 
   /** @test */
   public function boiteReservationsShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="RESERVATIONS"]','réservations');
+    $this->assertXPathContentContains('//li','réservations');
   }
 
 
   /** @test */
   public function boitePanierShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="PANIER"]','paniers');
+    $this->assertXPathContentContains('//li','paniers');
   }
 
 
   /** @test */
   public function boiteReservationsShouldBeInDivisionOne() {
-    $this->assertXPath('//ul[@id="box1"]/li[@id="RESERVATIONS"][@id_module="8"]//a[contains(@href,"admin/widget/edit-widget/id/8")]');
+    $this->assertXPath('//div[@data-division="1"]//li[@data-value="RESERVATIONS-8"]//a[contains(@href,"admin/widget/edit-widget/id/8")]');
   }
 
 
   /** @test */
   public function boiteHistoriqueRecherchesShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="HISTORIQUE_RECHERCHES"]','historique recherches');
+    $this->assertXPathContentContains('//li','historique recherches');
   }
 
 
   /** @test */
   public function boiteActivitiesShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="ACTIVITIES_WIDGET"]','activités');
+    $this->assertXPathContentContains('//li','activités');
   }
 
 
   /** @test */
   public function boiteActivitiesActionShouldBeActivitys() {
-    $this->assertXPath('//ul[@id="allItems"]/li[@id="ACTIVITIES_WIDGET"]//a[contains(@href, "admin/widget/edit-widget")]');
+    $this->assertXPath('//li//a[contains(@href, "admin/widget/edit-widget")]');
   }
 
 
   /** @test */
   public function boiteNewsShouldBeInDivisionOne() {
-    $this->assertXPath('//ul[@id="box1"]/li[@id="NEWS"][@id_module="2"]');
+    $this->assertXPath('//div[@data-division="1"]//li[contains(@data-value, "NEWS")]');
   }
 
 
   /** @test */
   public function boiteKiosqueShouldBeInDivisionTwo() {
-    $this->assertXPath('//ul[@id="box2"]/li[@id="KIOSQUE"][@id_module="3"]');
+    $this->assertXPath('//div[@data-division="2"]//li[contains(@data-value, "KIOSQUE")]');
   }
 
 
@@ -201,15 +202,10 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
 
   /** @test */
   public function boiteCritiquesShouldBeInDivisionTwo() {
-    $this->assertXPath('//ul[@id="box2"]/li[@id="CRITIQUES"][@id_module="6"]');
+    $this->assertXPath('//div[@data-division="2"]//li[contains(@data-value, "CRITIQUES")]') ;
   }
 
 
-  /** @test */
-  public function preferencesBoiteKiosqueShouldBeEncodedInAttributeProprietes() {
-    $this->assertXPath('//li[@id_module="3"][contains(@proprietes,"nb_notices%3D12---only_img%3D1---aleatoire%3D1")]');
-  }
-
 
   /** @test **/
   public function useParentCssCheckboxShouldBeChecked() {
@@ -228,13 +224,11 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
     $this->assertXPath('//input[@name="page_css"][contains(@value,"")]',$this->_response->getBody());
   }
 
+
   /** @test */
   public function postingDataWithSitemapModification() {
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost(array('sitemap' => 0));
-    $this->dispatch('/admin/profil/accueil/id_profil/7');
+    $this->postDispatch('/admin/profil/accueil/id_profil/7', ['libelle' => 'page',
+                                                              'sitemap' => 0]);
 
     $this->assertTrue($this->profil_wrapper->methodHasBeenCalled('save'));
     $this->assertRedirect('/admin/profil/accueil/id_profil/7');
@@ -242,6 +236,7 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
     return $this->profil_jeunesse;
   }
 
+
   /**
    * @depends postingDataWithSitemapModification
    * @test
@@ -254,13 +249,9 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
 
   /** @test */
   public function postingDataWithNoModifications() {
-    $cfg_module = 'box1|2|NEWS|;box2|3|KIOSQUE|nb_notices=12---nb_analyse=36---only_img=1---;box2|6|CRITIQUES|';
-
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost(array('saveContent' => $cfg_module));
-    $this->dispatch('/admin/profil/accueil/id_profil/7');
+    $this->postDispatch('/admin/profil/accueil/id_profil/7', ['libelle' => 'page',
+                                                              'division1' => 'NEWS-2',
+                                                              'division2' => 'KIOSQUE-3;CRITIQUES-6']);
 
     $this->assertTrue($this->profil_wrapper->methodHasBeenCalled('save'));
     $this->assertRedirect('/admin/profil/accueil/id_profil/7');
@@ -274,10 +265,7 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
    * @test
    */
   public function shouldPutDefaultNewsPrefereces($profil_jeunesse) {
-    $news = $profil_jeunesse->getModuleAccueilConfig(2, 'NEWS');
-    $this->assertEquals(1, $news['division']);
-    $this->assertEquals('NEWS', $news['type_module']);
-    $this->assertEquals('Boite articles', $news['preferences']['titre']);
+    $this->assertContains('Boite articles', $profil_jeunesse->getModulePref(2));
   }
 
 
@@ -305,33 +293,19 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
   }
 
 
-  /** @test */
-  public function postingDataWithBoiteDeuxColonnes() {
-    $cfg_module = 'box2|3|KIOSQUE|nb_notices=12/nb_analyse=36/only_img=1/;box2|6|CRITIQUES|;box2|new|CONTENEUR_DEUX_COLONNES|';
-
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost(array('saveContent' => $cfg_module));
-    $this->dispatch('/admin/profil/accueil/id_profil/7');
-
-    $this->assertTrue($this->profil_wrapper->methodHasBeenCalled('save'));
-    $this->assertRedirect('/admin/profil/accueil/id_profil/7');
-
-    return $this->profil_jeunesse;
-  }
-
-
   /**
-   * @depends postingDataWithBoiteDeuxColonnes
    * @test
    */
-  public function boiteDeuxColonnesShouldGetIdFourAndDefaultValues($profil_jeunesse) {
-    $b2cols = $profil_jeunesse->getModuleAccueilConfig(4, 'CONTENEUR_DEUX_COLONNES');
-    $this->assertEquals(2, $b2cols['division']);
-    $this->assertEquals('CONTENEUR_DEUX_COLONNES', $b2cols['type_module']);
-    $this->assertEquals('NEWS', $b2cols['preferences']['col_gauche_type']);
-    $this->assertEquals('CRITIQUES', $b2cols['preferences']['col_droite_type']);
+  public function boiteDeuxColonnesShouldGetIdFourAndDefaultValues() {
+    $this->postDispatch('/admin/profil/accueil/id_profil/7',
+                        ['libelle' => 'page',
+                         'division2' => 'KIOSQUE-3;CRITIQUES-6;CONTENEUR_DEUX_COLONNES-0']);
+
+    $profil_jeunesse = Class_Profil::find(7);
+    $b2cols = $profil_jeunesse->getModulePref(4);
+    $this->assertContains('Boite deux colonnes', $b2cols);
+    $this->assertContains('NEWS', $b2cols);
+    $this->assertContains('CRITIQUES', $b2cols);
   }
 }
 
@@ -340,48 +314,53 @@ class Admin_ProfilControllerPageAccueilJeunesseTest extends Admin_ProfilControll
 class ProfilControllerPageAccueilWithTelephonePackMobileTest extends Admin_AbstractControllerTestCase {
   public function setUp() {
     parent::setUp();
-
-    Class_AdminVar::getLoader()->newInstanceWithId('PACK_MOBILE')
-                               ->setValeur(1);
-
-    Class_AdminVar::getLoader()->newInstanceWithId('BIB_NUMERIQUE')
-                               ->setValeur(1);
-
-    $profil_telephone = Class_Profil::getLoader()
-      ->newInstanceWithId(3)
-      ->setLibelle('iPhone')
-      ->beTelephone();
-    $this->dispatch('/admin/profil/accueil/id_profil/3');
+    $this->fixture('Class_AdminVar',
+                   ['id' => 'PACK_MOBILE',
+                    'valeur' => 1]);
+    $this->fixture('Class_AdminVar',
+                   ['id' => 'BIB_NUMERIQUE',
+                    'valeur' => 1]);
+    $profil = $this->fixture('Class_Profil',
+                   ['id' => 3,
+                    'libelle' => 'iphone']);
+    $profil->beTelephone();
+    $this->dispatch('/admin/profil/accueil/id_profil/3', true);
   }
 
 
   /** @test */
   public function moduleNewsShouldBeAvailable() {
-    $this->assertXPath('//ul/li[@id="NEWS"]');
+    $this->assertXPath('//li[@data-value="NEWS-0"]');
   }
 
 
   /** @test */
   public function moduleBibNumeriqueShouldBeAvailable() {
-    $this->assertXPath('//ul/li[@id="BIB_NUMERIQUE"]');
+    $this->assertXPath('//ul/li[@data-value="BIB_NUMERIQUE-0"]');
   }
 
 
   /** @test */
   public function moduleCritiquesShouldBeAvailable() {
-    $this->assertXPath('//ul/li[@id="CRITIQUES"]');
+    $this->assertXPath('//ul/li[@data-value="CRITIQUES-0"]');
   }
 
 
   /** @test */
   public function moduleKiosqueShouldBeAvailable() {
-    $this->assertXPath('//ul/li[@id="KIOSQUE"]');
+    $this->assertXPath('//ul/li[@data-value="KIOSQUE-0"]');
   }
 
 
   /** @test */
   public function moduleLoginShouldNotBeAvailable() {
-    $this->assertNotXPath('//ul/li[@id="LOGIN"]');
+    $this->assertNotXPath('//ul/li[@data-value="LOGIN-0"]');
+  }
+
+
+  /** @test */
+  public function onlyDivision2shouldBeDisplayed() {
+    $this->assertXPath('//div[@class="drag_drop_container"]/div[1][@data-division="1"]');
   }
 }
 
@@ -400,13 +379,13 @@ class ProfilControllerPageAccueilWithTelephoneNoPackMobileNoBibNumTest extends A
 
     $this->profil_jeunesse->beTelephone();
 
-    $this->dispatch('/admin/profil/accueil/id_profil/'.$this->profil_jeunesse->getId());
+    $this->dispatch('/admin/profil/accueil/id_profil/'.$this->profil_jeunesse->getId(), true);
   }
 
 
   /** @test */
   public function moduleNewsShouldBeAvailable() {
-    $this->assertXPath('//ul/li[@id="NEWS"]');
+    $this->assertXPath('//ul/li[@data-value="NEWS-0"]');
   }
 
 
@@ -494,7 +473,7 @@ class Admin_ProfilControllerPageAccueilJeunesseWithPageCssNouveauteTest extends
 
   /** @test **/
   public function pageCssShoudBeNouveauCss() {
-    $this->assertXPath('//input[@name="page_css"][contains(@value, "nouveaute.css")]',$this->_response->getBody());
+    $this->assertXPath('//input[@name="page_css"][contains(@value, "nouveaute.css")]');
   }
 }
 
@@ -549,7 +528,7 @@ class Admin_ProfilControllerPageAccueilNoPanierTest extends Admin_ProfilControll
 
   /** @test **/
   public function boitePanierShouldHaveBeenAddedInDivision5() {
-    $this->assertXPath('//ul[@id="box5"]/li[@id="PANIER"]');
+    $this->assertXPath('//div[@data-division="5"]//li[contains(@data-value, "PANIER")]');
   }
 }
 
@@ -611,7 +590,7 @@ class Admib_ProfilControllerPageAccueilWithWidgetInBannerPostDispatchTest extend
 
   public function setUp() {
     parent::setUp();
-    $this->postDispatch('/admin/profil/accueil/id_profil/3', []);
+    $this->postDispatch('/admin/profil/accueil/id_profil/3', ['libelle' => 'test']);
 
   }
 
@@ -633,7 +612,7 @@ class Admib_ProfilControllerPageAccueilWithWidgetInBannerPostDispatchTest extend
 
 
 
-class Admin_ProfilControllerPageAccueilWithMenuBoiteEnabledTest extends Admin_AbstractControllerTestCase {
+class Admin642_ProfilControllerPageAccueilWithMenuBoiteEnabledTest extends Admin_AbstractControllerTestCase {
   public function setUp() {
     parent::setUp();
 
@@ -650,14 +629,13 @@ class Admin_ProfilControllerPageAccueilWithMenuBoiteEnabledTest extends Admin_Ab
 
     $this->fixture('Class_AdminVar',['id'=>'MENU_BOITE', 'valeur' => 1]);
 
-    $cfg_module = "box1|2|NEWS|titre=Articles---type_aff=1---id_categorie=---id_items=---nb_aff=1---nb_analyse=5---display_order=Selection---display_titles_only=---rss_avis=1---op_largeur_img=200---op_hauteur_boite=400---boite=---=---;box1|3|NEWS|titre=Articles---type_aff=1---id_categorie=---id_items=---nb_aff=1---nb_analyse=5---display_order=Selection---display_titles_only=---rss_avis=1---op_largeur_img=200---op_hauteur_boite=400---boite=---=---;box1|1|KIOSQUE|titre=Kiosque---style_liste=slide_show---nb_notices=20---only_img=1---aleatoire=1---tri=1---nb_analyse=50---op_hauteur_img=0---op_transition=---op_largeur_img=0---op_hauteur_boite=0---op_captions=0---op_autoplay=0---op_visible=0---op_speed=0---op_auto=0---op_scroll=1---rss_avis=1---id_catalogue=0---id_panier=0---profil_redirect=---boite=---=---;box1|4|KIOSQUE|titre=Kiosque---style_liste=slide_show---nb_notices=20---only_img=1---aleatoire=1---tri=1---nb_analyse=50---op_hauteur_img=0---op_transition=---op_largeur_img=0---op_hauteur_boite=0---op_captions=0---op_autoplay=0---op_visible=0---op_speed=0---op_auto=0---op_scroll=1---rss_avis=1---id_catalogue=0---id_panier=0---profil_redirect=---boite=---=---;box2|8|MENU_VERTICAL|menu=V---afficher_titre=1---menu_deplie=0---new_html=0---boite=---titre=---=---;box2|5|MENU_VERTICAL|menu=V---afficher_titre=1---menu_deplie=0---new_html=0---boite=---titre=---=---;box3|10|PANIER|titre=Favoris---boite=---=---;box3|new|PANIER|;box4|6|LOGIN|titre=Mon compte lecteur---titre_connecte=---identifiant=N° de carte---identifiant_exemple=---mot_de_passe=Année de naissance---mot_de_passe_exemple=---lien_connexion=Se connecter---lien_mot_de_passe_oublie=» Mot de passe oublié ?---lien_creer_compte=» S'enregistrer---message_connecte=Bienvenue---lien_compte=Mon compte---lien_deconnection=Se déconnecter---autocomplete_off=1---profil_redirect=---profil_logout_redirect=---boite=boite_banniere_droite---";
-
+    $cfg_module = "box3|new|PANIER|;box4|6|LOGIN|titre=Mon compte lecteur---titre_connecte=---identifiant=N° de carte---identifiant_exemple=---mot_de_passe=Année de naissance---mot_de_passe_exemple=---lien_connexion=Se connecter---lien_mot_de_passe_oublie=» Mot de passe oublié ?---lien_creer_compte=» S'enregistrer---message_connecte=Bienvenue---lien_compte=Mon compte---lien_deconnection=Se déconnecter---autocomplete_off=1---profil_redirect=---profil_logout_redirect=---boite=boite_banniere_droite---";
 
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost(array('saveContent' => $cfg_module));
-    $this->dispatch('/admin/profil/accueil/id_profil/713');
+    $this->postDispatch('/admin/profil/accueil/id_profil/713', ['libelle' => 'test',
+                                                                'division1' => 'NEWS-2;NEWS-3;KIOSQUE-1;KIOSQUE-4;',
+                                                                'division2' => 'MENU_VERTICAL-5;CALENDAR-0',
+                                                                'division3' => 'PANIER-10;PANIER-0',
+                                                                'division4' => 'LOGIN-6']);
   }
 
 
@@ -668,9 +646,10 @@ class Admin_ProfilControllerPageAccueilWithMenuBoiteEnabledTest extends Admin_Ab
     $this->assertCount(9, $cfg_accueil['modules']);
   }
 
+
   /** @test */
-  public function moduleTenTitleShouldBeFavoris() {
-    $this->assertEquals('Favoris',
+  public function moduleTenTitleShouldBePanier() {
+    $this->assertEquals('Panier',
                         Class_Profil::find(713)->getModuleAccueilPreferences(10, 'PANIER')['titre']);
   }
 }
@@ -681,28 +660,18 @@ class Admin_ProfilControllerPageAccueilRegression45558Test extends Admin_ProfilC
 
   public function setUp() {
     parent::setUp();
-    $post_cfg = 'box1|2|NEWS|menu%3D15-1---afficher_titre%3D1---menu_deplie%3D0---new_html%3D0---boite%3D---titre%3D%2A%2A+Nouvelle+bo%C3%AEte+%2A%2A---id_module%3D3---Valider%3DValider---%3D';
-
-
     $this->fixture('Class_Profil', ['id' => 23,
                                     'libelle' => 'My page']);
+
     $this->postDispatch('/admin/profil/accueil/id_profil/23',
-                        ['saveContent' => $post_cfg]);
+                        ['libelle' => 'My page',
+                         'division1' => 'NEWS-0;']);
   }
 
 
   /** @test */
   public function menuWidgetTitleShouldBeNouvelleBoite() {
-    $this->assertEquals('** Nouvelle boîte **',
-                        Class_Profil::find(23)->getModuleAccueilPreferences(2, 'MENU')['titre']);
-  }
-
-
-  /** @test */
-  public function menuWidgetAfficherTitreShouldBeOne() {
-    $this->assertEquals('1',
-                        Class_Profil::find(23)->getModuleAccueilPreferences(2, 'MENU')['afficher_titre']);
+    $this->assertContains('Boite articles',
+                          Class_Profil::find(23)->getModulePref(1));
   }
 }
-
-?>
\ No newline at end of file
diff --git a/tests/application/modules/admin/controllers/ProfilControllerTest.php b/tests/application/modules/admin/controllers/ProfilControllerTest.php
index 21264e781dd64908f424497821b4bd03a7230eee..b08441520db001a14ad464c86b19338dbaca0a38 100644
--- a/tests/application/modules/admin/controllers/ProfilControllerTest.php
+++ b/tests/application/modules/admin/controllers/ProfilControllerTest.php
@@ -97,7 +97,7 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
                                      ->mkdir(Class_Admin_Skin::DEFAULT_ADMIN_PATH . Class_Admin_Skin::DEFAULT_ADMIN_SKIN)
                                      ->mkdir(Class_Admin_Skin::DEFAULT_ADMIN_PATH . Class_Admin_Skin::DEFAULT_ADMIN_SKIN . '/' . Class_Admin_Skin::ADMIN_COLORS_FOLDER));
 
-    $this->dispatch('/admin/profil/edit/id_profil/5');
+    $this->dispatch('/admin/profil/edit/id_profil/5', true);
   }
 
 
@@ -121,7 +121,7 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
   /** @test */
   public function allowInputDivision1PercentAndPixels() {
-    $this->assertXPathContentContains("//select[@name='width_division1_scale']","pixels",$this->_response->getBody());
+    $this->assertXPathContentContains("//select[@name='width_division1_scale']","pixels");
   }
 
 
@@ -166,11 +166,12 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
     $this->assertXPath('//select[@name="id_site"]');
   }
 
-/** @test */
+  /** @test */
   public function division3ShouldHaveVisibilityOption() {
-    $this->assertXPathContentContains('//td','Toujours visible');
+    $this->assertXPathContentContains('//form','toujours visible');
   }
 
+
   /** @test */
   public function textInputHeaderImgShouldContainsPathToJeunessePng() {
     $this->assertXPath("//input[@type='text'][@name='header_img'][@value='/public/jeunesse.png']");
@@ -242,12 +243,12 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
   /** @test */
   public function radioButtonOrdreDivision123ShouldNotBeChecked() {
-    $this->assertXPath("//input[@type='radio'][@name='ordre_divisions'][@value='0'][not(@checked)]");
+    $this->assertXPath("//select[@name='ordre_divisions']/option[@value='0']");
   }
 
   /** @test */
   public function radioButtonOrdreDivision321ShouldBeChecked() {
-    $this->assertXPath("//input[@type='radio'][@name='ordre_divisions'][@value='1'][@checked='checked']");
+    $this->assertXPath("//select[@name='ordre_divisions']/option[@value='1'][@selected]");
   }
 
   /** @test */
@@ -263,7 +264,7 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
   /** @test */
   public function divisionThreeVisibleShouldBeChecked() {
-    $this->assertXPath("//input[@type='checkbox'][@name='division_three_always_visible'][@checked='checked']",$this->_response->getBody());
+    $this->assertXPath("//input[@type='checkbox'][@name='division_three_always_visible'][@checked='checked']");
   }
 
   /** @test */
@@ -279,13 +280,13 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
   /** @test */
   public function mailSuggestionAchatsShouldContainsSuggestionAtHergeDotBe() {
-    $this->assertXPath("//input[@type='text'][@name='mail_suggestion_achat'][@value='suggestion@herge.be']");
+    $this->assertXPath("//input[@type='email'][@name='mail_suggestion_achat'][@value='suggestion@herge.be']");
   }
 
 
   /** @test */
   public function mailSiteShouldContainsTintinAtHergeDotBe() {
-    $this->assertXPath("//input[@type='text'][@name='mail_site'][@value='tintin@herge.be']");
+    $this->assertXPath("//input[@type='email'][@name='mail_site'][@value='tintin@herge.be']");
   }
 
 
@@ -310,13 +311,9 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
   /** @test */
   public function postingLiensOff_BibTwoRedirectsToProfilIndex() {
-    $data = array(  'liens_sortants_off' => 0,
-                  'id_site' => 2);
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost($data);
-    $this->dispatch('/admin/profil/edit/id_profil/5');
+    $this->postDispatch('/admin/profil/edit/id_profil/5', ['libelle' => 'test',
+                                                           'liens_sortants_off' => 0,
+                                                           'id_site' => 2]);
 
     $this->assertController('profil');
     $this->assertAction('edit');
@@ -344,11 +341,7 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
 
   public function _postData($data) {
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost($data);
-    $this->dispatch('/admin/profil/edit/id_profil/5', true);
+    $this->postDispatch('/admin/profil/edit/id_profil/5', $data);
   }
 
 
@@ -365,8 +358,9 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
   /** @test */
   public function postingBoitesBanniereAndLoginShouldUpdateCreateThem() {
-    $this->_postData(array( 'boite_login_in_banniere' => false,
-                           'boite_recherche_simple_in_banniere' => true));
+    $this->_postData(['libelle' => 'test',
+                      'boite_login_in_banniere' => false,
+                      'boite_recherche_simple_in_banniere' => true]);
 
     $this->assertFalse($this->profil_jeunesse->getBoiteLoginInBanniere());
     $this->assertTrue($this->profil_jeunesse->getBoiteRechercheSimpleInBanniere());
@@ -380,7 +374,7 @@ class Admin_ProfilControllerEditProfilJeunesseTest extends Admin_ProfilControlle
 
     $this->assertFalse($this->profil_wrapper->methodHasBeenCalled('save'));
     $this->assertXPathContentContains('//ul[@class="errors"]//li',
-                                      'est obligatoire');
+                                      'Une valeur est requise');
   }
 
 
@@ -563,16 +557,19 @@ class Admin_ProfilControllerEditProfilVideTest extends Admin_AbstractControllerT
     $this->dispatch('/admin/profil/edit/id_profil/34');
   }
 
+
   /** @test */
   public function textInputNamedHauteurBanniereShouldBeDisplayed() {
     $this->assertXPath("//input[@type='text'][@name='hauteur_banniere'][@value='100']");
   }
 
+
   /** @test */
   public function checkBoxAccessibiliteOnShouldBeChecked() {
     $this->assertXPath("//input[@type='checkbox'][@name='accessibilite_on'][@checked='checked']");
   }
 
+
   /** @test */
   public function checkBoxLiensSortantsOffShouldBeNotChecked() {
     $this->assertXPath("//input[@type='checkbox'][@name='liens_sortants_off'][not(@checked)]");
@@ -609,16 +606,10 @@ class Admin_ProfilControllerEditProfilVideTest extends Admin_AbstractControllerT
 
   /** @test */
   public function postingDataWithWrongData() {
-    $data = array('libelle' => '',
-                  'largeur_site' => 200,
-                  'largeur_division1' => 100,
-                  'largeur_division2' => 500
-    );
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost($data);
-    $this->dispatch('/admin/profil/edit/id_profil/34');
+    $this->postDispatch('/admin/profil/edit/id_profil/34', ['libelle' => 'test',
+                                                            'largeur_site' => 200,
+                                                            'largeur_division1' => 100,
+                                                            'largeur_division2' => 500]);
     return $this->profil_vide;
   }
 
@@ -797,25 +788,13 @@ class Admin_ProfilControllerAddProfilHistoireTest extends Admin_AbstractControll
 
   /** @test */
   public function profilShouldNotBeSavedIfPostingLargeurTooLow() {
-    $wrapper = Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Profil');
-
-    $data = array(  'libelle' => "Histoire",
-                  'id_site' => 1,
-                  'largeur_site' => 100);
-
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost($data);
-    $this->dispatch('/admin/profil/add');
-    $this->assertAction('add');
-
-    $this->assertFalse($wrapper->methodHasBeenCalled('save'));
-    $this->assertXPathContentContains('//ul[@class="errors"]//li',
-                                      'La largeur du site doit' /*être comprise entre 800 et 2000 pixels.*/,
-                                      $this->_response->getBody());
+    $this->postDispatch('/admin/profil/add',
+                        ['libelle' => "Histoire",
+                         'id_site' => 1,
+                         'largeur_site' => 100]);
+    $this->assertXPathContentContains('//form',
+                                      'La largeur du site doit' /*être comprise entre 800 et 2000 pixels.*/);
   }
-
 }
 
 
@@ -1010,7 +989,7 @@ class Admin_ProfilControllerListProfilsJeunesseWithPagesTest extends Admin_Profi
 class Admin_ProfilControllerEditProfilJeunesseWithPagesTest extends Admin_ProfilControllerProfilPanelTest {
   public function setUp() {
     parent::setUp();
-    $this->dispatch('/admin/profil/edit/id_profil/5');
+    $this->dispatch('/admin/profil/edit/id_profil/5', true);
   }
 }
 
@@ -1022,7 +1001,7 @@ class Admin_ProfilControllerEditAccueilPageMusiqueTest extends Admin_ProfilContr
     parent::setUp();
 
     $this->page_musique->setRewriteUrl('musique');
-    $this->dispatch('/admin/profil/accueil/id_profil/23');
+    $this->dispatch('/admin/profil/accueil/id_profil/23', true);
   }
 
 
@@ -1064,13 +1043,11 @@ class Admin_ProfilControllerPostAccueilPageMusiqueTest extends Admin_ProfilContr
 
     $cfg_module = 'box1|new|KIOSQUE|nb_notices=12/nb_analyse=36/only_img=1/;box2|new|CRITIQUES|';
 
-    $this
-      ->getRequest()
-      ->setMethod('POST')
-      ->setPost(['saveContent' => $cfg_module,
-                 'libelle' => 'Bonne Musique',
-                 'rewrite_url' => 'music']);
-    $this->dispatch('/admin/profil/accueil/id_profil/23');
+    $this->postDispatch('/admin/profil/accueil/id_profil/23',
+                        ['libelle' => 'Bonne Musique',
+                         'rewrite_url' => 'music',
+                         'division1' => 'KIOSQUE-0',
+                         'division2' => 'CRITIQUES-0']);
   }
 
 
@@ -1138,9 +1115,10 @@ class Admin_ProfilControllerPostAccueilPageMusiqueWithErrorsTest extends Admin_P
                                                                  'preferences' => []]]]);
 
     $this->postDispatch('/admin/profil/accueil/id_profil/23',
-                        ['saveContent' => 'box1|new|KIOSQUE|nb_notices=12/nb_analyse=36/only_img=1/;box2|new|CRITIQUES|',
+                        ['division1' => 'KIOSQUE-0',
+                         'division2' => 'CRITIQUES-0',
                          'libelle' => 'Bonne Musique',
-                         'rewrite_url' => 'music +(«8'], true);
+                         'rewrite_url' => 'music +(«8']);
   }
 
 
@@ -1165,17 +1143,13 @@ class Admin_ProfilControllerPostAccueilPageMusiqueWithErrorsTest extends Admin_P
 
   /** @test */
   public function domainBrowserModuleShouldBeAvailable() {
-    $this->assertXPathContentContains('//ul[@id="allItems"]/li[@id="DOMAIN_BROWSER"]','domaines');
+    $this->assertXPathContentContains('//li','domaines');
   }
 
 
   /** @test */
-  public function boiteKiosqueShouldBeInDivisionOne() {
-    $this->assertXPath('//ul[@id="box1"]/li[@id="KIOSQUE"]');
-  }
-
-  public function boiteCritiquesShouldBeInDivisionTwo() {
-    $this->assertXPath('//ul[@id="box1"]/li[@id="CRITIQUES"]');
+  public function boiteSearchShouldBeInDivision4() {
+    $this->assertXPath('//div[@data-division="4"]//li[contains(@data-value, "RECH")]');
   }
 }
 
@@ -1509,8 +1483,7 @@ class Admin_ProfilControllerProfilPortalLoginPageTest extends Admin_AbstractCont
 
   /** @test */
   public function loginPageSelectShouldBePresent() {
-    $this->assertXPath('//select[@name="login_page"]//option[@value=""]',
-                       $this->_response->getBody());
+    $this->assertXPath('//select[@name="login_page"]//option[@value=""]');
   }
 
 
@@ -1636,15 +1609,15 @@ class ProfilControllerPostDispatchAccueilProfilTest extends Admin_AbstractContro
                         ['libelle' => 'new title',
                          'use_parent_css' => 1,
                          'page_css' => '',
-                         'saveContent' => 'box2|5|CALENDAR|titre=Calendrier+des+animations---id_categorie=---display_cat_select=---display_event_info=bib---rss_avis=0---display_next_event=1---display_order=EventDebut---display_mode=Title---nb_events=3---display_calendar=1---mode-affichage=simple---event_filter=none---enabled_filters=date;place;custom_field_1;custom_field_2---boite=---id_items=---Valider=Valider---;box1|1|RESERVATIONS|titre=Mes+réservations---boite=---=---;box2|2|PRETS|titre=Mes+prêts---boite=---=---;box2|3|NEWSLETTERS|titre=Newsletters---boite=---=---;box2|4|MULTIMEDIA|titre=Postes+multimédia---boite=---=---']);
+                         'division1' => 'CALENDAR-1',
+                         'division2' => 'CALENDAR-0;PRETS-0;NEWSLETTERS-0;MULTIMEDIA-0']);
   }
 
 
   /** @test */
   public function cfgModuleShouldContainsCalendarFiltersDatePlaceAndCustomFilters() {
-    $prefs = Class_Profil::find(1)->getModuleAccueilPreferences(5, 'CALENDAR');
-    $this->assertEquals('date;place;custom_field_1;custom_field_2',
-                        $prefs['enabled_filters']);
+    $prefs = Class_Profil::find(1)->getModuleAccueilPreferences(2, 'CALENDAR');
+    $this->assertContains('Boite calendrier', $prefs);
 
   }
 
diff --git a/tests/library/Class/ProfilTest.php b/tests/library/Class/ProfilTest.php
index 22513b4cac40647fb2b10d9fd0e8818a38bddc32..ca013886672b32ce7df064d9a297166fa876a68b 100644
--- a/tests/library/Class/ProfilTest.php
+++ b/tests/library/Class/ProfilTest.php
@@ -856,7 +856,6 @@ class ProfilAdulteChatenayTest extends ProfilAdulteChatenayTestCase  {
   }
 
 
-
   /** @test */
   public function savePageWithSameRewriteUrlAsAnotherPageWithoutParentShouldBeValid() {
     $this->fixture('Class_Profil', ['id' => 375,