]> _ Git - fluidbook-toolbox.git/commitdiff
wip #4211 @1
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 7 Mar 2022 16:22:28 +0000 (17:22 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Mon, 7 Mar 2022 16:22:28 +0000 (17:22 +0100)
.idea/workspace.xml
app/Console/Commands/WorkshopMigration.php
app/Models/FluidbookPublication.php

index 1cc6101f7b934969b4b7a3e637e7b1cd4f5e0b31..afce2109588d2f66998302aff7e1e09948380c1b 100644 (file)
     <select />
   </component>
   <component name="ChangeListManager">
-    <list default="true" id="5d2ecd5e-a05a-4f96-a195-fa6372618165" name="Default Changelist" comment="wip #5041 @1.5">
+    <list default="true" id="5d2ecd5e-a05a-4f96-a195-fa6372618165" name="Default Changelist" comment="wip #5041 @2">
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/app/Http/Controllers/Admin/Operations/ELearningPackage/ImportOperation.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/Http/Controllers/Admin/Operations/ELearningPackage/ImportOperation.php" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/app/Models/ELearningPackage.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/Models/ELearningPackage.php" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/app/SubForms/ElearningPackageContent.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/SubForms/ElearningPackageContent.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/app/Console/Commands/WorkshopMigration.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/Console/Commands/WorkshopMigration.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/app/Models/FluidbookPublication.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/Models/FluidbookPublication.php" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
       <workItem from="1646233658795" duration="1190000" />
       <workItem from="1646312342244" duration="162000" />
       <workItem from="1646312529624" duration="5350000" />
-      <workItem from="1646330633143" duration="4094000" />
-    </task>
-    <task id="LOCAL-00212" summary="wait #4951 @3">
-      <created>1639054348287</created>
-      <option name="number" value="00212" />
-      <option name="presentableId" value="LOCAL-00212" />
-      <option name="project" value="LOCAL" />
-      <updated>1639054348287</updated>
+      <workItem from="1646330633143" duration="4391000" />
+      <workItem from="1646655005312" duration="7451000" />
     </task>
     <task id="LOCAL-00213" summary="wip #4962 @0.5">
       <created>1639733224682</created>
       <option name="project" value="LOCAL" />
       <updated>1646318060645</updated>
     </task>
-    <option name="localTasksCounter" value="261" />
+    <task id="LOCAL-00261" summary="wip #5041 @2">
+      <created>1646334816571</created>
+      <option name="number" value="00261" />
+      <option name="presentableId" value="LOCAL-00261" />
+      <option name="project" value="LOCAL" />
+      <updated>1646334816571</updated>
+    </task>
+    <option name="localTasksCounter" value="262" />
     <servers />
   </component>
   <component name="TypeScriptGeneratedFilesManager">
     <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
     <option name="CHECK_NEW_TODO" value="false" />
     <option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
-    <MESSAGE value="wip #5045 @1" />
     <MESSAGE value="wip #5045" />
     <MESSAGE value="wip #5045 @0.5" />
     <MESSAGE value="wip #5045 @3" />
     <MESSAGE value="wait #5127 @0.5" />
     <MESSAGE value="wait #5127 @0.25" />
     <MESSAGE value="wip #5041 @1.5" />
-    <option name="LAST_COMMIT_MESSAGE" value="wip #5041 @1.5" />
+    <MESSAGE value="wip #5041 @2" />
+    <option name="LAST_COMMIT_MESSAGE" value="wip #5041 @2" />
   </component>
   <component name="XSLT-Support.FileAssociations.UIState">
     <expand />
index 0354ec9fbc4e6814501896ccff89f04952a43f78..7750c94c3b6b2afeb279bfc6c7db1cefbf574c4b 100644 (file)
@@ -12,6 +12,7 @@ use Cubist\Backpack\Magic\Fields\Color;
 use Cubist\Backpack\Magic\Fields\Date;
 use Cubist\Backpack\Magic\Fields\Datetime;
 use Cubist\Backpack\Magic\Fields\Files;
+use Cubist\Util\PHP;
 use Illuminate\Support\Facades\DB;
 
 class WorkshopMigration extends CubistCommand
@@ -79,6 +80,8 @@ class WorkshopMigration extends CubistCommand
 
     protected function importPublications()
     {
+        PHP::neverStop();
+
         $map = ['book_id' => 'id',
             'nom' => 'name',
             'proprietaire' => 'owner',
@@ -101,12 +104,17 @@ class WorkshopMigration extends CubistCommand
 
         $ignore = [];
 
+        $this->line('Begin publications migration');
+
         FluidbookTheme::$updateWS2ViewOnChange = false;
-        foreach (FluidbookPublication::all() as $book) {
+        foreach (FluidbookPublication::lazy() as $book) {
+            $this->line('Delete ' . $book->id);
             $book->delete();
         }
+        FluidbookPublication::truncate();
 
         foreach (DB::table($this->_oldDB . '.books')->get() as $e) {
+            $this->line('Import ' . $e->book_id);
             $oldRoot = $this->_oldRoot . 'books/working/' . $e->book_id . '/';
             $c = new FluidbookPublication();
             foreach ($e as $k => $v) {
@@ -121,6 +129,7 @@ class WorkshopMigration extends CubistCommand
                 }
                 $c->setAttribute($new, $v);
             }
+            dd($c->attributesToArray());
             $c->save();
 
             $s = $this->_unserialize($e->parametres);
@@ -139,9 +148,13 @@ class WorkshopMigration extends CubistCommand
                 } else {
                     if ($f instanceof Color) {
                         $data = FluidbookTheme::_colorToWS3($data);
+                    } else if ($f instanceof Datetime) {
+                        $date = new \DateTime();
+                        $date->setTimestamp($data);
+                        $data = $date;
                     }
-                    if(isset($mapValues[$data])){
-                        $data=$mapValues[$data];
+                    if (isset($mapValues[$data])) {
+                        $data = $mapValues[$data];
                     }
                     $c->setAttribute($k, $data);
                 }
index fec94edad1f00f18195776837f22cc4d546c8283..013f3cf9f13697cf9f5e004339dffd43158f2454 100644 (file)
@@ -9,11 +9,16 @@ use App\Fields\FluidbookSignature;
 use App\Fields\FluidbookTitle;
 use App\Fields\User;
 use App\Models\Base\ToolboxModel;
+use Cubist\Backpack\Magic\Fields\Checkbox;
 use Cubist\Backpack\Magic\Fields\Code;
 use Cubist\Backpack\Magic\Fields\Datetime;
+use Cubist\Backpack\Magic\Fields\FilesOrURL;
+use Cubist\Backpack\Magic\Fields\FormSection;
+use Cubist\Backpack\Magic\Fields\FormSeparator;
 use Cubist\Backpack\Magic\Fields\Hidden;
 use Cubist\Backpack\Magic\Fields\Integer;
 use Cubist\Backpack\Magic\Fields\LongText;
+use Cubist\Backpack\Magic\Fields\Number;
 use Cubist\Backpack\Magic\Fields\SelectFromArray;
 use Cubist\Backpack\Magic\Fields\Textarea;
 
@@ -30,6 +35,8 @@ class FluidbookPublication extends ToolboxModel
 
     protected $_syncDbSchema = false;
 
+    protected static $_permissionBase = 'fluidbook-publication';
+
 
     public function setFields()
     {
@@ -88,177 +95,100 @@ class FluidbookPublication extends ToolboxModel
 
     public function setSettingsFields()
     {
-        $this->addField([
-            'name' => 'section_important',
-            'type' => 'FormSection',
-            'label' => __('Description de la publication'),
-        ]);
-        $this->addField([
-            'name' => 'mobileLVersion',
-            'type' => FluidbookDevelopmentVersion::class,
-            'label' => __('Version logicielle'),
+        $this->addField('section_important', FormSection::class, __('Description de la publication'));
+        $this->addField('mobileLVersion', FluidbookDevelopmentVersion::class, __('Version logicielle'), [
             'default' => 'stable',
-            'can' => 'fluidbook-publication:admin',
-            'column' => true,
-            'filter' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobileVersion',
-            'type' => 'SelectFromArray',
+        $this->addField('mobileVersion', SelectFromArray::class, __('Version mobile'), [
             'options' => [
                 'pdf' => 'Rediriger vers le PDF',
                 'html5-desktop' => 'Version HTML5 recommandée (vecteurs sur desktop)',
                 'html5' => 'Version HTML5 vecteurs',
                 'html5-images' => 'Version HTML5 en images',
             ],
-            'label' => __('Version mobile'),
             'default' => 'html5-desktop',
             'translatable' => false,
         ]);
-
-        $this->addField([
-            'name' => 'url_link',
-            'type' => 'LongText',
-            'label' => __('URL du lien de retour au site'),
+        $this->addField('title', LongText::class, __('Titre de la publication'), [
+            'default' => '',
+            'translatable' => false,
+        ]);
+        $this->addField('url_link', LongText::class, __('URL du lien de retour au site'), [
             'default' => 'http://',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'signature',
-            'type' => FluidbookSignature::class,
+        $this->addField('signature', FluidbookSignature::class, __('Signature'), [
             'default' => '1',
-            'label' => __('Signature'),
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_assets',
-            'type' => 'FormSection',
-            'label' => __('Assets'),
-        ]);
-        $this->addField([
-            'name' => 'assetsDir',
-            'type' => 'LongText',
-            'label' => __('Utiliser le dossier d\'assets du fluidbook'),
+        $this->addField('section_assets', FormSection::class, __('Assets'));
+        $this->addField('assetsDir', LongText::class, __('Utiliser le dossier d\'assets du fluidbook'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linksAssets',
-            'type' => 'FilesOrURL',
-            'label' => __('Charger ou remplacer des fichiers de liens'),
+        $this->addField('linksAssets', FilesOrURL::class, __('Charger ou remplacer des fichiers de liens'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_basicStats',
-            'type' => 'FormSection',
-            'label' => __('Statistiques'),
-        ]);
-        $this->addField([
-            'name' => 'stats',
-            'type' => 'Checkbox',
-            'label' => __('Activer les statistiques Fluidbook'),
+        $this->addField('section_basicStats', FormSection::class, __('Statistiques'));
+        $this->addField('stats', Checkbox::class, __('Activer les statistiques Fluidbook'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'googleAnalytics',
-            'type' => 'LongText',
-            'label' => __('Code Google Analytics'),
+        $this->addField('googleAnalytics', LongText::class, __('Code Google Analytics'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'googleTagManager',
-            'type' => 'LongText',
-            'label' => __('Code Google Tag Manager'),
+        $this->addField('googleTagManager', LongText::class, __('Code Google Tag Manager'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_share',
-            'type' => 'FormSection',
-            'label' => __('Fonctions de partage'),
-        ]);
-        $this->addField([
-            'name' => 'share',
-            'type' => 'Checkbox',
-            'label' => __('Activer les fonctions de partage'),
+        $this->addField('section_share', FormSection::class, __('Fonctions de partage'));
+        $this->addField('share', Checkbox::class, __('Activer les fonctions de partage'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'email_title',
-            'type' => 'LongText',
-            'label' => __('Titre de l\'email "Envoyer à un ami"'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('email_title', LongText::class, __('Titre de l\'email "Envoyer à un ami"'), [
             'hint' => __('Laisser vide pour utiliser la valeur par défaut'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'email_body',
-            'type' => 'Textarea',
-            'label' => __('Corps de l\'email "Envoyer à un ami"'),
+        $this->addField('email_body', Textarea::class, __('Corps de l\'email "Envoyer à un ami"'), [
             'hint' => __('Laisser vide pour utiliser la valeur par défaut'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'email_editable',
-            'type' => 'Checkbox',
-            'label' => __('Permettre au lecteur de modifier le corps de l\'email'),
+        $this->addField('email_editable', Checkbox::class, __('Permettre au lecteur de modifier le corps de l\'email'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'askAcknowledge',
-            'type' => 'Checkbox',
-            'label' => __('Demander au destinataire un accusé de réception'),
+        $this->addField('askAcknowledge', Checkbox::class, __('Demander au destinataire un accusé de réception'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'sendasfluidbook',
-            'type' => 'Checkbox',
-            'label' => __('Envoyer le mail comme Fluidbook'),
+        $this->addField('sendasfluidbook', Checkbox::class, __('Envoyer le mail comme Fluidbook'), [
             'hint' => __('L\'expéditeur apparaîtra en reply-to'),
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'email_mailto',
-            'type' => 'Checkbox',
-            'label' => __('Envoyer le mail via le client mail du visiteur (mailto:)'),
+        $this->addField('email_mailto', Checkbox::class, __('Envoyer le mail via le client mail du visiteur (mailto:)'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'facebook_title',
-            'type' => 'LongText',
-            'label' => __('Titre du contenu partagé'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('facebook_title', LongText::class, __('Titre du contenu partagé'), [
             'hint' => __('Titre proposé sur les fonction de partage (par défaut, titre de la publication)'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'facebook_description',
-            'type' => 'Textarea',
-            'label' => __('Description du contenu partagé'),
+        $this->addField('facebook_description', Textarea::class, __('Description du contenu partagé'), [
             'hint' => __('Description proposée sur les fonctions de partage (par défaut, vide)'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'facebook_image',
-            'type' => 'FilesOrURL',
-            'label' => __('Miniature affichée'),
+        $this->addField('facebook_image', FilesOrURL::class, __('Miniature affichée'), [
             'default' => '',
             'accept' => [
                 0 => '*.jpg',
@@ -267,164 +197,90 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'twitter_description',
-            'type' => 'Textarea',
-            'label' => __('Contenu Partage court'),
+        $this->addField('twitter_description', Textarea::class, __('Contenu Partage court'), [
             'hint' => __('Contenu du partagé sur les partages courts'),
             'default' => '%title% : %short%',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'friend',
-            'type' => 'Checkbox',
-            'label' => __('E-mail'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('friend', Checkbox::class, __('E-mail'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'facebook',
-            'type' => 'Checkbox',
-            'label' => __('Facebook'),
+        $this->addField('facebook', Checkbox::class, __('Facebook'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'twitter',
-            'type' => 'Checkbox',
-            'label' => __('Twitter'),
+        $this->addField('twitter', Checkbox::class, __('Twitter'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'whatsapp',
-            'type' => 'Checkbox',
-            'label' => __('WhatsApp'),
+        $this->addField('whatsapp', Checkbox::class, __('WhatsApp'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkedin',
-            'type' => 'Checkbox',
-            'label' => __('LinkedIn'),
+        $this->addField('linkedin', Checkbox::class, __('LinkedIn'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pinterest',
-            'type' => 'Checkbox',
-            'label' => __('Pinterest'),
+        $this->addField('pinterest', Checkbox::class, __('Pinterest'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'googleplus',
-            'type' => 'Checkbox',
-            'label' => __('Google +'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('googleplus', Checkbox::class, __('Google +'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'viadeo',
-            'type' => 'Checkbox',
-            'label' => __('Viadeo'),
+        $this->addField('viadeo', Checkbox::class, __('Viadeo'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'customSharer',
-            'type' => 'LongText',
-            'label' => __('Classe personnalisée de partage'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('customSharer', LongText::class, __('Classe personnalisée de partage'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'friendWidth',
-            'type' => 'Integer',
-            'label' => __('Largeur du menu'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('friendWidth', Integer::class, __('Largeur du menu'), [
             'default' => 319,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'friendHeight',
-            'type' => 'Integer',
-            'label' => __('Largeur du menu'),
+        $this->addField('friendHeight', Integer::class, __('Largeur du menu'), [
             'default' => 500,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_seo',
-            'type' => 'FormSection',
-            'label' => __('Optimisation pour les moteurs de recherche'),
-        ]);
-        $this->addField([
-            'name' => 'seoVersion',
-            'type' => 'Checkbox',
-            'label' => __('Générer une version pour les moteurs de recherche'),
+        $this->addField('section_seo', FormSection::class, __('Optimisation pour les moteurs de recherche'));
+        $this->addField('seoVersion', Checkbox::class, __('Générer une version pour les moteurs de recherche'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'seoRobots',
-            'type' => 'Checkbox',
-            'label' => __('Autoriser le parcours par les moteurs de recherche'),
+        $this->addField('seoRobots', Checkbox::class, __('Autoriser le parcours par les moteurs de recherche'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'seoDescription',
-            'type' => 'Textarea',
-            'label' => __('Meta tag Description'),
+        $this->addField('seoDescription', Textarea::class, __('Meta tag Description'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'seoKeywords',
-            'type' => 'Textarea',
-            'label' => __('Meta tag Keywords'),
+        $this->addField('seoKeywords', Textarea::class, __('Meta tag Keywords'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'seoBaseURL',
-            'type' => 'LongText',
-            'label' => __('URL de base'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('seoBaseURL', LongText::class, __('URL de base'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'seoAdvanced',
-            'type' => 'FilesOrURL',
-            'label' => __('Données SEO par page'),
+        $this->addField('seoAdvanced', FilesOrURL::class, __('Données SEO par page'), [
             'default' => '',
             'accept' => [
                 0 => '*.xlsx',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_3d_mode',
-            'type' => 'FormSection',
-            'label' => __('Options de visualisation'),
-        ]);
-        $this->addField([
-            'name' => 'mobileNavigationType',
-            'type' => 'SelectFromArray',
+        $this->addField('section_3d_mode', FormSection::class, __('Options de visualisation'));
+        $this->addField('mobileNavigationType', SelectFromArray::class, __('Mode de navigation'), [
             'options' => [
                 'book' => 'Normal (automatique)',
                 'landscape' => 'Normal (double page)',
@@ -432,16 +288,11 @@ class FluidbookPublication extends ToolboxModel
                 'mobilefirst' => 'Mobile first',
                 'tab' => 'Magazine tablette',
             ],
-            'label' => __('Mode de navigation'),
             'default' => 'book',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'mobileTransitions',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('mobileTransitions', SelectFromArray::class, __('Transitions entre les pages'), [
             'options' => [
                 'none' => 'Aucune transition',
                 'fade' => 'Opacité',
@@ -449,314 +300,193 @@ class FluidbookPublication extends ToolboxModel
                 'flip' => 'Tourner (rigide)',
                 'flip3d' => 'Tourner (souple)',
             ],
-            'label' => __('Transitions entre les pages'),
             'default' => 'flip3d',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobileTransitionDuration',
-            'type' => 'Number',
-            'label' => __('Durée de la transition'),
+        $this->addField('mobileTransitionDuration', Number::class, __('Durée de la transition'), [
             'default' => 0.5,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'forceWhiteBackground',
-            'type' => 'Checkbox',
-            'label' => __('Ajouter un fond blanc aux pages'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('forceWhiteBackground', Checkbox::class, __('Ajouter un fond blanc aux pages'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'rasterizePages',
-            'type' => 'Textarea',
-            'label' => __('Ecraser les pages'),
+        $this->addField('rasterizePages', Textarea::class, __('Ecraser les pages'), [
             'hint' => __('1-3,5 = 1,2,3,5'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'vectorPages',
-            'type' => 'Textarea',
-            'label' => __('Conserver les pages en vecteur'),
+        $this->addField('vectorPages', Textarea::class, __('Conserver les pages en vecteur'), [
             'hint' => __('1-3,5 = 1,2,3,5'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'visualisationMode',
-            'type' => 'SelectFromArray',
+        $this->addField('visualisationMode', SelectFromArray::class, __('Mode de visualisation 3D'), [
             'options' => [
                 0 => 'Mode 3D',
                 1 => 'Mode 2D (caméra fixe et pages à plat)',
                 2 => 'Laisser le choix à l\'utilisateur (mode 3D par défaut)',
                 3 => 'Laisser le choix à l\'utilisateur (mode 2D par défaut)',
             ],
-            'label' => __('Mode de visualisation 3D'),
             'default' => '3',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'antialiasReading',
-            'type' => 'Checkbox',
-            'label' => __('Amélioration de la lisibilité en mode 2D'),
+        $this->addField('antialiasReading', Checkbox::class, __('Amélioration de la lisibilité en mode 2D'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'correctCenter',
-            'type' => 'Checkbox',
-            'label' => __('Corriger les lignes blanches entre les pages'),
+        $this->addField('correctCenter', Checkbox::class, __('Corriger les lignes blanches entre les pages'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pagesBaseAngle',
-            'type' => 'Integer',
-            'label' => __('Angle de base entre les pages'),
+        $this->addField('pagesBaseAngle', Integer::class, __('Angle de base entre les pages'), [
             'hint' => __('0 : Publication à plat
 2 : Valeur par défaut'),
             'default' => 2,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'centerBook',
-            'type' => 'Checkbox',
-            'label' => __('Centrer la publication sur les couvertures'),
+        $this->addField('centerBook', Checkbox::class, __('Centrer la publication sur les couvertures'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'extraXSpace',
-            'type' => 'Integer',
-            'label' => __('Marge supplémentaire horizontale'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('extraXSpace', Integer::class, __('Marge supplémentaire horizontale'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobileExtraXSpace',
-            'type' => 'Integer',
-            'label' => __('Marge supplémentaire horizontale'),
+        $this->addField('mobileExtraXSpace', Integer::class, __('Marge supplémentaire horizontale'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'extraYSpace',
-            'type' => 'Integer',
-            'label' => __('Marge supplémentaire verticale'),
+        $this->addField('extraYSpace', Integer::class, __('Marge supplémentaire verticale'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'viewMode',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('viewMode', SelectFromArray::class, __('Mode de visualisation (beta)'), [
             'options' => [
                 0 => 'Classique',
                 1 => 'Diaporama',
             ],
-            'label' => __('Mode de visualisation (beta)'),
             'default' => '0',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'dynamicBackgroundColor',
-            'type' => 'Textarea',
-            'label' => __('Couleur de fond dynamique'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('dynamicBackgroundColor', Textarea::class, __('Couleur de fond dynamique'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('', FormSeparator::class);
+        $this->addField('svgToCanvas', Checkbox::class, __('Activer le rendu svgtocanvas'), [
+            'default' => true,
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'svgToCanvasUpscale',
-            'type' => 'Number',
-            'label' => __('Upscale de la fonction svgtocanvas'),
+        $this->addField('svgToCanvasUpscale', Number::class, __('Upscale de la fonction svgtocanvas'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'textsThickness',
-            'type' => 'Number',
-            'label' => __('Epaisseur des textes'),
+        $this->addField('textsThickness', Number::class, __('Epaisseur des textes'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'textsThicknessPages',
-            'type' => 'LongText',
-            'label' => __('Appliquer l\'épaisseur des texte sur les pages'),
+        $this->addField('textsThicknessPages', LongText::class, __('Appliquer l\'épaisseur des texte sur les pages'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'imageFormat',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('imageFormat', SelectFromArray::class, __('Format des images'), [
             'options' => [
                 'jpg' => 'JPEG',
                 'png' => 'PNG',
             ],
-            'label' => __('Format des images'),
             'default' => 'jpg',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'maxResolution',
-            'type' => 'SelectFromArray',
+        $this->addField('maxResolution', SelectFromArray::class, __('Résolution maximale des pages'), [
             'options' => [
                 300 => '300dpi',
                 150 => '150dpi',
                 125 => '125dpi',
                 100 => '100dpi',
             ],
-            'label' => __('Résolution maximale des pages'),
             'default' => 300,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'JPEGQuality',
-            'type' => 'Integer',
-            'label' => __('Qualité JPEG'),
+        $this->addField('JPEGQuality', Integer::class, __('Qualité JPEG'), [
             'default' => 85,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_performances',
-            'type' => 'FormSection',
-            'label' => __('Performances'),
-        ]);
-        $this->addField([
-            'name' => 'rasterizeOnSafari',
-            'type' => 'Checkbox',
-            'label' => __('Ecraser les pages pour Safari (Mac OS)'),
+        $this->addField('section_performances', FormSection::class, __('Performances'));
+        $this->addField('rasterizeOnSafari', Checkbox::class, __('Ecraser les pages pour Safari (Mac OS)'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_general',
-            'type' => 'FormSection',
-            'label' => __('Fonctionnalités générales'),
+        $this->addField('performance3DMode', SelectFromArray::class, __('Performance de la 3D'), [
+            'options' => [
+                'auto' => 'Tester la machine',
+                'highPerf' => 'Haute',
+                'lowPerf' => 'Moyenne',
+                'veryLowPerf' => 'Basse',
+            ],
+            'default' => 'auto',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tooltipTimer',
-            'type' => 'Number',
-            'label' => __('Temps maximum d\'apparition des infos-bulles (en secondes)'),
+        $this->addField('section_general', FormSection::class, __('Fonctionnalités générales'));
+        $this->addField('tooltipTimer', Number::class, __('Temps maximum d\'apparition des infos-bulles (en secondes)'), [
             'default' => 3,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobilePlugins',
-            'type' => 'Textarea',
-            'label' => __('Plugin'),
+        $this->addField('mobilePlugins', Textarea::class, __('Plugin'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'preload',
-            'type' => 'Integer',
-            'label' => __('Nombre de pages à précharger'),
+        $this->addField('preload', Integer::class, __('Nombre de pages à précharger'), [
             'default' => 16,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'maxPages',
-            'type' => 'Integer',
-            'label' => __('Nombre de pages maximal affiché à l\'ouverture du fluidbook (pas de limite = 0)'),
+        $this->addField('maxPages', Integer::class, __('Nombre de pages maximal affiché à l\'ouverture du fluidbook (pas de limite = 0)'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pages',
-            'type' => 'Integer',
-            'label' => __('Nombre de pages'),
+        $this->addField('pages', Integer::class, __('Nombre de pages'), [
             'default' => 0,
             'translatable' => false,
-            'column' => true,
-            'column_label' => 'Pages'
         ]);
-        $this->addField([
-            'name' => 'width',
-            'type' => 'Number',
-            'label' => __('Largeur'),
+        $this->addField('width', Number::class, __('Largeur'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'height',
-            'type' => 'Number',
-            'label' => __('Hauteur'),
+        $this->addField('height', Number::class, __('Hauteur'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_menu',
-            'type' => 'FormSection',
-            'label' => __('Menu'),
-        ]);
-        $this->addField([
-            'name' => 'navOrder',
-            'type' => 'Textarea',
-            'label' => __('Ordre des icônes dans la nav'),
+        $this->addField('section_menu', FormSection::class, __('Menu'));
+        $this->addField('navOrder', Textarea::class, __('Ordre des icônes dans la nav'), [
             'default' => 'index, chapters, search, print, friend, bookmark, pdf, notes, archives, basket, fullscreen, sound, 3d, extra, extra1, extra2, extra3, extra4, extra5, help, lang',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navOrderH',
-            'type' => 'Textarea',
-            'label' => __('Ordre des icônes dans la nav (Si différente)'),
+        $this->addField('navOrderH', Textarea::class, __('Ordre des icônes dans la nav (Si différente)'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'mobileNavScale',
-            'type' => 'Integer',
-            'label' => __('Taille du menu (en %)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('mobileNavScale', Integer::class, __('Taille du menu (en %)'), [
             'default' => 100,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'menuBreakpoint',
-            'type' => 'LongText',
-            'label' => __('Breakpoint burger menu'),
+        $this->addField('menuBreakpoint', LongText::class, __('Breakpoint burger menu'), [
             'hint' => __('Par défaut 1023px'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'afterSearchDisplayForHTML',
-            'type' => 'Checkbox',
-            'label' => __('Afficher l\'image après le moteur de recherche sur la version HTML5'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('afterSearchDisplayForHTML', Checkbox::class, __('Afficher l\'image après le moteur de recherche sur la version HTML5'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'navExtraImage',
-            'type' => 'FilesOrURL',
-            'label' => __('Image pour navigation'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('navExtraImage', FilesOrURL::class, __('Image pour navigation'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -766,10 +496,7 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraImageMobile',
-            'type' => 'FilesOrURL',
-            'label' => __('Image pour mobile'),
+        $this->addField('navExtraImageMobile', FilesOrURL::class, __('Image pour mobile'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -779,27 +506,16 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraLink',
-            'type' => 'LongText',
-            'label' => __('URL'),
+        $this->addField('navExtraLink', LongText::class, __('URL'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraTooltip',
-            'type' => 'LongText',
-            'label' => __('Infobulle ou label'),
+        $this->addField('navExtraTooltip', LongText::class, __('Infobulle ou label'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'navExtraIcon1',
-            'type' => 'FilesOrURL',
-            'label' => __('Icône supplémentaire 1'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('navExtraIcon1', FilesOrURL::class, __('Icône supplémentaire 1'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -809,43 +525,29 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraType1',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraType1', SelectFromArray::class, __('Type'), [
             'options' => [
                 'icon' => 'Icône + Label',
                 'image' => 'Image',
             ],
-            'label' => __('Type'),
             'default' => 'icon',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraLink1',
-            'type' => 'LongText',
-            'label' => __('URL 1'),
+        $this->addField('navExtraLink1', LongText::class, __('URL 1'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraVisibility1',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraVisibility1', SelectFromArray::class, __('Visible 1'), [
             'options' => [
                 'horizontal' => 'Navigation horizontale',
                 'burger' => 'Navigation burger',
                 'both' => 'Navigations horizontale et burger',
             ],
-            'label' => __('Visible 1'),
             'default' => 'both',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'navExtraIcon2',
-            'type' => 'FilesOrURL',
-            'label' => __('Icône supplémentaire 2'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('navExtraIcon2', FilesOrURL::class, __('Icône supplémentaire 2'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -855,43 +557,29 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraType2',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraType2', SelectFromArray::class, __('Type'), [
             'options' => [
                 'icon' => 'Icône + Label',
                 'image' => 'Image',
             ],
-            'label' => __('Type'),
             'default' => 'icon',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraLink2',
-            'type' => 'LongText',
-            'label' => __('URL 2'),
+        $this->addField('navExtraLink2', LongText::class, __('URL 2'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraVisibility2',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraVisibility2', SelectFromArray::class, __('Visible 2'), [
             'options' => [
                 'horizontal' => 'Navigation horizontale',
                 'burger' => 'Navigation burger',
                 'both' => 'Navigations horizontale et burger',
             ],
-            'label' => __('Visible 2'),
             'default' => 'both',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'navExtraIcon3',
-            'type' => 'FilesOrURL',
-            'label' => __('Icône supplémentaire 3'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('navExtraIcon3', FilesOrURL::class, __('Icône supplémentaire 3'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -901,43 +589,29 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraType3',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraType3', SelectFromArray::class, __('Type'), [
             'options' => [
                 'icon' => 'Icône + Label',
                 'image' => 'Image',
             ],
-            'label' => __('Type'),
             'default' => 'icon',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraLink3',
-            'type' => 'LongText',
-            'label' => __('URL 3'),
+        $this->addField('navExtraLink3', LongText::class, __('URL 3'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraVisibility3',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraVisibility3', SelectFromArray::class, __('Visible 3'), [
             'options' => [
                 'horizontal' => 'Navigation horizontale',
                 'burger' => 'Navigation burger',
                 'both' => 'Navigations horizontale et burger',
             ],
-            'label' => __('Visible 3'),
             'default' => 'both',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'navExtraIcon4',
-            'type' => 'FilesOrURL',
-            'label' => __('Icône supplémentaire 4'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('navExtraIcon4', FilesOrURL::class, __('Icône supplémentaire 4'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -947,43 +621,29 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraType4',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraType4', SelectFromArray::class, __('Type'), [
             'options' => [
                 'icon' => 'Icône + Label',
                 'image' => 'Image',
             ],
-            'label' => __('Type'),
             'default' => 'icon',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraLink4',
-            'type' => 'LongText',
-            'label' => __('URL 4'),
+        $this->addField('navExtraLink4', LongText::class, __('URL 4'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraVisibility4',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraVisibility4', SelectFromArray::class, __('Visible 4'), [
             'options' => [
                 'horizontal' => 'Navigation horizontale',
                 'burger' => 'Navigation burger',
                 'both' => 'Navigations horizontale et burger',
             ],
-            'label' => __('Visible 4'),
             'default' => 'both',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'navExtraIcon5',
-            'type' => 'FilesOrURL',
-            'label' => __('Icône supplémentaire 5'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('navExtraIcon5', FilesOrURL::class, __('Icône supplémentaire 5'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -993,401 +653,251 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraType5',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraType5', SelectFromArray::class, __('Type'), [
             'options' => [
                 'icon' => 'Icône + Label',
                 'image' => 'Image',
             ],
-            'label' => __('Type'),
             'default' => 'icon',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraLink5',
-            'type' => 'LongText',
-            'label' => __('URL 5'),
+        $this->addField('navExtraLink5', LongText::class, __('URL 5'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'navExtraVisibility5',
-            'type' => 'SelectFromArray',
+        $this->addField('navExtraVisibility5', SelectFromArray::class, __('Visible 5'), [
             'options' => [
                 'horizontal' => 'Navigation horizontale',
                 'burger' => 'Navigation burger',
                 'both' => 'Navigations horizontale et burger',
             ],
-            'label' => __('Visible 5'),
             'default' => 'both',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'mobileBottomNav',
-            'type' => 'LongText',
-            'label' => __('Barre de boutons en bas'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('mobileBottomNav', LongText::class, __('Barre de boutons en bas'), [
             'hint' => __('Identifiants des boutons séparés par des virgules'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_landing',
-            'type' => 'FormSection',
-            'label' => __('Custom Landing Page'),
-        ]);
-        $this->addField([
-            'name' => 'landingPage',
-            'type' => 'FilesOrURL',
-            'label' => __('Landing Page content'),
+        $this->addField('section_landing', FormSection::class, __('Custom Landing Page'));
+        $this->addField('landingPage', FilesOrURL::class, __('Landing Page content'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_fs',
-            'type' => 'FormSection',
-            'label' => __('Plein écran'),
-        ]);
-        $this->addField([
-            'name' => 'fullscreen',
-            'type' => 'Checkbox',
-            'label' => __('Activer le mode plein-écran'),
+        $this->addField('section_fs', FormSection::class, __('Plein écran'));
+        $this->addField('fullscreen', Checkbox::class, __('Activer le mode plein-écran'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'fullscreenAuto',
-            'type' => 'Checkbox',
-            'label' => __('Lancer la publication en mode plein écran (lorsque possible)'),
+        $this->addField('fullscreenAuto', Checkbox::class, __('Lancer la publication en mode plein écran (lorsque possible)'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_bookmark',
-            'type' => 'FormSection',
-            'label' => __('Marques-pages'),
-        ]);
-        $this->addField([
-            'name' => 'bookmark',
-            'type' => 'Checkbox',
-            'label' => __('Activer les marques-pages'),
+        $this->addField('section_bookmark', FormSection::class, __('Marques-pages'));
+        $this->addField('bookmark', Checkbox::class, __('Activer les marques-pages'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('bookmarkView', SelectFromArray::class, __('Menu des marques-pages'), [
+            'options' => [
+                'small' => 'Réduit',
+                'large' => 'Complet',
+            ],
+            'default' => 'small',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmarkSendEnable',
-            'type' => 'Checkbox',
-            'label' => __('Activer l\'envoi des marques-pages par e-mail'),
+        $this->addField('bookmarkFunctionsMainMenu', Checkbox::class, __('Fonctions vers menus généraux'), [
+            'hint' => __('Les fonctions des marques pages (Télécharger, Imprimer, Envoyer) dirigent vers les menus généraux'),
+            'default' => false,
+            'translatable' => false,
+        ]);
+        $this->addField('bookmarkEmpty', Checkbox::class, __('Bouton pour effacer les marques-pages'), [
+            'default' => false,
+            'translatable' => false,
+        ]);
+        $this->addField('', FormSeparator::class);
+        $this->addField('bookmarkSendEnable', Checkbox::class, __('Activer l\'envoi des marques-pages par e-mail'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmark_email_title',
-            'type' => 'LongText',
-            'label' => __('Titre de l\'email "Envoyer à un ami"'),
+        $this->addField('bookmark_email_title', LongText::class, __('Titre de l\'email "Envoyer à un ami"'), [
             'hint' => __('Laisser vide pour utiliser la valeur par défaut'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmark_email_body',
-            'type' => 'Textarea',
-            'label' => __('Corps de l\'email "Envoyer à un ami"'),
+        $this->addField('bookmark_email_body', Textarea::class, __('Corps de l\'email "Envoyer à un ami"'), [
             'hint' => __('Laisser vide pour utiliser la valeur par défaut'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('', FormSeparator::class);
+        $this->addField('bookmarkPrint', Checkbox::class, __('Activer l\'impression des marques-pages'), [
+            'default' => false,
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmarkCornerSize',
-            'type' => 'Integer',
-            'label' => __('Taille des marques-pages'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('bookmarkCornerSize', Integer::class, __('Taille des marques-pages'), [
             'hint' => __('Taille relative à la largeur de la page'),
             'default' => 8,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmarkOffset',
-            'type' => 'Integer',
-            'label' => __('Décaler de x pixels vers l\'intérieur'),
+        $this->addField('bookmarkOffset', Integer::class, __('Décaler de x pixels vers l\'intérieur'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmarkPermanentIcon',
-            'type' => 'Checkbox',
-            'label' => __('Afficher l\'icône en permanance'),
+        $this->addField('bookmarkPermanentIcon', Checkbox::class, __('Afficher l\'icône en permanance'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmarkBlinkOnPageChange',
-            'type' => 'Checkbox',
-            'label' => __('Faire clignoter le marque page à l\'apparition de la page'),
+        $this->addField('bookmarkBlinkOnPageChange', Checkbox::class, __('Faire clignoter le marque page à l\'apparition de la page'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'bookmarkDisablePages',
-            'type' => 'LongText',
-            'label' => __('Désactiver les marques-pages sur ces pages'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('bookmarkDisablePages', LongText::class, __('Désactiver les marques-pages sur ces pages'), [
             'hint' => __('1-3,5 = 1,2,3,5'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'bookmarkUsePDF',
-            'type' => 'SelectFromArray',
+        $this->addField('bookmarkUsePDF', SelectFromArray::class, __('PDF à utiliser pour l\'envoi ou le téléchargement de pages marquées'), [
             'options' => [
                 'pages' => 'PDF des pages',
                 'download' => 'PDF de remplacement',
                 'thumbnails' => 'PDF des miniatures',
             ],
-            'label' => __('PDF à utiliser pour l\'envoi ou le téléchargement de pages marquées'),
             'default' => 'pages',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_help',
-            'type' => 'FormSection',
-            'label' => __('Aide'),
-        ]);
-        $this->addField([
-            'name' => 'help',
-            'type' => 'Checkbox',
-            'label' => __('Activer l\'aide'),
+        $this->addField('section_help', FormSection::class, __('Aide'));
+        $this->addField('help', Checkbox::class, __('Activer l\'aide'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'helpStartup',
-            'type' => 'Checkbox',
-            'label' => __('Afficher l\'aide au démarrage'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('helpStartup', Checkbox::class, __('Afficher l\'aide au démarrage'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'helpStartupTime',
-            'type' => 'Integer',
-            'label' => __('Temps d\'affichage en secondes'),
+        $this->addField('helpStartupTime', Integer::class, __('Temps d\'affichage en secondes'), [
             'default' => 15,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'helpBookmarks',
-            'type' => 'Checkbox',
-            'label' => __('Améliorer l\'aide des marques-pages'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('helpBookmarks', Checkbox::class, __('Améliorer l\'aide des marques-pages'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'helpArrowTooltip',
-            'type' => 'LongText',
-            'label' => __('Bulle affichée au niveau de la flèche de droite'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('helpArrowTooltip', LongText::class, __('Bulle affichée au niveau de la flèche de droite'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'landscapeWarning',
-            'type' => 'Textarea',
-            'label' => __('Avertissement affiché sur mobile au chargement de la publication'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('landscapeWarning', Textarea::class, __('Avertissement affiché sur mobile au chargement de la publication'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_index',
-            'type' => 'FormSection',
-            'label' => __('Vue d\'index (vignettes)'),
-        ]);
-        $this->addField([
-            'name' => 'indexAutoScroll',
-            'type' => 'Checkbox',
-            'label' => __('Activer le scroll automatique'),
+        $this->addField('section_index', FormSection::class, __('Vue d\'index (vignettes)'));
+        $this->addField('indexAutoScroll', Checkbox::class, __('Activer le scroll automatique'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pdfThumbnails',
-            'type' => 'FilesOrURL',
-            'label' => __('PDF utilisé pour générer les miniatures'),
+        $this->addField('pdfThumbnails', FilesOrURL::class, __('PDF utilisé pour générer les miniatures'), [
             'default' => '',
             'accept' => [
                 0 => '*.pdf',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'indexMessage',
-            'type' => 'Textarea',
-            'label' => __('Message en haut'),
+        $this->addField('indexMessage', Textarea::class, __('Message en haut'), [
             'hint' => __('Message en haut de la vue index'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_print',
-            'type' => 'FormSection',
-            'label' => __('Impression'),
-        ]);
-        $this->addField([
-            'name' => 'print',
-            'type' => 'Checkbox',
-            'label' => __('Activer l\'impression'),
+        $this->addField('section_print', FormSection::class, __('Impression'));
+        $this->addField('print', Checkbox::class, __('Activer l\'impression'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'printFullBrochure',
-            'type' => 'Checkbox',
-            'label' => __('Autoriser l\'impression de la brochure complète'),
+        $this->addField('printFullBrochure', Checkbox::class, __('Autoriser l\'impression de la brochure complète'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'printPageRange',
-            'type' => 'Checkbox',
-            'label' => __('Activer l\'option pour imprimer une plage de pages'),
+        $this->addField('printPageRange', Checkbox::class, __('Activer l\'option pour imprimer une plage de pages'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_search',
-            'type' => 'FormSection',
-            'label' => __('Moteur de recherche'),
-        ]);
-        $this->addField([
-            'name' => 'search',
-            'type' => 'Checkbox',
-            'label' => __('Activer le moteur de recherche'),
+        $this->addField('section_search', FormSection::class, __('Moteur de recherche'));
+        $this->addField('search', Checkbox::class, __('Activer le moteur de recherche'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('', FormSeparator::class);
+        $this->addField('searchFullBurger', Checkbox::class, __('Afficher le burger menu complet à l\'ouverture de la recheche'), [
+            'default' => false,
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'ignoreWordLimit',
-            'type' => 'Integer',
-            'label' => __('Ignorer les mots de moins de X caractères'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('ignoreWordLimit', Integer::class, __('Ignorer les mots de moins de X caractères'), [
             'default' => 3,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'ignoreSearch',
-            'type' => 'Textarea',
-            'label' => __('Mots à ignorer'),
+        $this->addField('ignoreSearch', Textarea::class, __('Mots à ignorer'), [
             'hint' => __('Liste des mots à ignorer séparés par des virgules'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'ignoreSearchSeparators',
-            'type' => 'LongText',
-            'label' => __('Caractères à ne pas considérer comme un séparateur de mot'),
+        $this->addField('ignoreSearchSeparators', LongText::class, __('Caractères à ne pas considérer comme un séparateur de mot'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'searchWordSelectionAlgorithm',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('searchWordSelectionAlgorithm', SelectFromArray::class, __('Algorithme de sélection des occurences'), [
             'options' => [
                 'begins' => 'mot commençant par la requête',
                 'exact' => 'mot correspondant exactement à la requête',
                 'contains' => 'mot contenant la requête',
                 'expression' => 'expression exacte',
             ],
-            'label' => __('Algorithme de sélection des occurences'),
             'default' => 'begins',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'searchPageSelectionAlgorithm',
-            'type' => 'SelectFromArray',
+        $this->addField('searchPageSelectionAlgorithm', SelectFromArray::class, __('Algorithme de sélection des résultats'), [
             'options' => [
                 'AND' => 'les double-pages qui contiennent tous les mots recherchés (ET logique)',
                 'OR' => 'les double-page qui contiennent un des mots recherché (OU logique)',
             ],
-            'label' => __('Algorithme de sélection des résultats'),
             'default' => 'AND',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'highlightResults',
-            'type' => 'Checkbox',
-            'label' => __('Surligner les résultats'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('highlightResults', Checkbox::class, __('Surligner les résultats'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'highlightAllOccurences',
-            'type' => 'Checkbox',
-            'label' => __('Surligner toutes les occurences'),
+        $this->addField('highlightAllOccurences', Checkbox::class, __('Surligner toutes les occurences'), [
             'hint' => __('Même sur les pages non considérées comme un résultat'),
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'searchShowNoResultsPages',
-            'type' => 'Checkbox',
-            'label' => __('Afficher les pages sans résultats'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('searchShowNoResultsPages', Checkbox::class, __('Afficher les pages sans résultats'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'textExtraction',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('textExtraction', SelectFromArray::class, __('Méthode d\'extraction des textes'), [
             'options' => [
                 'pdfbox' => 'PDFBox',
                 'poppler' => 'Poppler',
                 'fluidbook' => 'Fluidbook (expérimentation basée sur PDFBox)',
             ],
-            'label' => __('Méthode d\'extraction des textes'),
             'default' => 'pdfbox',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_sound',
-            'type' => 'FormSection',
-            'label' => __('Effets sonores'),
-        ]);
-        $this->addField([
-            'name' => 'soundTheme',
-            'type' => 'SelectFromArray',
+        $this->addField('section_sound', FormSection::class, __('Effets sonores'));
+        $this->addField('soundTheme', SelectFromArray::class, __('Thème sonore'), [
             'options' => [
                 '' => 'Pas de son',
                 'classic' => 'Classique',
@@ -1396,24 +906,15 @@ class FluidbookPublication extends ToolboxModel
                 'silent' => 'Silencieux',
                 'woosh' => 'Woosh',
             ],
-            'label' => __('Thème sonore'),
             'default' => 'classic',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'soundOn',
-            'type' => 'Checkbox',
-            'label' => __('Activer les effets sonores à l\'ouverture'),
+        $this->addField('soundOn', Checkbox::class, __('Activer les effets sonores à l\'ouverture'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'ambientSound',
-            'type' => 'FilesOrURL',
-            'label' => __('Ambiance sonore'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('ambientSound', FilesOrURL::class, __('Ambiance sonore'), [
             'default' => '',
             'accept' => [
                 0 => '*.mp3',
@@ -1421,334 +922,193 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'ambientSoundVolume',
-            'type' => 'Integer',
-            'label' => __('Volume de l\'ambiance sonore'),
+        $this->addField('ambientSoundVolume', Integer::class, __('Volume de l\'ambiance sonore'), [
             'min' => 0,
             'max' => 100,
             'default' => 50,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_downloadpdf',
-            'type' => 'FormSection',
-            'label' => __('Fonction de téléchargement'),
-        ]);
-        $this->addField([
-            'name' => 'pdf',
-            'type' => 'Checkbox',
-            'label' => __('Activer les fonctions de téléchargement'),
+        $this->addField('section_downloadpdf', FormSection::class, __('Fonction de téléchargement'));
+        $this->addField('pdf', Checkbox::class, __('Activer les fonctions de téléchargement'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pdfName',
-            'type' => 'LongText',
-            'label' => __('Nom du fichier PDF'),
+        $this->addField('pdfName', LongText::class, __('Nom du fichier PDF'), [
             'default' => 'document.pdf',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pdfReplace',
-            'type' => 'FilesOrURL',
-            'label' => __('PDF de remplacement'),
+        $this->addField('pdfReplace', FilesOrURL::class, __('PDF de remplacement'), [
             'default' => '',
             'accept' => [
                 0 => '*.pdf',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pdfCompress',
-            'type' => 'Checkbox',
-            'label' => __('Compression du fichier PDF'),
+        $this->addField('pdfCompress', Checkbox::class, __('Compression du fichier PDF'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'pdfComplex',
-            'type' => 'Checkbox',
-            'label' => __('Téchargement de PDF avancé'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('pdfComplex', Checkbox::class, __('Téchargement de PDF avancé'), [
             'hint' => __('Permet à l\'utilisateur de sélectionner les pages qu\'il souhaite télécharger'),
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'offlineExport',
-            'type' => 'Checkbox',
-            'label' => __('Téléchargement des versions offline'),
-            'hint' => __('Valable si le téléchargement avancé est activé'),
-            'default' => false,
+        $this->addField('pdfComplexShowCurrent', Checkbox::class, __('Afficher les pages courrantes'), [
+            'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_zoom',
-            'type' => 'FormSection',
-            'label' => __('Zoom'),
-        ]);
-        $this->addField([
-            'name' => 'zoomWheel',
-            'type' => 'SelectFromArray',
+        $this->addField('section_zoom', FormSection::class, __('Zoom'));
+        $this->addField('zoomWheel', SelectFromArray::class, __('Zoom molette'), [
             'options' => [
                 'disabled' => 'Désactivé',
                 'wheel' => 'Molette',
                 'ctrlwheel' => 'Ctrl+Molette',
             ],
-            'label' => __('Zoom molette'),
             'default' => 'wheel',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'zoom',
-            'type' => 'Integer',
-            'label' => __('Zoom par défaut (atteint au clic)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('zoom', Integer::class, __('Zoom par défaut (atteint au clic)'), [
             'default' => 200,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'zoomw',
-            'type' => 'Integer',
-            'label' => __('Zoom maximal (atteint à l\'aide de la molette)'),
+        $this->addField('zoomw', Integer::class, __('Zoom maximal (atteint à l\'aide de la molette)'), [
             'default' => 300,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_stats',
-            'type' => 'FormSection',
-            'label' => __('Statistiques avancées'),
+        $this->addField('section_stats', FormSection::class, __('Statistiques avancées'));
+        $this->addField('tagcommander_id', LongText::class, __('Tag commander ID'), [
+            'default' => '',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'stats_score',
-            'type' => 'Checkbox',
-            'label' => __('Afficher les scores dans les rapports'),
+        $this->addField('tagcommander_prod', Checkbox::class, __('Production'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'stats_exclude_ip',
-            'type' => 'Textarea',
-            'label' => __('Exclure les IP suivantes des statistiques'),
-            'hint' => __('Indiquer une adresse ip de la forme www.xxx.yyy.zzz par ligne'),
+        $this->addField('tagcommander_plan', FilesOrURL::class, __('Plan de taggage "Tag commander"'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'relay_url_params',
-            'type' => 'LongText',
-            'label' => __('Relayer les paramètres d\'url dans les liens sortants'),
+        $this->addField('tagcommander_default_vars', Textarea::class, __('Variables par défaut'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'gtag_additional_code',
-            'type' => 'Textarea',
-            'label' => __('Code additionnel Google Tag Manager'),
+        $this->addField('anchorsAliases', LongText::class, __('Alias des ancres'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'googleAnalyticsCustom',
-            'type' => 'Textarea',
-            'label' => __('Code Stats personnalisé (placé avant fermeture de head)'),
-            'default' => '',
+        $this->addField('', FormSeparator::class);
+        $this->addField('stats_score', Checkbox::class, __('Afficher les scores dans les rapports'), [
+            'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'statsCustom',
-            'type' => 'Textarea',
-            'label' => __('Code Stats personnalisé (placé avant fermeture du body)'),
+        $this->addField('stats_exclude_ip', Textarea::class, __('Exclure les IP suivantes des statistiques'), [
+            'hint' => __('Indiquer une adresse ip de la forme www.xxx.yyy.zzz par ligne'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'xiti',
-            'type' => 'Textarea',
-            'label' => __('Code XiTi global'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('relay_url_params', LongText::class, __('Relayer les paramètres d\'url dans les liens sortants'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'xiti_page',
-            'type' => 'Textarea',
-            'label' => __('Modèle code xiti (pour tags relatifs aux pages)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('gtag_additional_code', Textarea::class, __('Code additionnel Google Tag Manager'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'tagcommander_id',
-            'type' => 'LongText',
-            'label' => __('Tag commander ID'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('googleAnalyticsCustom', Textarea::class, __('Code Stats personnalisé (placé avant fermeture de head)'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tagcommander_prod',
-            'type' => 'Checkbox',
-            'label' => __('Production'),
-            'default' => true,
+        $this->addField('statsCustom', Textarea::class, __('Code Stats personnalisé (placé avant fermeture du body)'), [
+            'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tagcommander_plan',
-            'type' => 'FilesOrURL',
-            'label' => __('Plan de taggage "Tag commander"'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('xiti', Textarea::class, __('Code XiTi global'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tagcommander_default_vars',
-            'type' => 'Textarea',
-            'label' => __('Variables par défaut'),
+        $this->addField('xiti_page', Textarea::class, __('Modèle code xiti (pour tags relatifs aux pages)'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_sommaire',
-            'type' => 'FormSection',
-            'label' => __('Sommaire'),
-        ]);
-        $this->addField([
-            'name' => 'chaptersCaptionDisplay',
-            'type' => 'Checkbox',
-            'label' => __('Afficher le titre "Sommaire" dans la popup'),
+        $this->addField('section_sommaire', FormSection::class, __('Sommaire'));
+        $this->addField('chaptersCaptionDisplay', Checkbox::class, __('Afficher le titre "Sommaire" dans la popup'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersFontSize',
-            'type' => 'Integer',
-            'label' => __('Taille du texte des élements du sommaire'),
+        $this->addField('chaptersFontSize', Integer::class, __('Taille du texte des élements du sommaire'), [
             'hint' => __('En % par rapport à la taille normale'),
             'min' => 50,
             'max' => 120,
             'default' => 100,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'displayChaptersIcon',
-            'type' => 'Checkbox',
-            'label' => __('Affiche l\'icône du sommaire'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('displayChaptersIcon', Checkbox::class, __('Affiche l\'icône du sommaire'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'displayChaptersPopup',
-            'type' => 'Checkbox',
-            'label' => __('Always display chapters in a popup'),
+        $this->addField('displayChaptersPopup', Checkbox::class, __('Always display chapters in a popup'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'displayChaptersAtStart',
-            'type' => 'Checkbox',
-            'label' => __('Afficher le sommaire au chargement de la publication'),
+        $this->addField('displayChaptersAtStart', Checkbox::class, __('Afficher le sommaire au chargement de la publication'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersPage',
-            'type' => 'LongText',
-            'label' => __('Faire pointer le sommaire sur la page'),
+        $this->addField('chaptersPage', LongText::class, __('Faire pointer le sommaire sur la page'), [
             'hint' => __('Laisser vide pour utiliser le sommaire classique'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersPosition',
-            'type' => 'SelectFromArray',
+        $this->addField('chaptersPosition', SelectFromArray::class, __('Position du sommaire'), [
             'options' => [
                 'center' => 'Centré',
                 'chaptersIcon' => 'Aligné sur l\'icône',
             ],
-            'label' => __('Position du sommaire'),
             'default' => 'center',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersLevelLimit',
-            'type' => 'Integer',
-            'label' => __('Limiter à x niveaux'),
+        $this->addField('chaptersLevelLimit', Integer::class, __('Limiter à x niveaux'), [
             'default' => 5,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersCascade',
-            'type' => 'Checkbox',
-            'label' => __('Sommaire en cascade'),
+        $this->addField('chaptersCascade', Checkbox::class, __('Sommaire en cascade'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersPagesNumber',
-            'type' => 'SelectFromArray',
+        $this->addField('chaptersPagesNumber', SelectFromArray::class, __('Numérotation du sommaire'), [
             'options' => [
                 'virtual' => 'Virtuelle',
                 'physical' => 'Physique',
             ],
-            'label' => __('Numérotation du sommaire'),
             'default' => 'virtual',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'chaptersColMaxWidth',
-            'type' => 'Integer',
-            'label' => __('Largeur max d\'une colonne'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('chaptersColMaxWidth', Integer::class, __('Largeur max d\'une colonne'), [
             'default' => 300,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersColumns',
-            'type' => 'Integer',
-            'label' => __('Afficher le sommaire sur x colonne(s)'),
+        $this->addField('chaptersColumns', Integer::class, __('Afficher le sommaire sur x colonne(s)'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'displayChaptersLine',
-            'type' => 'Checkbox',
-            'label' => __('Affiche une ligne entre le label et le numéro de page'),
+        $this->addField('displayChaptersLine', Checkbox::class, __('Affiche une ligne entre le label et le numéro de page'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'chaptersIndent',
-            'type' => 'Checkbox',
-            'label' => __('Indenter les éléments (pour les sommaires à plat)'),
+        $this->addField('chaptersIndent', Checkbox::class, __('Indenter les éléments (pour les sommaires à plat)'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'externalChaptersHTML',
-            'type' => 'FilesOrURL',
-            'label' => __('Sommaire personnalisé'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('externalChaptersHTML', FilesOrURL::class, __('Sommaire personnalisé'), [
             'hint' => __('Laisser vide pour utiliser le sommaire classique'),
             'default' => '',
             'accept' => [
@@ -1756,29 +1116,17 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'mobileChaptersStyle',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('mobileChaptersStyle', SelectFromArray::class, __('Style des chapitres'), [
             'options' => [
                 'classic' => 'Classique',
                 'ina' => 'INA',
             ],
-            'label' => __('Style des chapitres'),
             'default' => 'classic',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_tabs',
-            'type' => 'FormSection',
-            'label' => __('Onglets'),
-        ]);
-        $this->addField([
-            'name' => 'tabsHTML5',
-            'type' => 'FilesOrURL',
-            'label' => __('Fichier d\'onglets (SVG, ZIP)'),
+        $this->addField('section_tabs', FormSection::class, __('Onglets'));
+        $this->addField('tabsHTML5', FilesOrURL::class, __('Fichier d\'onglets (SVG, ZIP)'), [
             'hint' => __('Charger un zip rendra les options ci-dessous inopérantes'),
             'default' => '',
             'accept' => [
@@ -1787,426 +1135,248 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsPages',
-            'type' => 'LongText',
-            'label' => __('Pages des onglets'),
+        $this->addField('tabsPages', LongText::class, __('Pages des onglets'), [
             'hint' => __('Numéros de pages séparas par une virgule'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsSections',
-            'type' => 'LongText',
-            'label' => __('Sections des onglets'),
+        $this->addField('tabsSections', LongText::class, __('Sections des onglets'), [
             'hint' => __('Numéros de pages séparés par une virgule'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsPagesNumbers',
-            'type' => 'SelectFromArray',
+        $this->addField('tabsPagesNumbers', SelectFromArray::class, __('Numérotation utilisée'), [
             'options' => [
                 'virtual' => 'Virtuelle',
                 'physical' => 'Physique',
             ],
-            'label' => __('Numérotation utilisée'),
             'default' => 'virtual',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('tabsDisabledOnPages', LongText::class, __('Onglets inactifs sur les pages'), [
+            'hint' => __('1-3,5 = 1,2,3,5'),
+            'default' => '',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsSide',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('tabsSide', SelectFromArray::class, __('Position des onglets'), [
             'options' => [
                 'left' => 'Gauche',
                 'right' => 'Droite',
             ],
-            'label' => __('Position des onglets'),
             'default' => 'right',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsMargin',
-            'type' => 'Number',
-            'label' => __('Marge des onglets'),
+        $this->addField('tabsMargin', Number::class, __('Marge des onglets'), [
             'hint' => __('Une marge négative = les onglets passent sous la publication'),
             'default' => -10,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'tabsHideOnPages',
-            'type' => 'LongText',
-            'label' => __('Cacher les onglets sur les pages'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('tabsHideOnPages', LongText::class, __('Cacher les onglets sur les pages'), [
             'hint' => __('1-3,5 = 1,2,3,5'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsHideOnCover',
-            'type' => 'Checkbox',
-            'label' => __('Cacher les onglets sur la couverture'),
+        $this->addField('tabsHideOnCover', Checkbox::class, __('Cacher les onglets sur la couverture'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsHideOnLastPage',
-            'type' => 'Checkbox',
-            'label' => __('Cacher les onglets sur la dernière page'),
+        $this->addField('tabsHideOnLastPage', Checkbox::class, __('Cacher les onglets sur la dernière page'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsHideEdges',
-            'type' => 'SelectFromArray',
+        $this->addField('tabsHideEdges', SelectFromArray::class, __('Masquer les bordures du fluidbook'), [
             'options' => [
                 'none' => 'Aucune',
                 'left' => 'Gauche',
                 'right' => 'Droite',
                 'both' => 'Les deux',
             ],
-            'label' => __('Masquer les bordures du fluidbook'),
             'default' => 'right',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'tabsPriority',
-            'type' => 'Integer',
-            'label' => __('Priorité des onglets sur les contenus (%)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('tabsPriority', Integer::class, __('Priorité des onglets sur les contenus (%)'), [
             'hint' => __('La valeur indique la réduction permise de la taille de la publication.'),
             'min' => 0,
             'max' => 100,
             'default' => 15,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsLinkWidth',
-            'type' => 'Number',
-            'label' => __('Largeur des onglets'),
+        $this->addField('tabsLinkWidth', Number::class, __('Largeur des onglets'), [
             'hint' => __('Largeur réservée pour les onglets et largeur de la zone cliquable des liens'),
             'default' => 30,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsHideWhenOverlapingArrows',
-            'type' => 'Checkbox',
-            'label' => __('Cacher les onglets lorsqu\'ils passent sous les flèches de navigation'),
+        $this->addField('tabsHideWhenOverlapingArrows', Checkbox::class, __('Cacher les onglets lorsqu\'ils passent sous les flèches de navigation'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsHideOnPortrait',
-            'type' => 'Checkbox',
-            'label' => __('Cacher les onglets lorsque le fluidbook est en mode portrait'),
+        $this->addField('tabsHideOnPortrait', Checkbox::class, __('Cacher les onglets lorsque le fluidbook est en mode portrait'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'tabsHideOnZoom',
-            'type' => 'Checkbox',
-            'label' => __('Cacher les onglets lorsque le fluidbook est zoomé'),
+        $this->addField('tabsHideOnZoom', Checkbox::class, __('Cacher les onglets lorsque le fluidbook est zoomé'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_links',
-            'type' => 'FormSection',
-            'label' => __('Liens'),
-        ]);
-        $this->addField([
-            'name' => 'permanentLinks',
-            'type' => 'Checkbox',
-            'label' => __('Liens visibles en permanence'),
+        $this->addField('section_links', FormSection::class, __('Liens'));
+        $this->addField('permanentLinks', Checkbox::class, __('Liens visibles en permanence'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobileLinksRevealAnim',
-            'type' => 'Checkbox',
-            'label' => __('Animer les liens après un changement de page'),
+        $this->addField('mobileLinksRevealAnim', Checkbox::class, __('Animer les liens après un changement de page'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkBlinkTime',
-            'type' => 'Number',
-            'label' => __('Temps d\'apparition du lien à l\'ouverture de la page (en secondes)'),
+        $this->addField('linkBlinkTime', Number::class, __('Temps d\'apparition du lien à l\'ouverture de la page (en secondes)'), [
             'default' => 1.0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkBlinkRepetition',
-            'type' => 'Integer',
-            'label' => __('Nombre de clignotement lors de l\'apparition des liens'),
+        $this->addField('linkBlinkRepetition', Integer::class, __('Nombre de clignotement lors de l\'apparition des liens'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'openLinkAtStartup',
-            'type' => 'LongText',
-            'label' => __('Déclencher un lien à l\'ouverture du fluidbook'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('openLinkAtStartup', LongText::class, __('Déclencher un lien à l\'ouverture du fluidbook'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'customLinkClass',
-            'type' => 'LongText',
-            'label' => __('Classe pour les liens personnalisés'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('customLinkClass', LongText::class, __('Classe pour les liens personnalisés'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'ignoreLinksTypes',
-            'type' => 'LongText',
-            'label' => __('Ignorer les liens de type'),
+        $this->addField('ignoreLinksTypes', LongText::class, __('Ignorer les liens de type'), [
             'hint' => __('Liste des numéros séparés par des virgules'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobileIgnoreBackgroundLinks',
-            'type' => 'Checkbox',
-            'label' => __('Ignorer les liens de background'),
+        $this->addField('mobileIgnoreBackgroundLinks', Checkbox::class, __('Ignorer les liens de background'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkTooltipManager',
-            'type' => 'LongText',
-            'label' => __('Gestionnaire des info-bulles'),
+        $this->addField('linkTooltipManager', LongText::class, __('Gestionnaire des info-bulles'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkCornerSize',
-            'type' => 'Integer',
-            'label' => __('Taille des liens de coins de page'),
+        $this->addField('linkCornerSize', Integer::class, __('Taille des liens de coins de page'), [
             'hint' => __('Pourcentage de la largeur de la page'),
             'default' => 10,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkTooltipMaxWidth',
-            'type' => 'Integer',
-            'label' => __('Largeur max des infobulles des liens de type "infobulle"'),
+        $this->addField('linkTooltipMaxWidth', Integer::class, __('Largeur max des infobulles des liens de type "infobulle"'), [
             'default' => 140,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'linkTracker',
-            'type' => 'LongText',
-            'label' => __('Tracking des liens'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('linkTracker', LongText::class, __('Tracking des liens'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'linkTrackerRegexp',
-            'type' => 'LongText',
-            'label' => __('Tracking des liens applicables aux liens du domaine'),
+        $this->addField('linkTrackerRegexp', LongText::class, __('Tracking des liens applicables aux liens du domaine'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'linkFilePrefix',
-            'type' => 'LongText',
-            'label' => __('Préfixer les liens de téléchargement'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('linkFilePrefix', LongText::class, __('Préfixer les liens de téléchargement'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_multimedia',
-            'type' => 'FormSection',
-            'label' => __('Multimedia'),
-        ]);
-        $this->addField([
-            'name' => 'textPopupStylesheet',
-            'type' => 'FilesOrURL',
-            'label' => __('Feuille de style des popups de texte'),
+        $this->addField('section_multimedia', FormSection::class, __('Multimedia'));
+        $this->addField('textPopupStylesheet', FilesOrURL::class, __('Feuille de style des popups de texte'), [
             'default' => '',
             'accept' => [
                 0 => '*.css',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'textPopupWidth',
-            'type' => 'Integer',
-            'label' => __('Largeur optimale des popups'),
+        $this->addField('textPopupWidth', Integer::class, __('Largeur optimale des popups'), [
             'default' => 600,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'iframePopupMaxWidth',
-            'type' => 'Integer',
-            'label' => __('Largeur maximale des popups iframe'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('iframePopupMaxWidth', Integer::class, __('Largeur maximale des popups iframe'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'OAMChromeFactor',
-            'type' => 'Number',
-            'label' => __('Facteur OAM Chrome'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('OAMChromeFactor', Number::class, __('Facteur OAM Chrome'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'OAMIEFactor',
-            'type' => 'Number',
-            'label' => __('Facteur OAM IE11'),
+        $this->addField('OAMIEFactor', Number::class, __('Facteur OAM IE11'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_pdf',
-            'type' => 'FormSection',
-            'label' => __('PDF'),
-        ]);
-        $this->addField([
-            'name' => 'PDFRenderer',
-            'type' => 'SelectFromArray',
+        $this->addField('section_pdf', FormSection::class, __('PDF'));
+        $this->addField('PDFRenderer', SelectFromArray::class, __('Rendu des PDF par'), [
             'options' => [
                 'native' => 'Navigateur',
                 'pdfjs' => 'PDF.js',
                 'pdfjs-legacy' => 'PDF.js (legacy)',
             ],
-            'label' => __('Rendu des PDF par'),
             'default' => 'native',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'PDFJSCSS',
-            'type' => 'Textarea',
-            'label' => __('Styles PDF.js'),
+        $this->addField('PDFJSCSS', Textarea::class, __('Styles PDF.js'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_slideshow',
-            'type' => 'FormSection',
-            'label' => __('Slideshow'),
-        ]);
-        $this->addField([
-            'name' => 'inlineSlideshowLibrary',
-            'type' => 'SelectFromArray',
+        $this->addField('section_slideshow', FormSection::class, __('Slideshow'));
+        $this->addField('inlineSlideshowLibrary', SelectFromArray::class, __('Librarie utilisée pour les slideshow intégrés aux pages'), [
             'options' => [
                 'dummy' => 'Simple (défaut)',
                 'vacheron' => 'Vacheron',
             ],
-            'label' => __('Librarie utilisée pour les slideshow intégrés aux pages'),
             'default' => 'dummy',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'popupSlideshowLibrary',
-            'type' => 'SelectFromArray',
+        $this->addField('popupSlideshowLibrary', SelectFromArray::class, __('Librarie utilisée pour les slideshow popup'), [
             'options' => [
                 'splide' => 'Splide (défaut)',
                 'vacheron' => 'Vacheron',
             ],
-            'label' => __('Librarie utilisée pour les slideshow popup'),
             'default' => 'splide',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'slideshowCaptionSize',
-            'type' => 'LongText',
-            'label' => __('Taille de police de la légende du diaporama'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('slideshowCaptionSize', LongText::class, __('Taille de police de la légende du diaporama'), [
             'hint' => __('Laisser vide pour utiliser la valeur par défaut'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'inlineSlideshowTransitionDuration',
-            'type' => 'Number',
-            'label' => __('Durée de la transition des diaporamas intégrés aux pages(s)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('inlineSlideshowTransitionDuration', Number::class, __('Durée de la transition des diaporamas intégrés aux pages(s)'), [
             'default' => 0.75,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'inlineSlideshowDuration',
-            'type' => 'Number',
-            'label' => __('Temps d\'attente des diaporamas intégrés aux pages (s)'),
+        $this->addField('inlineSlideshowDuration', Number::class, __('Temps d\'attente des diaporamas intégrés aux pages (s)'), [
             'default' => 7,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_videos',
-            'type' => 'FormSection',
-            'label' => __('Vidéos'),
-        ]);
-        $this->addField([
-            'name' => 'webvideoAsLocal',
-            'type' => 'Checkbox',
-            'label' => __('Intégrer les webvidéos en local'),
+        $this->addField('section_videos', FormSection::class, __('Vidéos'));
+        $this->addField('webvideoAsLocal', Checkbox::class, __('Intégrer les webvidéos en local'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'mobileVideosPath',
-            'type' => 'LongText',
-            'label' => __('Chemin vers les vidéos'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('mobileVideosPath', LongText::class, __('Chemin vers les vidéos'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'brightcovePlayerId',
-            'type' => 'LongText',
-            'label' => __('Brightcove Player Id'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('brightcovePlayerId', LongText::class, __('Brightcove Player Id'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'brightcovePlayerSecret',
-            'type' => 'LongText',
-            'label' => __('Brightcove Player Secret'),
+        $this->addField('brightcovePlayerSecret', LongText::class, __('Brightcove Player Secret'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'bigPlayImage',
-            'type' => 'FilesOrURL',
-            'label' => __('Image pour le bouton "Big Play"'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('bigPlayImage', FilesOrURL::class, __('Image pour le bouton "Big Play"'), [
             'default' => '',
             'accept' => [
                 0 => '*.svg',
@@ -2216,51 +1386,27 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_audio',
-            'type' => 'FormSection',
-            'label' => __('Lecteur audio'),
-        ]);
-        $this->addField([
-            'name' => 'audioPlayerTheme',
-            'type' => 'SelectFromArray',
+        $this->addField('section_audio', FormSection::class, __('Lecteur audio'));
+        $this->addField('audioPlayerTheme', SelectFromArray::class, __('Apparence du lecteur audio'), [
             'options' => [
                 'native' => 'Apparence native du navigateur',
                 'invisible' => 'Zone cliquable invisible',
-                'redbull' => 'Red Bull',
+                'redbull' => 'Circulaire',
             ],
-            'label' => __('Apparence du lecteur audio'),
             'default' => 'native',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_downloadportion',
-            'type' => 'FormSection',
-            'label' => __('Téléchargement d\'extraits'),
-        ]);
-        $this->addField([
-            'name' => 'downloadPortionPDF',
-            'type' => 'FilesOrURL',
-            'label' => __('PDF utilisé pour le téléchargement des extraits'),
+        $this->addField('section_downloadportion', FormSection::class, __('Téléchargement d\'extraits'));
+        $this->addField('downloadPortionPDF', FilesOrURL::class, __('PDF utilisé pour le téléchargement des extraits'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'downloadPortionZoom',
-            'type' => 'Integer',
-            'label' => __('Zoom des images extraites'),
+        $this->addField('downloadPortionZoom', Integer::class, __('Zoom des images extraites'), [
             'default' => 8,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_product_zoom',
-            'type' => 'FormSection',
-            'label' => __('Zooms produits'),
-        ]);
-        $this->addField([
-            'name' => 'product_zoom_references',
-            'type' => 'FilesOrURL',
-            'label' => __('Références produits'),
+        $this->addField('section_product_zoom', FormSection::class, __('Zooms produits'));
+        $this->addField('product_zoom_references', FilesOrURL::class, __('Références produits'), [
             'hint' => __('Fichier contenant les références produits'),
             'default' => '',
             'accept' => [
@@ -2269,40 +1415,25 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'product_zoom_buttons_order',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('product_zoom_buttons_order', SelectFromArray::class, __('Order des boutons'), [
             'options' => [
                 'right' => 'De la droite vers la gauche',
                 'left' => 'De la gauche vers la droite',
             ],
-            'label' => __('Order des boutons'),
             'default' => 'right',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'product_zoom_label_1',
-            'type' => 'LongText',
-            'label' => __('Label du bouton 1'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('product_zoom_label_1', LongText::class, __('Label du bouton 1'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_tooltip_1',
-            'type' => 'LongText',
-            'label' => __('Label de l\'infobulle 1'),
+        $this->addField('product_zoom_tooltip_1', LongText::class, __('Label de l\'infobulle 1'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_icon_1',
-            'type' => 'SelectFromArray',
+        $this->addField('product_zoom_icon_1', SelectFromArray::class, __('Icône du bouton 1'), [
             'options' => [
                 'none' => 'Aucune',
                 'nav-share' => 'Partage',
@@ -2320,13 +1451,10 @@ class FluidbookPublication extends ToolboxModel
                 'icon-360' => '360°',
                 'icon-photo' => 'Photo',
             ],
-            'label' => __('Icône du bouton 1'),
             'default' => 'click',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_action_1',
-            'type' => 'SelectFromArray',
+        $this->addField('product_zoom_action_1', SelectFromArray::class, __('Action du bouton 1'), [
             'options' => [
                 'disabled' => 'Désactiver',
                 'link' => 'Ouvrir un lien',
@@ -2338,30 +1466,19 @@ class FluidbookPublication extends ToolboxModel
                 'image' => 'Voir une image',
                 'addtocart' => 'Ajouter au panier',
             ],
-            'label' => __('Action du bouton 1'),
             'default' => 'disabled',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'product_zoom_label_2',
-            'type' => 'LongText',
-            'label' => __('Label du bouton 2'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('product_zoom_label_2', LongText::class, __('Label du bouton 2'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_tooltip_2',
-            'type' => 'LongText',
-            'label' => __('Label de l\'infobulle 2'),
+        $this->addField('product_zoom_tooltip_2', LongText::class, __('Label de l\'infobulle 2'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_icon_2',
-            'type' => 'SelectFromArray',
+        $this->addField('product_zoom_icon_2', SelectFromArray::class, __('Icône du bouton 2'), [
             'options' => [
                 'none' => 'Aucune',
                 'nav-share' => 'Partage',
@@ -2379,13 +1496,10 @@ class FluidbookPublication extends ToolboxModel
                 'icon-360' => '360°',
                 'icon-photo' => 'Photo',
             ],
-            'label' => __('Icône du bouton 2'),
             'default' => 'click',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_action_2',
-            'type' => 'SelectFromArray',
+        $this->addField('product_zoom_action_2', SelectFromArray::class, __('Action du bouton 2'), [
             'options' => [
                 'disabled' => 'Désactiver',
                 'link' => 'Ouvrir un lien',
@@ -2397,30 +1511,19 @@ class FluidbookPublication extends ToolboxModel
                 'image' => 'Voir une image',
                 'addtocart' => 'Ajouter au panier',
             ],
-            'label' => __('Action du bouton 2'),
             'default' => 'disabled',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'product_zoom_label_3',
-            'type' => 'LongText',
-            'label' => __('Label du bouton 3'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('product_zoom_label_3', LongText::class, __('Label du bouton 3'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_tooltip_3',
-            'type' => 'LongText',
-            'label' => __('Label de l\'infobulle 3'),
+        $this->addField('product_zoom_tooltip_3', LongText::class, __('Label de l\'infobulle 3'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_icon_3',
-            'type' => 'SelectFromArray',
+        $this->addField('product_zoom_icon_3', SelectFromArray::class, __('Icône du bouton 3'), [
             'options' => [
                 'none' => 'Aucune',
                 'nav-share' => 'Partage',
@@ -2438,13 +1541,10 @@ class FluidbookPublication extends ToolboxModel
                 'icon-360' => '360°',
                 'icon-photo' => 'Photo',
             ],
-            'label' => __('Icône du bouton 3'),
             'default' => 'click',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_zoom_action_3',
-            'type' => 'SelectFromArray',
+        $this->addField('product_zoom_action_3', SelectFromArray::class, __('Action du bouton 3'), [
             'options' => [
                 'disabled' => 'Désactiver',
                 'link' => 'Ouvrir un lien',
@@ -2456,90 +1556,57 @@ class FluidbookPublication extends ToolboxModel
                 'image' => 'Voir une image',
                 'addtocart' => 'Ajouter au panier',
             ],
-            'label' => __('Action du bouton 3'),
             'default' => 'disabled',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'product_share_enabled',
-            'type' => 'Checkbox',
-            'label' => __('Activer le bouton de partage'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('product_share_enabled', Checkbox::class, __('Activer le bouton de partage'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_share_link',
-            'type' => 'SelectFromArray',
+        $this->addField('product_share_link', SelectFromArray::class, __('Lien de partage'), [
             'options' => [
                 'product' => 'Lien du produit',
                 'page' => 'Lien vers la page du fluidbook',
             ],
-            'label' => __('Lien de partage'),
             'default' => 'product',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_email_title',
-            'type' => 'LongText',
-            'label' => __('Titre de l\'email "Envoyer à un ami"'),
+        $this->addField('product_email_title', LongText::class, __('Titre de l\'email "Envoyer à un ami"'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_email_body',
-            'type' => 'Textarea',
-            'label' => __('Corps de l\'email "Envoyer à un ami"'),
+        $this->addField('product_email_body', Textarea::class, __('Corps de l\'email "Envoyer à un ami"'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'product_tweet',
-            'type' => 'Textarea',
-            'label' => __('Contenu Partage court'),
+        $this->addField('product_tweet', Textarea::class, __('Contenu Partage court'), [
             'hint' => __('Contenu du partagé sur les partages courts'),
             'default' => '%short%',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_accessibility',
-            'type' => 'FormSection',
-            'label' => __('Accessibilité'),
-        ]);
-        $this->addField([
-            'name' => 'audiodescriptionTexts',
-            'type' => 'FilesOrURL',
-            'label' => __('Contenus textuels pour l\'audiodescription ou les lecteurs d\'écran'),
+        $this->addField('section_accessibility', FormSection::class, __('Accessibilité'));
+        $this->addField('audiodescriptionTexts', FilesOrURL::class, __('Contenus textuels pour l\'audiodescription ou les lecteurs d\'écran'), [
             'default' => '',
             'accept' => [
                 0 => '*.xlsx',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'audiodescriptionVoice',
-            'type' => 'SelectFromArray',
+        $this->addField('audiodescriptionVoice', SelectFromArray::class, __('Voix pour l\'audiodescription'), [
             'options' => [
                 '' => '',
                 'festival:voice_cmu_us_slt_arctic_hts' => 'Festival (en-US)',
                 'readspeaker:Sophie/en_us' => 'ReadSpeaker Sophie (en-US)',
                 'readspeaker:Marc/en_us' => 'ReadSpeaker Marc (en-US)',
+                'azuretts:fr-FR/Female/fr-FR-DeniseNeural' => 'Azure Denise (fr-FR)',
+                'azuretts:fr-FR/Male/fr-FR-MaleNeural' => 'Azure Henry (fr-FR)',
             ],
-            'label' => __('Voix pour l\'audiodescription'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_splash',
-            'type' => 'FormSection',
-            'label' => __('Ecran de chargement'),
-        ]);
-        $this->addField([
-            'name' => 'splashImage',
-            'type' => 'FilesOrURL',
-            'label' => __('Image'),
+        $this->addField('section_splash', FormSection::class, __('Ecran de chargement'));
+        $this->addField('splashImage', FilesOrURL::class, __('Image'), [
             'default' => '',
             'accept' => [
                 0 => '*.jpg',
@@ -2548,114 +1615,72 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'splashURL',
-            'type' => 'LongText',
-            'label' => __('URL'),
+        $this->addField('splashURL', LongText::class, __('URL'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'splashTarget',
-            'type' => 'SelectFromArray',
+        $this->addField('splashTarget', SelectFromArray::class, __('Ouvrir le lien'), [
             'options' => [
                 '_self' => 'Dans la fenêtre courrante',
                 '_blank' => 'Dans un nouvel onglet',
             ],
-            'label' => __('Ouvrir le lien'),
             'default' => '_self',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'splashMinimalTime',
-            'type' => 'Number',
-            'label' => __('Temps minimal d\'affichage'),
+        $this->addField('splashMinimalTime', Number::class, __('Temps minimal d\'affichage'), [
             'default' => 1,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_notes',
-            'type' => 'FormSection',
-            'label' => __('Notes'),
-        ]);
-        $this->addField([
-            'name' => 'notes',
-            'type' => 'Checkbox',
-            'label' => __('Activer les notes'),
+        $this->addField('section_notes', FormSection::class, __('Notes'));
+        $this->addField('notes', Checkbox::class, __('Activer les notes'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_articles',
-            'type' => 'FormSection',
-            'label' => __('Articles'),
-        ]);
-        $this->addField([
-            'name' => 'articlesFile',
-            'type' => 'FilesOrURL',
-            'label' => __('Articles'),
+        $this->addField('section_articles', FormSection::class, __('Articles'));
+        $this->addField('articlesFile', FilesOrURL::class, __('Articles'), [
             'default' => '',
             'accept' => [
                 0 => '*.xml',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'articlesImages',
-            'type' => 'FilesOrURL',
-            'label' => __('Images des articles'),
+        $this->addField('articlesImages', FilesOrURL::class, __('Images des articles'), [
             'hint' => __('Les noms des fichiers doivent être les même que ceux des balises <image> du XML'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'articlesShare',
-            'type' => 'Checkbox',
-            'label' => __('Activer le partage'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('articlesShare', Checkbox::class, __('Activer le partage'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('articlesPrint', Checkbox::class, __('Activer l\'impression'), [
+            'default' => true,
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'articlesStyle',
-            'type' => 'SelectFromArray',
+        $this->addField('', FormSeparator::class);
+        $this->addField('articlesStyle', SelectFromArray::class, __('Style'), [
             'options' => [
                 'default' => 'Défaut',
                 'atlantic' => 'Atlantic',
                 'harmonie-mutuelle' => 'Harmonie Mutuelle',
                 'business-immo' => 'Business Immo',
             ],
-            'label' => __('Style'),
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'articlesFont',
-            'type' => 'SelectFromArray',
+        $this->addField('articlesFont', SelectFromArray::class, __('Police des articles'), [
             'options' => [
                 'OpenSans' => 'Open Sans (défaut)',
                 'Montserrat' => 'Montserrat',
                 'Arial' => 'Arial, Helvetica, sans-serif (police système)',
                 'sans-serif' => 'Police système sans-serif',
             ],
-            'label' => __('Police des articles'),
             'default' => 'OpenSans',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_archives',
-            'type' => 'FormSection',
-            'label' => __('Archives'),
-        ]);
-        $this->addField([
-            'name' => 'externalArchives',
-            'type' => 'FilesOrURL',
-            'label' => __('Archives'),
+        $this->addField('section_archives', FormSection::class, __('Archives'));
+        $this->addField('externalArchives', FilesOrURL::class, __('Archives'), [
             'default' => '',
             'accept' => [
                 0 => '*.jpg',
@@ -2664,84 +1689,40 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'archivesLabel',
-            'type' => 'LongText',
-            'label' => __('Label'),
+        $this->addField('archivesLabel', LongText::class, __('Label'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_form',
-            'type' => 'FormSection',
-            'label' => __('Formulaire'),
-        ]);
-        $this->addField([
-            'name' => 'form',
-            'type' => 'SelectFromArray',
+        $this->addField('section_form', FormSection::class, __('Formulaire'));
+        $this->addField('form', SelectFromArray::class, __('Formulaire'), [
             'options' => [
                 '' => 'Aucun',
                 'bulle' => 'Bulle Groupe',
                 'bourbon' => 'Bourbon / Suggestions',
                 'avery' => 'Avery',
             ],
-            'label' => __('Formulaire'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_privacy',
-            'type' => 'FormSection',
-            'label' => __('Respect de la vie privée'),
-        ]);
-        $this->addField([
-            'name' => 'cookieConsent',
-            'type' => 'Checkbox',
-            'label' => __('Message cookie'),
+        $this->addField('section_privacy', FormSection::class, __('Respect de la vie privée'));
+        $this->addField('cookieConsent', Checkbox::class, __('Message cookie'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'cookieConsentMessage',
-            'type' => 'Textarea',
-            'label' => __('Texte du consentement'),
+        $this->addField('cookieConsentMessage', Textarea::class, __('Texte du consentement'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'cookieConsentAutoclose',
-            'type' => 'Integer',
-            'label' => __('Masquer automatiquement après x secondes'),
+        $this->addField('cookieConsentAutoclose', Integer::class, __('Masquer automatiquement après x secondes'), [
             'default' => 0,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_basket',
-            'type' => 'FormSection',
-            'label' => __('Panier'),
-        ]);
-        $this->addField([
-            'name' => 'basket',
-            'type' => 'Checkbox',
-            'label' => __('Panier activé'),
+        $this->addField('section_basket', FormSection::class, __('Panier'));
+        $this->addField('basket', Checkbox::class, __('Panier activé'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'cartIcon',
-            'type' => 'SelectFromArray',
-            'options' => [
-                'nav-basket' => 'Sac',
-                'nav-cart-caddie' => 'Caddie',
-                'nav-cart-wishlist' => 'Wishlist',
-            ],
-            'label' => __('Icône'),
-            'default' => 'nav-basket',
-            'translatable' => false,
-        ]);
-        $this->addField([
-            'name' => 'basketManager',
-            'type' => 'SelectFromArray',
+        $this->addField('basketManager', SelectFromArray::class, __('Manager de panier'), [
             'options' => [
                 'com.fluidbook.player.basket.BasketManager' => 'Classic',
                 'com.fluidbook.player.basket.custom.grdf.GrdfBasketManager' => 'Grdf',
@@ -2762,14 +1743,29 @@ class FluidbookPublication extends ToolboxModel
                 'GrandPavois' => 'Grand Pavois',
                 'JoueclubWishlist2021' => 'Wishlist Jouéclub Noël 2021',
             ],
-            'label' => __('Manager de panier'),
             'default' => 'classic',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'basketReferences',
-            'type' => 'FilesOrURL',
-            'label' => __('Références produits'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('cartIcon', SelectFromArray::class, __('Icône'), [
+            'options' => [
+                'nav-basket' => 'Sac',
+                'nav-cart-caddie' => 'Caddie',
+                'nav-cart-wishlist' => 'Wishlist',
+            ],
+            'default' => 'nav-basket',
+            'translatable' => false,
+        ]);
+        $this->addField('cartLinkAppearance', SelectFromArray::class, __('Apparence des liens panier'), [
+            'options' => [
+                'link' => 'Lien',
+                'overlay' => 'Boutons + et - avec overlay',
+            ],
+            'default' => 'link',
+            'translatable' => false,
+        ]);
+        $this->addField('', FormSeparator::class);
+        $this->addField('basketReferences', FilesOrURL::class, __('Références produits'), [
             'hint' => __('Fichier contenant les références produits'),
             'default' => '',
             'accept' => [
@@ -2778,556 +1774,354 @@ class FluidbookPublication extends ToolboxModel
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'basketImages',
-            'type' => 'FilesOrURL',
-            'label' => __('Images des produits'),
+        $this->addField('basketImages', FilesOrURL::class, __('Images des produits'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'basketPDFBackground',
-            'type' => 'FilesOrURL',
-            'label' => __('Fond du PDF (bon de commande)'),
-            'hint' => __('Fond du bon de commande'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('cartHeaderImage', FilesOrURL::class, __('Header panier'), [
             'default' => '',
             'accept' => [
-                0 => '*.ai',
-                1 => '*.eps',
+                0 => '*.jpg',
+                1 => '*.jpeg',
+                2 => '*.png',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_offline',
-            'type' => 'FormSection',
-            'label' => __('Version offline'),
+        $this->addField('cartHeaderMobileImage', FilesOrURL::class, __('Header panier (mobile)'), [
+            'default' => '',
+            'accept' => [
+                0 => '*.jpg',
+                1 => '*.jpeg',
+                2 => '*.png',
+            ],
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'offlineTitle',
-            'type' => 'LongText',
-            'label' => __('Titre de l\'application'),
+        $this->addField('cartExtraSettings', Textarea::class, __('Paramètres panier'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'offlineLink',
-            'type' => 'LongText',
-            'label' => __('URL du Fluidbook'),
+        $this->addField('section_offline', FormSection::class, __('Version offline'));
+        $this->addField('offlineTitle', LongText::class, __('Titre de l\'application'), [
+            'default' => '',
+            'translatable' => false,
+        ]);
+        $this->addField('offlineLink', LongText::class, __('URL du Fluidbook'), [
             'hint' => __('URL du fluidbook utilisée pour la version Offline (CD-ROM, clé USB, Exécutables)'),
             'default' => 'http://',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('', FormSeparator::class);
+        $this->addField('offlineWindowsInstallPath', LongText::class, __('Chemin d\'installation par défaut'), [
+            'hint' => __('Par défaut: %LOCALAPPDATA%/%title%'),
+            'default' => '',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'offlineEnableAdvancedPrinting',
-            'type' => 'Checkbox',
-            'label' => __('Activer le menu d\'impression avancée'),
+        $this->addField('offlineWindowsProfilePath', LongText::class, __('Répertoire de stockage du profile'), [
+            'hint' => __('Par défaut: %LOCALAPPDATA%/%title%'),
+            'default' => '',
+            'translatable' => false,
+        ]);
+        $this->addField('', FormSeparator::class);
+        $this->addField('offlineEnableAdvancedPrinting', Checkbox::class, __('Activer le menu d\'impression avancée'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_mobilefirst',
-            'type' => 'FormSection',
-            'label' => __('Mobile first'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('debugConsole', Checkbox::class, __('Activer la console de débuggage'), [
+            'default' => false,
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobilefirstFluidbookId',
-            'type' => 'LongText',
-            'label' => __('Identifiant du fluidbook "Mobile first"'),
+        $this->addField('section_mobilefirst', FormSection::class, __('Mobile first'));
+        $this->addField('mobilefirstFluidbookId', LongText::class, __('Identifiant du fluidbook "Mobile first"'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'mobilefirstBreakpoint',
-            'type' => 'LongText',
-            'label' => __('Breakpoint du passage à la version "Mobile first" (en pixels)'),
+        $this->addField('mobilefirstBreakpoint', LongText::class, __('Breakpoint du passage à la version "Mobile first" (en pixels)'), [
             'default' => '640',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_phonegap',
-            'type' => 'FormSection',
-            'label' => __('Applications mobile'),
-        ]);
-        $this->addField([
-            'name' => 'phonegapId',
-            'type' => 'LongText',
-            'label' => __('Identifiant de l\'identifiant'),
+        $this->addField('section_phonegap', FormSection::class, __('Applications mobile'));
+        $this->addField('phonegapId', LongText::class, __('Identifiant de l\'identifiant'), [
             'hint' => __('De la forme com.fluidbook.phonegap.xxxxx'),
             'default' => 'com.fluidbook.phonegap.$id',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'phonegapVersion',
-            'type' => 'LongText',
-            'label' => __('Version de l\'application'),
+        $this->addField('phonegapVersion', LongText::class, __('Version de l\'application'), [
             'hint' => __('De la forme 1.2.3'),
             'default' => '1.0.0',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'phonegapPlugins',
-            'type' => 'Textarea',
-            'label' => __('Plugins Phonegap'),
+        $this->addField('phonegapPlugins', Textarea::class, __('Plugins Phonegap'), [
             'default' => 'ChildBrowser',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'appScreenshots',
-            'type' => 'Textarea',
-            'label' => __('Générer les screenshots'),
+        $this->addField('appScreenshots', Textarea::class, __('Générer les screenshots'), [
             'hint' => __('Une ligne par vue à générer de la forme X,Y (X : P(ortrait) ou L(andscape), Y : numéro de page ou vue (1, index))'),
             'default' => 'P,0
 L,2
 L,index',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_secure',
-            'type' => 'FormSection',
-            'label' => __('Sécurisation'),
-        ]);
-        $this->addField([
-            'name' => 'secureURL',
-            'type' => 'LongText',
-            'label' => __('URL de sécurisation'),
+        $this->addField('section_secure', FormSection::class, __('Sécurisation'));
+        $this->addField('secureURL', LongText::class, __('URL de sécurisation'), [
             'hint' => __('URL intérrogé pour vérifier si le visiteur à les droits pour consulter la publication'),
             'default' => 'http://',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'secureURLRedirect',
-            'type' => 'LongText',
-            'label' => __('Redirection'),
+        $this->addField('secureURLRedirect', LongText::class, __('Redirection'), [
             'hint' => __('Si l\'authentification échoue, redirection vers cette adresse'),
             'default' => 'http://',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'secureClientSidePassword',
-            'type' => 'FilesOrURL',
-            'label' => __('Sécurisation par mot de passe côté client'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('secureClientSidePassword', FilesOrURL::class, __('Sécurisation par mot de passe côté client'), [
             'default' => '',
             'accept' => [
                 0 => '*.html',
             ],
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'secureClientSidePasswordCredentials',
-            'type' => 'Textarea',
-            'label' => __('Utilisateurs / mots de passe'),
+        $this->addField('secureClientSidePasswordCredentials', Textarea::class, __('Utilisateurs / mots de passe'), [
             'hint' => __('Format user:password par ligne'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'preventRightClick',
-            'type' => 'Checkbox',
-            'label' => __('Essayer d\'empêcher le clic droit'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('preventRightClick', Checkbox::class, __('Essayer d\'empêcher le clic droit'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'restrictPrintDownload',
-            'type' => 'LongText',
-            'label' => __('Paramètre de l\'url permettant de désactiver la restriction (non vide pour activer les restrictions)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('restrictPrintDownload', LongText::class, __('Paramètre de l\'url permettant de désactiver la restriction (non vide pour activer les restrictions)'), [
             'hint' => __('Ne pas indiquer le ?'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'restrictPrint',
-            'type' => 'Checkbox',
-            'label' => __('Restreindre l\'impression'),
+        $this->addField('restrictPrint', Checkbox::class, __('Restreindre l\'impression'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'restrictDownload',
-            'type' => 'Checkbox',
-            'label' => __('Restreindre le téléchargement du pdf'),
+        $this->addField('restrictDownload', Checkbox::class, __('Restreindre le téléchargement du pdf'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'restrictSendBookmark',
-            'type' => 'Checkbox',
-            'label' => __('Restreindre l\'envoi de marques-pages'),
+        $this->addField('restrictSendBookmark', Checkbox::class, __('Restreindre l\'envoi de marques-pages'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_multibrochure',
-            'type' => 'FormSection',
-            'label' => __('Multibrochure'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('recaptcha', LongText::class, __('Activer reCATPCHA v3 (clé du site)'), [
+            'default' => '',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'home',
-            'type' => 'LongText',
-            'label' => __('Accueil de l\'interface multibrochure'),
+        $this->addField('section_multibrochure', FormSection::class, __('Multibrochure'));
+        $this->addField('home', LongText::class, __('Accueil de l\'interface multibrochure'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'country',
-            'type' => 'LongText',
-            'label' => __('Pays de la brochure'),
+        $this->addField('country', LongText::class, __('Pays de la brochure'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'multilangDisplay',
-            'type' => 'SelectFromArray',
+        $this->addField('multilangDisplay', SelectFromArray::class, __('Affichage'), [
             'options' => [
                 'lang' => 'Langue',
                 'lang_country' => 'Langue (Pays)',
                 'country_lang' => 'Pays (Langue)',
             ],
-            'label' => __('Affichage'),
             'default' => 'lang',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'multilang',
-            'type' => 'Textarea',
-            'label' => __('Langues'),
+        $this->addField('multilang', Textarea::class, __('Langues'), [
             'hint' => __('Code langue,Code pays,URL'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_plv',
-            'type' => 'FormSection',
-            'label' => __('Mode PLV'),
-        ]);
-        $this->addField([
-            'name' => 'plv',
-            'type' => 'Checkbox',
-            'label' => __('Activer le mode PLV'),
+        $this->addField('section_plv', FormSection::class, __('Mode PLV'));
+        $this->addField('plv', Checkbox::class, __('Activer le mode PLV'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'plvTimer',
-            'type' => 'Integer',
-            'label' => __('Temps'),
+        $this->addField('plvTimer', Integer::class, __('Temps'), [
             'min' => 1,
             'max' => 60,
             'default' => 5,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'plvMode',
-            'type' => 'SelectFromArray',
+        $this->addField('plvMode', SelectFromArray::class, __('Arrivé à la dernière page'), [
             'options' => [
                 'back' => 'Remonter vers la première page',
                 'first' => 'Recommencer à la première page',
             ],
-            'label' => __('Arrivé à la dernière page'),
             'default' => 'first',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_theme',
-            'type' => 'FormSection',
-            'label' => __('Options du thème'),
-        ]);
-        $this->addField([
-            'name' => 'themeEnableAfterSearch',
-            'type' => 'Checkbox',
-            'label' => __('Afficher l\'image supplémentaire à droite du moteur de recherche'),
+        $this->addField('section_theme', FormSection::class, __('Options du thème'));
+        $this->addField('themeEnableAfterSearch', Checkbox::class, __('Afficher l\'image supplémentaire à droite du moteur de recherche'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_package',
-            'type' => 'FormSection',
-            'label' => __('Option d\'export'),
-        ]);
-        $this->addField([
-            'name' => 'htmlExtension',
-            'type' => 'LongText',
-            'label' => __('Extension des fichiers html'),
+        $this->addField('section_package', FormSection::class, __('Option d\'export'));
+        $this->addField('htmlExtension', LongText::class, __('Extension des fichiers html'), [
             'hint' => __('Ex : php, htm, html, phtml, asp, aspx'),
             'default' => 'html',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'actualHtmlExtension',
-            'type' => 'LongText',
-            'label' => __('Extension des fichiers html réellement appliquée au fluidbook'),
+        $this->addField('actualHtmlExtension', LongText::class, __('Extension des fichiers html réellement appliquée au fluidbook'), [
             'hint' => __('Ex : php, htm, html, phtml, asp'),
             'default' => 'html',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'htmlPrepend',
-            'type' => 'Textarea',
-            'label' => __('Code à insérer en tête des fichiers'),
+        $this->addField('htmlPrepend', Textarea::class, __('Code à insérer en tête des fichiers'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'baseUrl',
-            'type' => 'LongText',
-            'label' => __('Base de l\'url'),
+        $this->addField('baseUrl', LongText::class, __('Base de l\'url'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'forceCompileOnDownload',
-            'type' => 'Checkbox',
-            'label' => __('Forcer la compilation lors du téléchargement'),
+        $this->addField('forceCompileOnDownload', Checkbox::class, __('Forcer la compilation lors du téléchargement'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'embedAllLibraries',
-            'type' => 'Checkbox',
-            'label' => __('Intégrer toutes les bibliothèques JS'),
+        $this->addField('embedAllLibraries', Checkbox::class, __('Intégrer toutes les bibliothèques JS'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_demo',
-            'type' => 'FormSection',
-            'label' => __('Lien de démo'),
-        ]);
-        $this->addField([
-            'name' => 'disableDemo',
-            'type' => 'Checkbox',
-            'label' => __('Désactiver le lien de démo'),
+        $this->addField('section_demo', FormSection::class, __('Lien de démo'));
+        $this->addField('disableDemo', Checkbox::class, __('Désactiver le lien de démo'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'redirectDemo',
-            'type' => 'LongText',
-            'label' => __('Rediriger le lien de démo vers'),
+        $this->addField('redirectDemo', LongText::class, __('Rediriger le lien de démo vers'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_scorm',
-            'type' => 'FormSection',
-            'label' => __('SCORM'),
+        $this->addField('section_gamify', FormSection::class, __('Gamification'));
+        $this->addField('gamify_coins_pages', Textarea::class, __('Attribuer des coins lors de la visite des pages'), [
+            'default' => '',
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_enable',
-            'type' => 'Checkbox',
-            'label' => __('Activer SCORM'),
+        $this->addField('section_scorm', FormSection::class, __('SCORM'));
+        $this->addField('scorm_enable', Checkbox::class, __('Activer SCORM'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_version',
-            'type' => 'SelectFromArray',
+        $this->addField('scorm_version', SelectFromArray::class, __('Version du standard SCORM'), [
             'options' => [
                 '1.2' => 'SCORM 1.2',
                 2004 => 'SCORM 2004 4th edition',
             ],
-            'label' => __('Version du standard SCORM'),
             'default' => '1.2',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_id',
-            'type' => 'LongText',
-            'label' => __('Identifiant SCORM'),
+        $this->addField('scorm_id', LongText::class, __('Identifiant SCORM'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_org',
-            'type' => 'LongText',
-            'label' => __('Organisation SCORM'),
+        $this->addField('scorm_org', LongText::class, __('Organisation SCORM'), [
             'default' => 'ACME-ORG-1350650111249',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_title',
-            'type' => 'LongText',
-            'label' => __('Titre SCORM'),
+        $this->addField('scorm_title', LongText::class, __('Titre SCORM'), [
             'hint' => __('Laisser vide pour utiliser le titre de la publication'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_variables',
-            'type' => 'Textarea',
-            'label' => __('Variables SCORM'),
+        $this->addField('scorm_variables', Textarea::class, __('Variables SCORM'), [
             'hint' => __('Laisser vide pour utiliser le titre de la publication'),
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'scorm_complete_on_exit',
-            'type' => 'Checkbox',
-            'label' => __('Marquer le cours comme "Complete" à la fermeture de la fenêtre'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('scorm_complete_on_exit', Checkbox::class, __('Marquer le cours comme "Complete" à la fermeture de la fenêtre'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_complete_on_last_page',
-            'type' => 'Checkbox',
-            'label' => __('Marquer le cours comme "Complete" lorsque le visiteur atteint la dernière page'),
+        $this->addField('scorm_complete_on_last_page', Checkbox::class, __('Marquer le cours comme "Complete" lorsque le visiteur atteint la dernière page'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
+        $this->addField('scorm_complete_coins', Integer::class, __('Marquer le cours comme "Complete" lorsque le visiteur accumule X coins'), [
+            'default' => 0,
+            'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_pass_on_complete',
-            'type' => 'Checkbox',
-            'label' => __('Marquer le cours comme Pass lorsqu\'il est terminé (SCORM 2004 seulement)'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('scorm_pass_on_complete', Checkbox::class, __('Marquer le cours comme Pass lorsqu\'il est terminé (SCORM 2004 seulement)'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_score100_on_complete',
-            'type' => 'Checkbox',
-            'label' => __('Marquer le cours comme réussi à 100% lorsqu\'il est terminé'),
+        $this->addField('scorm_score100_on_complete', Checkbox::class, __('Marquer le cours comme réussi à 100% lorsqu\'il est terminé'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'scorm_quizdata',
-            'type' => 'FilesOrURL',
-            'label' => __('Données de quiz'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('scorm_quizdata', FilesOrURL::class, __('Données de quiz'), [
             'default' => '',
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_score',
-            'type' => 'Checkbox',
-            'label' => __('Activer le support du score'),
+        $this->addField('scorm_score', Checkbox::class, __('Activer le support du score'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_score_min',
-            'type' => 'Integer',
-            'label' => __('Score minimal pour marquer le contenu comme réussi'),
+        $this->addField('scorm_score_min', Integer::class, __('Score minimal pour marquer le contenu comme réussi'), [
             'min' => 0,
             'max' => 100,
             'default' => 50,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_quiz_as_questionnaire',
-            'type' => 'Checkbox',
-            'label' => __('Traiter les quiz comme des questionnaires (toutes les réponses sont considérées comme correctes)'),
+        $this->addField('scorm_quiz_as_questionnaire', Checkbox::class, __('Traiter les quiz comme des questionnaires (toutes les réponses sont considérées comme correctes)'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'type' => 'FormSeparator',
-        ]);
-        $this->addField([
-            'name' => 'scorm_force_attempts',
-            'type' => 'Checkbox',
-            'label' => __('Forcer la création d\'un "attempt" à chaque ouverture'),
+        $this->addField('', FormSeparator::class);
+        $this->addField('scorm_force_attempts', Checkbox::class, __('Forcer la création d\'un "attempt" à chaque ouverture'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'scorm_commit_immediately',
-            'type' => 'Checkbox',
-            'label' => __('Envoyer les données immédiatement au LMS (Peut provoquer des ralentissement sur certains LMS)'),
+        $this->addField('scorm_commit_immediately', Checkbox::class, __('Envoyer les données immédiatement au LMS (Peut provoquer des ralentissement sur certains LMS)'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'section_downloads',
-            'type' => 'FormSection',
-            'label' => __('Versions disponibles au téléchargement'),
-        ]);
-        $this->addField([
-            'name' => 'download_online',
-            'type' => 'Checkbox',
-            'label' => __('Version online - Version par défaut'),
+        $this->addField('section_downloads', FormSection::class, __('Versions disponibles au téléchargement'));
+        $this->addField('download_online', Checkbox::class, __('Version online - Version par défaut'), [
             'default' => true,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_sharepoint',
-            'type' => 'Checkbox',
-            'label' => __('Version Sharepoint - Version par défaut'),
+        $this->addField('download_sharepoint', Checkbox::class, __('Version Sharepoint - Version par défaut'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_scorm',
-            'type' => 'Checkbox',
-            'label' => __('Version SCORM - Version par défaut'),
+        $this->addField('download_scorm', Checkbox::class, __('Version SCORM - Version par défaut'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_win_inss_html',
-            'type' => 'Checkbox',
-            'label' => __('Version offline - Executable Windows'),
+        $this->addField('download_win_inss_html', Checkbox::class, __('Version offline - Executable Windows'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_win_ins_html',
-            'type' => 'Checkbox',
-            'label' => __('Version offline - Installeur Auto-executable Windows'),
+        $this->addField('download_win_ins_html', Checkbox::class, __('Version offline - Installeur Auto-executable Windows'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_win_exe_html',
-            'type' => 'Checkbox',
-            'label' => __('Version offline - ZIP Windows'),
+        $this->addField('download_win_exe_html', Checkbox::class, __('Version offline - ZIP Windows'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_mac_exe_html',
-            'type' => 'Checkbox',
-            'label' => __('Version offline - Exécutable Mac OS X'),
+        $this->addField('download_mac_exe_html', Checkbox::class, __('Version offline - Exécutable Mac OS X'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_win_cd_html',
-            'type' => 'Checkbox',
-            'label' => __('Version offline - CD-ROM / Clé USB'),
+        $this->addField('download_win_cd_html', Checkbox::class, __('Version offline - CD-ROM / Clé USB'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_win_html',
-            'type' => 'Checkbox',
-            'label' => __('Version offline - HTML (Non adaptée à l\'installation sur un serveur web)'),
+        $this->addField('download_win_html', Checkbox::class, __('Version offline - HTML (Non adaptée à l\'installation sur un serveur web)'), [
             'default' => false,
             'translatable' => false,
         ]);
-        $this->addField([
-            'name' => 'download_precompiled',
-            'type' => 'Checkbox',
-            'label' => __('Version precompilée'),
+        $this->addField('download_precompiled', Checkbox::class, __('Version precompilée'), [
             'default' => false,
             'translatable' => false,
         ]);