diff --git a/Gemfile b/Gemfile
index d1b9cae281ff09f01f04851583b66bad3e3b6274..f88fcfa93a5865b52010414ad2c74f02bdd0906e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -41,12 +41,14 @@ gem 'has_scope', '~> 0.8.0'
 
 # Front
 gem 'jquery-rails'
+gem 'angularjs-rails'
 gem 'sassc-rails'
 gem 'jbuilder'
 gem 'kamifusen'#, path: '../kamifusen'
 gem 'bootstrap'
 gem 'sanitize'
-gem 'summernote-rails', git: 'https://github.com/noesya/summernote-rails.git'
+gem 'summernote-rails', git: 'https://github.com/noesya/summernote-rails.git', branch: 'activestorage'
+# gem 'summernote-rails', path: '../summernote-rails'
 
 group :development, :test do
   gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
diff --git a/Gemfile.lock b/Gemfile.lock
index 93d6602011bd58a9400c9d9defbe4dbc495cf00a..4a64144fe0d2e5ae31354c8c5ee58d758cd916c9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,9 +1,10 @@
 GIT
   remote: https://github.com/noesya/summernote-rails.git
-  revision: 0543165914c4996df00bcd46b77a558819443778
+  revision: 7463656df2b81ff434c8fa8786453b55be129054
+  branch: activestorage
   specs:
-    summernote-rails (0.8.20.0)
-      railties (>= 3.1)
+    summernote-rails (0.8.20.1)
+      rails (>= 6.0)
 
 GIT
   remote: https://github.com/noesya/two_factor_authentication.git
@@ -19,60 +20,60 @@ GIT
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (6.1.4.4)
-      actionpack (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    actioncable (6.1.4.6)
+      actionpack (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailbox (6.1.4.4)
-      actionpack (= 6.1.4.4)
-      activejob (= 6.1.4.4)
-      activerecord (= 6.1.4.4)
-      activestorage (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    actionmailbox (6.1.4.6)
+      actionpack (= 6.1.4.6)
+      activejob (= 6.1.4.6)
+      activerecord (= 6.1.4.6)
+      activestorage (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       mail (>= 2.7.1)
-    actionmailer (6.1.4.4)
-      actionpack (= 6.1.4.4)
-      actionview (= 6.1.4.4)
-      activejob (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    actionmailer (6.1.4.6)
+      actionpack (= 6.1.4.6)
+      actionview (= 6.1.4.6)
+      activejob (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 2.0)
-    actionpack (6.1.4.4)
-      actionview (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    actionpack (6.1.4.6)
+      actionview (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       rack (~> 2.0, >= 2.0.9)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.2.0)
-    actiontext (6.1.4.4)
-      actionpack (= 6.1.4.4)
-      activerecord (= 6.1.4.4)
-      activestorage (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    actiontext (6.1.4.6)
+      actionpack (= 6.1.4.6)
+      activerecord (= 6.1.4.6)
+      activestorage (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       nokogiri (>= 1.8.5)
-    actionview (6.1.4.4)
-      activesupport (= 6.1.4.4)
+    actionview (6.1.4.6)
+      activesupport (= 6.1.4.6)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.1, >= 1.2.0)
-    activejob (6.1.4.4)
-      activesupport (= 6.1.4.4)
+    activejob (6.1.4.6)
+      activesupport (= 6.1.4.6)
       globalid (>= 0.3.6)
-    activemodel (6.1.4.4)
-      activesupport (= 6.1.4.4)
-    activerecord (6.1.4.4)
-      activemodel (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
-    activestorage (6.1.4.4)
-      actionpack (= 6.1.4.4)
-      activejob (= 6.1.4.4)
-      activerecord (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    activemodel (6.1.4.6)
+      activesupport (= 6.1.4.6)
+    activerecord (6.1.4.6)
+      activemodel (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
+    activestorage (6.1.4.6)
+      actionpack (= 6.1.4.6)
+      activejob (= 6.1.4.6)
+      activerecord (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       marcel (~> 1.0.0)
       mini_mime (>= 1.1.0)
-    activesupport (6.1.4.4)
+    activesupport (6.1.4.6)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 1.6, < 2)
       minitest (>= 5.1)
@@ -80,13 +81,14 @@ GEM
       zeitwerk (~> 2.3)
     addressable (2.8.0)
       public_suffix (>= 2.0.2, < 5.0)
+    angularjs-rails (1.8.0)
     annotate (3.2.0)
       activerecord (>= 3.2, < 8.0)
       rake (>= 10.4, < 14.0)
     autoprefixer-rails (10.4.2.0)
       execjs (~> 2)
     aws-eventstream (1.2.0)
-    aws-partitions (1.553.0)
+    aws-partitions (1.554.0)
     aws-sdk-core (3.126.0)
       aws-eventstream (~> 1, >= 1.0.2)
       aws-partitions (~> 1, >= 1.525.0)
@@ -138,7 +140,7 @@ GEM
       countries (~> 4.2)
       sort_alphabetical (~> 1.1)
     crass (1.0.6)
-    curation (1.7)
+    curation (1.8)
       metainspector
       nokogiri
     delayed_job (4.1.10)
@@ -252,7 +254,7 @@ GEM
     listen (3.7.1)
       rb-fsevent (~> 0.10, >= 0.10.3)
       rb-inotify (~> 0.9, >= 0.9.10)
-    loofah (2.13.0)
+    loofah (2.14.0)
       crass (~> 1.0.2)
       nokogiri (>= 1.5.9)
     mail (2.7.1)
@@ -287,10 +289,10 @@ GEM
       faraday (>= 0.9)
       sawyer (~> 0.8.0, >= 0.5.3)
     orm_adapter (0.5.0)
-    pg (1.3.1)
+    pg (1.3.2)
     popper_js (2.9.3)
     public_suffix (4.0.6)
-    puma (5.6.1)
+    puma (5.6.2)
       nio4r (~> 2.0)
     racc (1.6.0)
     rack (2.2.3)
@@ -300,32 +302,32 @@ GEM
       rack
     rack-test (1.1.0)
       rack (>= 1.0, < 3)
-    rails (6.1.4.4)
-      actioncable (= 6.1.4.4)
-      actionmailbox (= 6.1.4.4)
-      actionmailer (= 6.1.4.4)
-      actionpack (= 6.1.4.4)
-      actiontext (= 6.1.4.4)
-      actionview (= 6.1.4.4)
-      activejob (= 6.1.4.4)
-      activemodel (= 6.1.4.4)
-      activerecord (= 6.1.4.4)
-      activestorage (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    rails (6.1.4.6)
+      actioncable (= 6.1.4.6)
+      actionmailbox (= 6.1.4.6)
+      actionmailer (= 6.1.4.6)
+      actionpack (= 6.1.4.6)
+      actiontext (= 6.1.4.6)
+      actionview (= 6.1.4.6)
+      activejob (= 6.1.4.6)
+      activemodel (= 6.1.4.6)
+      activerecord (= 6.1.4.6)
+      activestorage (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       bundler (>= 1.15.0)
-      railties (= 6.1.4.4)
+      railties (= 6.1.4.6)
       sprockets-rails (>= 2.0.0)
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
     rails-html-sanitizer (1.4.2)
       loofah (~> 2.3)
-    rails-i18n (7.0.1)
+    rails-i18n (7.0.2)
       i18n (>= 0.7, < 2)
       railties (>= 6.0.0, < 8)
-    railties (6.1.4.4)
-      actionpack (= 6.1.4.4)
-      activesupport (= 6.1.4.4)
+    railties (6.1.4.6)
+      actionpack (= 6.1.4.6)
+      activesupport (= 6.1.4.6)
       method_source
       rake (>= 0.13)
       thor (~> 1.0)
@@ -334,7 +336,7 @@ GEM
     rb-fsevent (0.11.1)
     rb-inotify (0.10.1)
       ffi (~> 1.0)
-    regexp_parser (2.2.0)
+    regexp_parser (2.2.1)
     responders (3.0.1)
       actionpack (>= 5.0)
       railties (>= 5.0)
@@ -426,6 +428,7 @@ PLATFORMS
   ruby
 
 DEPENDENCIES
+  angularjs-rails
   annotate
   aws-sdk-s3
   bootsnap (>= 1.4.4)
diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js
index 8325a2d7fb557ccbcf2813bec4b23fe348317df0..4811939e52b4f481691d628987ced09673aff732 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin.js
@@ -5,12 +5,15 @@
 //= require notyf/notyf.min
 //= require simple_form_password_with_hints
 //= require simple_form_bs5_file_input
+//= require angular
 //= require cropperjs/dist/cropper
 //= require jquery-cropper/dist/jquery-cropper
 //= require appstack/app
 //= require gdpr/cookie_consent
 //= require trix
 //= require sortablejs/Sortable
+//= require summernote/summernote-lite
+//= require summernote-rails
 //= require slug/slug
 //= require cocoon
 //= require_self
diff --git a/app/assets/javascripts/admin/commons/slug_input.js b/app/assets/javascripts/admin/commons/slug_input.js
index 6c84d800029961677d7cc16763f5244e99e41b80..11284f93348d62263f9954c9520d22ce823513b1 100644
--- a/app/assets/javascripts/admin/commons/slug_input.js
+++ b/app/assets/javascripts/admin/commons/slug_input.js
@@ -1,10 +1,7 @@
-/*global $ */
 window.osuny.slugInput = {
     init: function () {
         'use strict';
-        var sourceInput,
-            slugInput,
-            i;
+        var i;
         this.slugInputs = document.querySelectorAll('.js-slug-input');
 
         if (this.slugInputs.length === 0) {
diff --git a/app/assets/javascripts/admin/plugins/summernote.js b/app/assets/javascripts/admin/plugins/summernote.js
new file mode 100644
index 0000000000000000000000000000000000000000..82025b4763175f8b17cca4c1cd121056595f9f91
--- /dev/null
+++ b/app/assets/javascripts/admin/plugins/summernote.js
@@ -0,0 +1,50 @@
+/*global $, SummernoteAttachmentUpload */
+$(function () {
+    'use strict';
+
+    $.extend($.summernote.lang['en-US'].image, {
+        dragImageHere: 'Drag file here',
+        dropImage: 'Drop file'
+    });
+
+    $('[data-provider="summernote"]').each(function () {
+        $(this).summernote({
+            popover: {
+                image: [
+                    ['remove', ['removeMedia']]
+                ]
+            },
+            toolbar: [
+                ['style', ['style']],
+                ['font', ['bold', 'italic']],
+                ['para', ['ul', 'ol']],
+                ['table', ['table']],
+                ['insert', ['link', 'picture', 'video']],
+                ['view', ['codeview']]
+            ],
+            styleTags: [
+                'p',
+                'blockquote',
+                'pre',
+                'h2',
+                'h3',
+                'h4'
+            ],
+            callbacks: {
+                onImageUpload: function (files) {
+                    var attachmentUpload = new SummernoteAttachmentUpload(this, files[0]);
+                    attachmentUpload.start();
+                },
+                onMediaDelete: function (_, $editable) {
+                    $.summernote.rails.cleanEmptyAttachments($editable);
+                },
+                onKeyup: function (e) {
+                    var $editable = $(e.currentTarget);
+                    if (e.keyCode === 8) {
+                        $.summernote.rails.cleanEmptyAttachments($editable);
+                    }
+                }
+            }
+        });
+    });
+});
diff --git a/app/assets/stylesheets/admin.sass b/app/assets/stylesheets/admin.sass
index bb3070795a9d36bfdd6469f255ae799e6e1c0708..61c00c7594a7737fc23f0626e9a81a04d85e5ad1 100644
--- a/app/assets/stylesheets/admin.sass
+++ b/app/assets/stylesheets/admin.sass
@@ -3,6 +3,7 @@
 @import 'appstack/light'
 @import 'simple_form_password_with_hints'
 @import 'simple_form_bs5_file_input'
+@import 'summernote-lite'
 @import 'cropperjs/dist/cropper'
 @import 'gdpr/cookie_consent'
 @import 'commons/*'
diff --git a/app/assets/stylesheets/admin/preview.sass b/app/assets/stylesheets/admin/preview.sass
new file mode 100644
index 0000000000000000000000000000000000000000..494cf4bde41cf6b51a556452aad621aba6903099
--- /dev/null
+++ b/app/assets/stylesheets/admin/preview.sass
@@ -0,0 +1,4 @@
+.preview
+    img
+        height: auto
+        max-width: 100%
diff --git a/app/assets/stylesheets/admin/treeview.sass b/app/assets/stylesheets/admin/treeview.sass
index 929f7613f8adebb9589e033e63dad2ad5e56da91..b77719ec75f72eac129591189104c62f3e22c9e8 100644
--- a/app/assets/stylesheets/admin/treeview.sass
+++ b/app/assets/stylesheets/admin/treeview.sass
@@ -4,21 +4,25 @@
             display: none
 
         & > .treeview__label
-            & > a .close_btn
+            & > a .close_btn,
+            & > a .close_text
                 display: none
                 .close_btn--with_children
                     display: inline
                 .close_btn--without_children
                     display: none
 
-            & > a .open_btn
+            & > a .open_btn,
+            & > a .open_text
                 display: inline
                 .open_btn--with_children
                     display: inline
                 .open_btn--without_children
                     display: none
 
-            & > .move_btn
+            & > .move_btn,
+            & > a .open_text,
+            & > a .close_text
                 opacity: 0
                 transition: opacity 0.1s
 
@@ -27,9 +31,11 @@
 
         &--opened
             & > .treeview__label
-                & > a .close_btn
+                & > a .close_btn,
+                & > a .close_text
                     display: inline
-                & > a .open_btn
+                & > a .open_btn,
+                & > a .open_text
                     display: none
             & > .treeview__children
                 display: block
@@ -60,5 +66,7 @@
         .treeview__element
             &:hover
                 & > .treeview__label
-                    & > .move_btn
+                    & > .move_btn,
+                    & > a .open_text,
+                    & > a .close_text
                         opacity: 1
diff --git a/app/assets/stylesheets/commons/_summernote.sass b/app/assets/stylesheets/commons/_summernote.sass
new file mode 100644
index 0000000000000000000000000000000000000000..9be47b54ee1b72027294690ece978e2151634130
--- /dev/null
+++ b/app/assets/stylesheets/commons/_summernote.sass
@@ -0,0 +1,10 @@
+.summernote
+    b
+        color: black
+        font-weight: bold
+    .note-btn.dropdown-toggle:after
+        content: none
+    .note-editable
+        img, video
+            max-width: 100%
+            height: auto
diff --git a/app/controllers/admin/communication/website/blocks_controller.rb b/app/controllers/admin/communication/website/blocks_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c87686c55ef5ac0fe0b34f513684e7b114dbe43a
--- /dev/null
+++ b/app/controllers/admin/communication/website/blocks_controller.rb
@@ -0,0 +1,70 @@
+class Admin::Communication::Website::BlocksController < Admin::Communication::Website::ApplicationController
+  load_and_authorize_resource class: Communication::Website::Block, through: :website
+
+  def reorder
+    ids = params[:ids] || []
+    first_page = nil
+    ids.each.with_index do |id, index|
+      block = @website.blocks.find(id)
+      block.update position: index + 1
+    end
+  end
+
+  def show
+    breadcrumb
+  end
+
+  def new
+    @block.about_type = params[:about_type]
+    @block.about_id = params[:about_id]
+    breadcrumb
+  end
+
+  def edit
+    breadcrumb
+  end
+
+  def create
+    @block.university = @website.university
+    @block.website = @website
+    if @block.save
+      redirect_to [:edit, :admin, @block], notice: t('admin.successfully_created_html', model: @block.to_s)
+    else
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def update
+    if @block.update(block_params)
+      @block.about.save_and_sync
+      redirect_to [:admin, @block.about], notice: t('admin.successfully_updated_html', model: @block.to_s)
+    else
+      render :edit, status: :unprocessable_entity
+    end
+  end
+
+  def destroy
+    @about = @block.about
+    @block.destroy
+    redirect_to [:admin, @about], notice: t('admin.successfully_destroyed_html', model: @block.to_s)
+  end
+
+  protected
+
+  def breadcrumb
+    super
+    add_breadcrumb @block.about.model_name.human(count: 2), [:admin, @block.about.class]
+    add_breadcrumb @block.about, [:admin, @block.about]
+    if @block.new_record?
+      add_breadcrumb t('communication.website.block.choose_template')
+    else
+      add_breadcrumb @block
+    end
+  end
+
+
+  def block_params
+    params.require(:communication_website_block)
+          .permit(:about_id, :about_type, :template, :data)
+  end
+end
diff --git a/app/helpers/admin/application_helper.rb b/app/helpers/admin/application_helper.rb
index 7ecd56b565737828bd5ca8676aa3bf4b48c24cd8..802c701136e0f07490f292de0049a3be4fb94750 100644
--- a/app/helpers/admin/application_helper.rb
+++ b/app/helpers/admin/application_helper.rb
@@ -37,6 +37,10 @@ module Admin::ApplicationHelper
             class: button_classes
   end
 
+  def preview_link
+    raw "<button class=\"btn btn-primary\" type=\"button\" data-bs-toggle=\"offcanvas\" data-bs-target=\"#preview\" aria-controls=\"preview\">#{ t 'preview.button'}</button>"
+  end
+
   def button_classes(additional = '', **options)
     classes = "btn btn-primary btn-xs #{additional}"
     classes += ' disabled' if options[:disabled]
diff --git a/app/models/administration/qualiopi/indicator.rb b/app/models/administration/qualiopi/indicator.rb
index c43737ecec0ff0f33f11a12b85d2730fc6652174..8231f9cdebe7ef68ac431bbe809ef6f386098580 100644
--- a/app/models/administration/qualiopi/indicator.rb
+++ b/app/models/administration/qualiopi/indicator.rb
@@ -20,7 +20,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_eed87f7acf  (criterion_id => administration_qualiopi_criterions.id)
+#  fk_rails_31f1a0a2c9  (criterion_id => administration_qualiopi_criterions.id)
 #
 class Administration::Qualiopi::Indicator < ApplicationRecord
   belongs_to :criterion
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index f3abb7a6ead4d460b55ca177650988a8711727c3..1280d26b6f0eba6e2abb37013db16f3ec7af27a0 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -29,7 +29,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_bb6a496c08  (university_id => universities.id)
+#  fk_rails_94b0abd85b  (university_id => universities.id)
 #
 class Communication::Website < ApplicationRecord
   include WithAbouts
diff --git a/app/models/communication/website/block.rb b/app/models/communication/website/block.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d5987f96a32fb3cdbb1dd0fc2b01f890109e2c51
--- /dev/null
+++ b/app/models/communication/website/block.rb
@@ -0,0 +1,71 @@
+# == Schema Information
+#
+# Table name: communication_website_blocks
+#
+#  id                       :uuid             not null, primary key
+#  about_type               :string           indexed => [about_id]
+#  data                     :jsonb
+#  position                 :integer          default(0), not null
+#  template                 :integer          default(NULL), not null
+#  created_at               :datetime         not null
+#  updated_at               :datetime         not null
+#  about_id                 :uuid             indexed => [about_type]
+#  communication_website_id :uuid             not null, indexed
+#  university_id            :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_communication_website_blocks_on_about                     (about_type,about_id)
+#  index_communication_website_blocks_on_communication_website_id  (communication_website_id)
+#  index_communication_website_blocks_on_university_id             (university_id)
+#
+# Foreign Keys
+#
+#  fk_rails_18291ef65f  (university_id => universities.id)
+#  fk_rails_75bd7c8d6c  (communication_website_id => communication_websites.id)
+#
+class Communication::Website::Block < ApplicationRecord
+  include WithPosition
+
+  belongs_to :university
+  belongs_to :website, foreign_key: :communication_website_id
+  belongs_to :about, polymorphic: true
+
+  enum template: {
+    organization_chart: 100,
+    partners: 200
+  }
+
+  def data=(value)
+    value = JSON.parse value if value.is_a? String
+    super(value)
+  end
+
+  def git_dependencies
+    m = "git_dependencies_for_#{template}"
+    respond_to?(m, true) ? send(m) : []
+  end
+
+  def last_ordered_element
+    about.blocks.ordered.last
+  end
+
+  def to_s
+    "Bloc #{position}"
+  end
+
+  protected
+
+  def git_dependencies_for_organization_chart
+    dependencies = []
+    data['elements'].each do |element|
+      element['persons'].each do |person|
+        slug = person['slug']
+        next if slug.blank?
+        person = university.people.find_by slug: slug
+        dependencies << person unless person.nil?
+      end
+    end
+    dependencies.uniq
+  end
+end
diff --git a/app/models/communication/website/home.rb b/app/models/communication/website/home.rb
index 00353bdc29900672e5fe998248be50318b553a78..3b55fc80c9ff3594106df7e9f763d1f82de5ef9c 100644
--- a/app/models/communication/website/home.rb
+++ b/app/models/communication/website/home.rb
@@ -6,7 +6,7 @@
 #  description              :text
 #  featured_image_alt       :string
 #  github_path              :text
-#  text_new                 :text
+#  text                     :text
 #  created_at               :datetime         not null
 #  updated_at               :datetime         not null
 #  communication_website_id :uuid             not null, indexed
@@ -30,7 +30,7 @@ class Communication::Website::Home < ApplicationRecord
   belongs_to :university
   belongs_to :website, foreign_key: :communication_website_id
 
-  has_rich_text :text
+  has_summernote :text
 
   def to_s
     website.to_s
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index c72e01cc657d6382c1048e1f9ce4e13592462362..9ad8b4439f2c42afef03bae5cae9aca798c8efab 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -12,7 +12,7 @@
 #  position                 :integer          default(0), not null
 #  published                :boolean          default(FALSE)
 #  slug                     :string
-#  text_new                 :text
+#  text                     :text
 #  title                    :string
 #  created_at               :datetime         not null
 #  updated_at               :datetime         not null
@@ -46,8 +46,9 @@ class Communication::Website::Page < ApplicationRecord
   include WithSlug # We override slug_unavailable? method
   include WithTree
   include WithPosition
+  include WithBlocks
 
-  has_rich_text :text
+  has_summernote :text
 
   belongs_to :university
   belongs_to :website,
@@ -77,7 +78,7 @@ class Communication::Website::Page < ApplicationRecord
   end
 
   def git_dependencies(website)
-    [self] + descendents + active_storage_blobs + siblings
+    [self] + descendents + active_storage_blobs + siblings + git_block_dependencies
   end
 
   def git_destroy_dependencies(website)
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index a8fd08a0d39bada8e8139522c726a60f7af1376e..21ab6e532c964bcbdce31606436b1f8a32fd2b11 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -11,7 +11,7 @@
 #  published                :boolean          default(FALSE)
 #  published_at             :datetime
 #  slug                     :text
-#  text_new                 :text
+#  text                     :text
 #  title                    :string
 #  created_at               :datetime         not null
 #  updated_at               :datetime         not null
@@ -38,7 +38,7 @@ class Communication::Website::Post < ApplicationRecord
   include WithMenuItemTarget
   include WithSlug # We override slug_unavailable? method
 
-  has_rich_text :text
+  has_summernote :text
 
   has_one :imported_post,
           class_name: 'Communication::Website::Imported::Post',
@@ -64,6 +64,7 @@ class Communication::Website::Post < ApplicationRecord
   scope :ordered, -> { order(published_at: :desc, created_at: :desc) }
   scope :recent, -> { order(published_at: :desc).limit(5) }
 
+
   def path
     # used in menu_item#static_target
     "/#{published_at.strftime "%Y/%m/%d"}/#{slug}"
diff --git a/app/models/communication/website/with_abouts.rb b/app/models/communication/website/with_abouts.rb
index 83916b81544fc65b6e2c256bc20e4053ddcff20e..556203472bbeb2e397d3a92968723b2ac9c96f72 100644
--- a/app/models/communication/website/with_abouts.rb
+++ b/app/models/communication/website/with_abouts.rb
@@ -26,6 +26,10 @@ module Communication::Website::WithAbouts
                 foreign_key: :communication_website_id,
                 dependent: :destroy
 
+    has_many    :blocks,
+                foreign_key: :communication_website_id,
+                dependent: :destroy
+
     def self.about_types
       [
         nil,
diff --git a/app/models/concerns/with_blobs.rb b/app/models/concerns/with_blobs.rb
index 8a0cd6874e20212d011cd3f4e821db064e5214f3..27a729abf2ae36972f22040537d611906c4e7a16 100644
--- a/app/models/concerns/with_blobs.rb
+++ b/app/models/concerns/with_blobs.rb
@@ -13,20 +13,25 @@ module WithBlobs
     blobs_with_ids inherited_blob_ids
   end
 
+  def summernote_embeds
+    summernote_embeds_reflection_names.map { |summernote_reflection_name|
+      public_send(summernote_reflection_name)
+    }.flatten
+  end
+
   protected
 
   def explicit_blob_ids
-    [rich_text_blob_ids]
+    [summernote_blob_ids]
   end
 
   def inherited_blob_ids
     []
   end
 
-  def rich_text_blob_ids
-    rich_text_reflection_names.map { |rich_text_reflection_name|
-      rich_text = public_send(rich_text_reflection_name)
-      rich_text.present? ? rich_text.embeds.blobs.pluck(:id) : []
+  def summernote_blob_ids
+    summernote_embeds_reflection_names.map { |summernote_reflection_name|
+      public_send(summernote_reflection_name).pluck(:blob_id)
     }.flatten
   end
 
@@ -34,7 +39,7 @@ module WithBlobs
     university.active_storage_blobs.where(id: ids.flatten.compact)
   end
 
-  def rich_text_reflection_names
-    @rich_text_reflection_names ||= _reflections.select { |name, reflection| reflection.class_name == "ActionText::RichText" }.keys
+  def summernote_embeds_reflection_names
+    @summernote_embeds_reflection_names ||= _reflections.keys.select { |name| name.ends_with?('_summernote_embeds_attachments') }
   end
 end
diff --git a/app/models/concerns/with_blocks.rb b/app/models/concerns/with_blocks.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3c27dc981b0e94e75091e773749c485ae44db4fd
--- /dev/null
+++ b/app/models/concerns/with_blocks.rb
@@ -0,0 +1,11 @@
+module WithBlocks
+  extend ActiveSupport::Concern
+
+  included do
+    has_many :blocks, as: :about
+  end
+
+  def git_block_dependencies
+    blocks.collect &:git_dependencies
+  end
+end
diff --git a/app/models/concerns/with_inheritance.rb b/app/models/concerns/with_inheritance.rb
index 7257f9c53b9d8fd5783d9475264c5034df5d8805..7f7dd625cd2ebe8d9f2f7e7500242fce0f72b047 100644
--- a/app/models/concerns/with_inheritance.rb
+++ b/app/models/concerns/with_inheritance.rb
@@ -4,13 +4,17 @@ module WithInheritance
   included do
     def self.rich_text_areas_with_inheritance(*properties)
       properties.each do |property|
-        has_rich_text property
-        define_method :"best_#{property}" do
-          best(property)
-        end
-        define_method :"best_#{property}_source" do
-          best_source(property)
-        end
+        has_summernote property
+
+        class_eval <<-CODE, __FILE__, __LINE__ + 1
+          def best_#{property}
+            best("#{property}")
+          end
+
+          def best_#{property}_source
+            best_source("#{property}")
+          end
+        CODE
       end
     end
   end
@@ -22,9 +26,9 @@ module WithInheritance
     value.blank? ? parent&.send("best_#{property}") : value
   end
 
-  def best_source(property)
+  def best_source(property, is_ancestor: false)
     value = send(property)
-    return nil if !value.blank? # There is a value, no inheritance needed
-    best(property)&.record
+    return (is_ancestor ? self : nil) if value.present?
+    parent&.send(:best_source, property, is_ancestor: true)
   end
 end
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index 9abd988e96d3f1c9c75cb32f48b67e4630aa1557..cec653a4a5952ba56db12f73f460b52a52e3a8b6 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -3,29 +3,29 @@
 # Table name: education_programs
 #
 #  id                 :uuid             not null, primary key
-#  accessibility_new  :text
+#  accessibility      :text
 #  capacity           :integer
-#  contacts_new       :text
-#  content_new        :text
+#  contacts           :text
+#  content            :text
 #  continuing         :boolean
 #  description        :text
-#  duration_new       :text
+#  duration           :text
 #  ects               :integer
-#  evaluation_new     :text
+#  evaluation         :text
 #  featured_image_alt :string
 #  level              :integer
 #  name               :string
-#  objectives_new     :text
-#  opportunities_new  :text
-#  other_new          :text
+#  objectives         :text
+#  opportunities      :text
+#  other              :text
 #  path               :string
-#  pedagogy_new       :text
+#  pedagogy           :text
 #  position           :integer          default(0)
-#  prerequisites_new  :text
-#  pricing_new        :text
+#  prerequisites      :text
+#  pricing            :text
 #  published          :boolean          default(FALSE)
-#  registration_new   :text
-#  results_new        :text
+#  registration       :text
+#  results            :text
 #  slug               :string
 #  created_at         :datetime         not null
 #  updated_at         :datetime         not null
@@ -39,7 +39,7 @@
 #
 # Foreign Keys
 #
-#  fk_rails_08b351087c  (university_id => universities.id)
+#  fk_rails_6e16107511  (university_id => universities.id)
 #  fk_rails_ec1f16f607  (parent_id => education_programs.id)
 #
 class Education::Program < ApplicationRecord
diff --git a/app/models/research/journal/article.rb b/app/models/research/journal/article.rb
index 3ff64d1093a41146aa9c9ee78e2b7fc03833624f..18e2717aebcda7a9b9bd8f3a5dcf3c5aa3d8fc76 100644
--- a/app/models/research/journal/article.rb
+++ b/app/models/research/journal/article.rb
@@ -10,7 +10,7 @@
 #  published_at               :datetime
 #  references                 :text
 #  slug                       :string
-#  text_new                   :text
+#  text                       :text
 #  title                      :string
 #  created_at                 :datetime         not null
 #  updated_at                 :datetime         not null
@@ -38,7 +38,7 @@ class Research::Journal::Article < ApplicationRecord
   include WithBlobs
   include WithPosition
 
-  has_rich_text :text
+  has_summernote :text
   has_one_attached :pdf
 
   belongs_to :university
diff --git a/app/models/research/laboratory/axis.rb b/app/models/research/laboratory/axis.rb
index 5556990de730a60877322bdc79974b3085253335..11e2f3d15423984867cb20a04840df99da6014b4 100644
--- a/app/models/research/laboratory/axis.rb
+++ b/app/models/research/laboratory/axis.rb
@@ -7,7 +7,7 @@
 #  name                   :string
 #  position               :integer
 #  short_name             :string
-#  text_new               :text
+#  text                   :text
 #  created_at             :datetime         not null
 #  updated_at             :datetime         not null
 #  research_laboratory_id :uuid             not null, indexed
@@ -26,7 +26,7 @@
 class Research::Laboratory::Axis < ApplicationRecord
   include WithPosition
 
-  has_rich_text :text
+  has_summernote :text
 
   belongs_to :university
   belongs_to :laboratory, foreign_key: :research_laboratory_id
diff --git a/app/models/university/person.rb b/app/models/university/person.rb
index 8f25ccd6d549213397050f95e310eb72ee3221ca..49718973f6abed6db2b9bf4b1e863f47a5e4bb4b 100644
--- a/app/models/university/person.rb
+++ b/app/models/university/person.rb
@@ -3,7 +3,7 @@
 # Table name: university_people
 #
 #  id                :uuid             not null, primary key
-#  biography_new     :text
+#  biography         :text
 #  description       :text
 #  email             :string
 #  first_name        :string
@@ -37,7 +37,7 @@ class University::Person < ApplicationRecord
   include WithPicture
   include WithEducation
 
-  has_rich_text :biography
+  has_summernote :biography
 
   belongs_to :university
   belongs_to :user, optional: true
@@ -141,7 +141,14 @@ class University::Person < ApplicationRecord
     @teacher ||= University::Person::Teacher.find(id)
   end
 
+  def in_block_dependencies?(website)
+    website.blocks.find_each do |block|
+      return true if in? block.git_dependencies
+    end
+  end
+
   def for_website?(website)
+    in_block_dependencies?(website) ||
     administrator.for_website?(website) ||
     author.for_website?(website) ||
     researcher.for_website?(website) ||
@@ -159,6 +166,6 @@ class University::Person < ApplicationRecord
   end
 
   def sanitize_email
-    self.email = self.email.downcase.strip
+    self.email = self.email.to_s.downcase.strip
   end
 end
diff --git a/app/models/university/person/administrator.rb b/app/models/university/person/administrator.rb
index 45c0cf4c7c389a6029fadf3018d75465cccc01b2..b7bca44426417b0705317eb94dbdb4af47d11eeb 100644
--- a/app/models/university/person/administrator.rb
+++ b/app/models/university/person/administrator.rb
@@ -3,7 +3,7 @@
 # Table name: university_people
 #
 #  id                :uuid             not null, primary key
-#  biography_new     :text
+#  biography         :text
 #  description       :text
 #  email             :string
 #  first_name        :string
diff --git a/app/models/university/person/author.rb b/app/models/university/person/author.rb
index 1bb44c1eb9111e6857654761c402c169e7b2db21..5bf2ee2c4a68b86044a237691a08fd9b4391e150 100644
--- a/app/models/university/person/author.rb
+++ b/app/models/university/person/author.rb
@@ -3,7 +3,7 @@
 # Table name: university_people
 #
 #  id                :uuid             not null, primary key
-#  biography_new     :text
+#  biography         :text
 #  description       :text
 #  email             :string
 #  first_name        :string
diff --git a/app/models/university/person/researcher.rb b/app/models/university/person/researcher.rb
index 207a0919a838b9554625946d10b22f74952b33e1..9ca52242568e5da3fee487a5a4868d3bb28aaa88 100644
--- a/app/models/university/person/researcher.rb
+++ b/app/models/university/person/researcher.rb
@@ -3,7 +3,7 @@
 # Table name: university_people
 #
 #  id                :uuid             not null, primary key
-#  biography_new     :text
+#  biography         :text
 #  description       :text
 #  email             :string
 #  first_name        :string
diff --git a/app/models/university/person/teacher.rb b/app/models/university/person/teacher.rb
index 18518ba9231e6231cbe06d3b9aa4b3b96f6cce7d..2f75bd1ab96b16846fa83af4670c2724d9d116e4 100644
--- a/app/models/university/person/teacher.rb
+++ b/app/models/university/person/teacher.rb
@@ -3,7 +3,7 @@
 # Table name: university_people
 #
 #  id                :uuid             not null, primary key
-#  biography_new     :text
+#  biography         :text
 #  description       :text
 #  email             :string
 #  first_name        :string
diff --git a/app/views/active_storage/blobs/_blob.html.erb b/app/views/active_storage/blobs/_blob.html.erb
index 71830569ac0266c0cbcc2fde11db14334319771c..e823ece4caee828b2e1677c38b1cca44cb4fbbe2 100644
--- a/app/views/active_storage/blobs/_blob.html.erb
+++ b/app/views/active_storage/blobs/_blob.html.erb
@@ -2,7 +2,7 @@
   <% if blob.image? %>
     <%= kamifusen_tag blob, width: 800 %>
   <% elsif blob.video? %>
-    <video>
+    <video controls>
       <source src="<%= rails_blob_path(blob) %>" type="<%= blob.content_type %>">
     </video>
   <% else %>
diff --git a/app/views/admin/administration/qualiopi/evaluations/_list.html.erb b/app/views/admin/administration/qualiopi/evaluations/_list.html.erb
index f388a90fa19af1f56b7b5e29dc3c183795da08da..c0651e4e222cb870d82ffb41c8f9c9748b106c6b 100644
--- a/app/views/admin/administration/qualiopi/evaluations/_list.html.erb
+++ b/app/views/admin/administration/qualiopi/evaluations/_list.html.erb
@@ -22,13 +22,13 @@
         </td>
         <% checks.each do |check| %>
           <% valid = !program.public_send("best_#{check}").blank? %>
-          <th>
+          <td>
             <% if valid %>
               <span class="fas fa-check text-success"></span>
             <% else %>
               <span class="fas fa-times text-danger"></span>
             <% end %>
-          </th>
+          </td>
         <% end %>
       </tr>
     <% end %>
diff --git a/app/views/admin/application/_preview.html.erb b/app/views/admin/application/_preview.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..12ee4fca52f1461e4f750b2c9792a560073bbce9
--- /dev/null
+++ b/app/views/admin/application/_preview.html.erb
@@ -0,0 +1,9 @@
+<div class="offcanvas offcanvas-start preview" tabindex="-1" id="preview" aria-labelledby="offcanvasRightLabel" aria-modal="true" role="dialog">
+  <div class="offcanvas-header">
+    <h5 id="offcanvasRightLabel"><%= t 'preview.title' %></h5>
+    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+  </div>
+  <div class="offcanvas-body">
+    <%= yield :preview %>
+  </div>
+</div>
diff --git a/app/views/admin/application/property/_summernote_embeds.html.erb b/app/views/admin/application/property/_summernote_embeds.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..4953d5ce5680f6984f8ce54d898b9e854b5ac8e3
--- /dev/null
+++ b/app/views/admin/application/property/_summernote_embeds.html.erb
@@ -0,0 +1,27 @@
+<h3 class="h5"><%= object.class.human_attribute_name(property) %></h3>
+<% if object.summernote_embeds.any? %>
+  <% object.summernote_embeds.each do |embed| %>
+    <div class="row mb-3">
+      <div class="col-md-2">
+        <div class="img-thumbnail text-center">
+          <% if embed.variable? %>
+            <%= kamifusen_tag embed, class: 'img-fluid' %>
+          <% else %>
+            <i class="fas fa-file p-3 fa-2x"></i>
+          <% end %>
+        </div>
+      </div>
+      <div class="col-md-10">
+        <p class="mb-1">
+          <%= embed.filename %>
+          <%= number_to_human_size embed.metadata['filesize'] %>
+        </p>
+        <%= link_to t('download'),
+                    embed.blob.url(disposition: 'attachment', filename: embed.filename),
+                    class: 'btn btn-xs btn-light' %>
+      </div>
+    </div>
+  <% end %>
+<% else %>
+  <p>0</p>
+<% end %>
diff --git a/app/views/admin/application/property/_text.html.erb b/app/views/admin/application/property/_text.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..0fd8acc44e27911923090811aba761d992ce50c5
--- /dev/null
+++ b/app/views/admin/application/property/_text.html.erb
@@ -0,0 +1,23 @@
+<%
+value = object.send(property).to_s
+if object.respond_to? "best_#{property}"
+  value = object.public_send("best_#{property}").to_s
+  source = object.public_send("best_#{property}_source")
+end
+%>
+<h3 class="h5">
+  <%= object.class.human_attribute_name(property) %>
+  <% if source %>
+    <span class="small text-muted">
+      <%= t 'admin.inheritance.sentence_html',
+            link: link_to(source, [:admin, source]) %>
+    </span>
+  <% end %>
+</h3>
+<p>
+  <% if value.blank? %>
+    <i class="fa fa-exclamation-circle text-danger"></i>
+  <% else %>
+    <%= strip_tags(value).truncate(200).html_safe %>
+  <% end %>
+</p>
diff --git a/app/views/admin/communication/website/blocks/_list.html.erb b/app/views/admin/communication/website/blocks/_list.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..e215b67157d89447740fae3b0cab2d657bb63439
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/_list.html.erb
@@ -0,0 +1,35 @@
+<div class="card flex-fill w-100">
+  <div class="card-header">
+    <div class="float-end">
+      <%= link_to t('add'),
+                  new_admin_communication_website_block_path(about_id: about.id, about_type: about.class.name),
+                  class: button_classes %>
+    </div>
+    <h2 class="card-title mb-0 h5">
+      <%= Communication::Website::Block.model_name.human(count: 2) %>
+    </h2>
+  </div>
+    <table class="<%= table_classes %>">
+      <thead>
+        <tr>
+          <th width="20" class="ps-0">&nbsp;</th>
+          <th><%= Communication::Website::Block.human_attribute_name('name') %></th>
+          <th><%= Communication::Website::Block.human_attribute_name('template') %></th>
+          <th></th>
+        </tr>
+      </thead>
+      <tbody data-sortable data-sort-url="<%= reorder_admin_communication_website_blocks_path %>">
+        <% about.blocks.ordered.each do |block| %>
+          <tr data-id="<%= block.id %>">
+            <td><i class="fa fa-bars handle"></i></td>
+            <td><%= link_to block, admin_communication_website_block_path(block) %></td>
+            <td><%= block.template_i18n  %></td>
+            <td class="text-end">
+              <%= edit_link block %>
+              <%= destroy_link block %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+</div>
diff --git a/app/views/admin/communication/website/blocks/_static.html.erb b/app/views/admin/communication/website/blocks/_static.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..2b5dbed63c6d3d0f53312df54e68bcdd3fdcccb4
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/_static.html.erb
@@ -0,0 +1,7 @@
+<% if about.blocks.any? %>
+blocks:
+<% about.blocks.each do |block| %>
+  - template: <%= block.template %>
+    data:
+<%= render "admin/communication/website/blocks/templates/#{block.template}/static", block: block if block.data %><% end %>
+<% end %>
diff --git a/app/views/admin/communication/website/blocks/edit.html.erb b/app/views/admin/communication/website/blocks/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..0760375b3d46559d43d8c85ab571233b749d9500
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/edit.html.erb
@@ -0,0 +1,14 @@
+<% content_for :title, @block %>
+<%
+@block.data = {} if @block.data.nil? || @block.data.blank?
+@block.data['elements'] ||= []
+%>
+<div ng-app ng-init="data = <%= @block.data.is_a?(String) ? @block.data : @block.data.to_json %>">
+  <%= simple_form_for [:admin, @block] do |f| %>
+    <%= render "admin/communication/website/blocks/templates/#{@block.template}/edit", f: f %>
+    <textarea name="communication_website_block[data]" rows="20" cols="200" class="d-none">{{ data | json}}</textarea>
+    <% content_for :action_bar_right do %>
+      <%= submit f %>
+    <% end %>
+  <% end %>
+</div>
diff --git a/app/views/admin/communication/website/blocks/new.html.erb b/app/views/admin/communication/website/blocks/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..82d23c0ee9c077a843848653065766ddc3e65152
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/new.html.erb
@@ -0,0 +1,20 @@
+<% content_for :title, t('communication.website.block.choose_template') %>
+
+<div class="row">
+  <% Communication::Website::Block.templates.keys.each do |template| %>
+    <% @block.template = template %>
+    <div class="col-lg-3 col-md-4">
+      <div class="card">
+        <div class="card-body">
+          <h5 class="card-title"><%= t "enums.communication.website.block.template.#{template}" %></h5>
+          <%= simple_form_for [:admin, @block] do |f| %>
+            <%= f.input :about_type, as: :hidden %>
+            <%= f.input :about_id, as: :hidden %>
+            <%= f.input :template, as: :hidden %>
+            <%= f.submit t('communication.website.block.choose'), class: button_classes %>
+          <% end %>
+        </div>
+      </div>
+    </div>
+  <% end %>
+</div>
diff --git a/app/views/admin/communication/website/blocks/show.html.erb b/app/views/admin/communication/website/blocks/show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..abb88f0df4d096f307b3890a81dfbbc466b084ba
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/show.html.erb
@@ -0,0 +1,7 @@
+<% content_for :title, @block %>
+
+<%= render "admin/communication/website/blocks/templates/#{@block.template}/show" %>
+
+<% content_for :action_bar_right do %>
+  <%= edit_link @block %>
+<% end %>
diff --git a/app/views/admin/communication/website/blocks/templates/organization_chart/_edit.html.erb b/app/views/admin/communication/website/blocks/templates/organization_chart/_edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..6e715eeb2351044d1496a6841ce6c319b374d1ea
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/templates/organization_chart/_edit.html.erb
@@ -0,0 +1,44 @@
+<a class="<%= button_classes('mb-2') %>" ng-click="data.elements.push({title: 'Role name', persons: []})">Add role</a>
+<div class="card" ng-repeat="element in data.elements">
+  <div class="card-body">
+    <div class="row">
+      <div class="col-md-4">
+        <div class="row">
+          <div class="col-md-11">
+            <input class="form-control" type="text" ng-model="element.title">
+          </div>
+          <div class="col-md-1 text-end">
+            <a class="btn btn-sm btn-danger mt-1" ng-click="data.elements.splice(data.elements.indexOf(element))"><i class="fas fa-trash"></i></a>
+          </div>
+        </div>
+      </div>
+      <div class="offset-md-1 col-md-7">
+        <div class="row">
+          <div class="col-md-8">
+            <p>People</p>
+          </div>
+          <div class="col-md-4 text-end">
+            <a class="<%= button_classes %>" ng-click="element.persons.push({slug: ''})">Add person</a>
+          </div>
+        </div>
+        <div ng-repeat="person in element.persons" class="mb-2">
+          <div class="row">
+            <div class="col-md-5">
+              <select class="form-select select" ng-model="person.slug">
+                <% @website.university.people.ordered.each_with_index do |person, index| %>
+                <option value="<%= person.slug %>"><%= person %></option>
+                <% end %>
+              </select>
+            </div>
+            <div class="col-md-6">
+              <input class="form-control" type="text" ng-model="person.role" placeholder="Type role here">
+            </div>
+            <div class="col-md-1 text-end">
+              <a class="btn btn-sm btn-danger mt-1" ng-click="element.persons.splice(element.persons.indexOf(person))"><i class="fas fa-trash"></i></a>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/app/views/admin/communication/website/blocks/templates/organization_chart/_show.html.erb b/app/views/admin/communication/website/blocks/templates/organization_chart/_show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..d099275bfaaad537b0fa5868619a632d445475d1
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/templates/organization_chart/_show.html.erb
@@ -0,0 +1,19 @@
+<% @block.data['elements'].each do |element| %>
+  <h2><%= element['title'] %></h2>
+  <div class="row">
+    <% element['persons'].each do |person| %>
+      <%
+      p = current_university.people.find_by slug: person['slug']
+      next if p.nil?
+      %>
+      <div class="col-md-3">
+        <article class="card">
+          <div class="card-body">
+            <h3 class="card-title h5"><%= link_to p, [:admin, p] %></h3>
+            <p class="mb-0"><%= person['role'] %></p>
+          </div>
+        </article>
+      </div>
+    <% end %>
+  </div>
+<% end %>
diff --git a/app/views/admin/communication/website/blocks/templates/organization_chart/_static.html.erb b/app/views/admin/communication/website/blocks/templates/organization_chart/_static.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..3aa0a781d35a1bedf0bc1bd3ca8e22acc6c3ab60
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/templates/organization_chart/_static.html.erb
@@ -0,0 +1,12 @@
+<% if !block.data.nil? && !block.data.is_a?(String) && block.data.has_key?('elements') %>
+<% block.data['elements'].each do |element| %>
+      - title: >
+          <%= element['title'] %>
+        persons:
+<% element['persons'].each do |person| %>
+          - slug: "<%= person['slug'] %>"
+            role: >
+              <%= person['role'] %>
+<% end %>
+<% end %>
+<% end %>
diff --git a/test/integration/.keep b/app/views/admin/communication/website/blocks/templates/partners/_edit.html.erb
similarity index 100%
rename from test/integration/.keep
rename to app/views/admin/communication/website/blocks/templates/partners/_edit.html.erb
diff --git a/app/views/admin/communication/website/blocks/templates/partners/_show.html.erb b/app/views/admin/communication/website/blocks/templates/partners/_show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/app/views/admin/communication/website/blocks/templates/partners/_static.html.erb b/app/views/admin/communication/website/blocks/templates/partners/_static.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..ac50540f4f24e523b48f4fd7655ca045aeb29a84
--- /dev/null
+++ b/app/views/admin/communication/website/blocks/templates/partners/_static.html.erb
@@ -0,0 +1,3 @@
+      - name: Partner 1
+        url: https://partner1.com
+        logo: "e09f3794-44e5-4b51-be02-0e384616e791"
diff --git a/app/views/admin/communication/website/categories/_treebranch.html.erb b/app/views/admin/communication/website/categories/_treebranch.html.erb
index 1caf23cbd3edb56cef0506882e6dec71e831df0b..04fcbc2b2392c4d3f2b893f0975ce92362cff8a4 100644
--- a/app/views/admin/communication/website/categories/_treebranch.html.erb
+++ b/app/views/admin/communication/website/categories/_treebranch.html.erb
@@ -14,6 +14,11 @@
       <% end %>
       <%= link_to category, admin_communication_website_category_path(website_id: category.website.id, id: category.id) %>
       <span class="move_btn py-2 ps-2"><i class="fas fa-sort"></i></span>
+      <%= link_to children_admin_communication_website_category_path(website_id: category.website.id, id: category.id),
+                  class: 'js-treeview-openzone small ps-2', remote: true do %>
+        <span class="open_text"><%= t 'folder.open' %></span>
+        <span class="close_text"><%= t 'folder.close' %></span>
+      <% end %>
       <div class="btn-group ms-auto" role="group">
         <%= edit_link category %>
         <%= destroy_link category %>
@@ -22,7 +27,7 @@
     <ul class="list-unstyled treeview__children js-treeview-children js-treeview-sortable-container ms-4" data-id="<%= category.id %>">
       <li class="treeview__empty">
         <div class="d-flex align-items-center treeview__label border-bottom p-1">
-          <span class="p-2 ps-0"><%= t('empty_folder') %></span>
+          <span class="p-2 ps-0"><%= t('folder.empty') %></span>
         </div>
       </li>
       <li class="treeview__loading border-bottom p-1"><%= t('loading') %></li>
diff --git a/app/views/admin/communication/website/homes/edit.html.erb b/app/views/admin/communication/website/homes/edit.html.erb
index ca117a77ceb0e53e27cad5d07d7341cbf1a1118c..5f6ed054c1e30e6f8fe53b2c47c0be9cdd03fe0a 100644
--- a/app/views/admin/communication/website/homes/edit.html.erb
+++ b/app/views/admin/communication/website/homes/edit.html.erb
@@ -10,7 +10,7 @@
           </div>
           <div class="card-body">
             <%= f.input :description %>
-            <%= f.input :text, as: :rich_text_area %>
+            <%= f.input :text, as: :summernote %>
           </div>
         </div>
       </div>
diff --git a/app/views/admin/communication/website/menu/items/_treebranch.html.erb b/app/views/admin/communication/website/menu/items/_treebranch.html.erb
index 841ea52d063e69c9f50bb1a52b8a39131efee7b8..d986dfb7a333b424c8712302e56161777edff9a0 100644
--- a/app/views/admin/communication/website/menu/items/_treebranch.html.erb
+++ b/app/views/admin/communication/website/menu/items/_treebranch.html.erb
@@ -15,6 +15,11 @@
       <% end %>
       <%= link_to_if can?(:read, item), item, admin_communication_website_menu_item_path(website_id: item.website.id, menu_id: item.menu.id, id: item.id) %>
       <span class="move_btn py-2 ps-2"><i class="fas fa-sort"></i></span>
+      <%= link_to children_admin_communication_website_menu_item_path(website_id: item.website.id, menu_id: item.menu.id, id: item.id),
+                  class: 'js-treeview-openzone small ps-2', remote: true do %>
+        <span class="open_text"><%= t 'folder.open' %></span>
+        <span class="close_text"><%= t 'folder.close' %></span>
+      <% end %>
       <div class="btn-group ms-auto" role="group">
         <%= link_to t('edit'),
                     edit_admin_communication_website_menu_item_path(website_id: item.website.id, menu_id: item.menu.id, id: item.id),
@@ -29,7 +34,7 @@
     <ul class="list-unstyled treeview__children js-treeview-children <%= 'js-treeview-sortable-container' if can?(:reorder, item) %> ms-4" data-id="<%= item.id %>">
       <li class="treeview__empty">
         <div class="d-flex align-items-center treeview__label border-bottom p-1">
-          <span class="p-2 ps-0"><%= t('empty_folder') %></span>
+          <span class="p-2 ps-0"><%= t('folder.empty') %></span>
         </div>
       </li>
       <li class="treeview__loading border-bottom p-1"><%= t('loading') %></li>
diff --git a/app/views/admin/communication/website/pages/_form.html.erb b/app/views/admin/communication/website/pages/_form.html.erb
index b7b890ce605ac69d123db269a8cbd3cf9096b4ab..2781e1729e265ea7e183b6cd7815823ffd3f4f6d 100644
--- a/app/views/admin/communication/website/pages/_form.html.erb
+++ b/app/views/admin/communication/website/pages/_form.html.erb
@@ -8,7 +8,7 @@
         <div class="card-body">
           <%= f.input :title %>
           <%= f.input :description %>
-          <%= f.input :text, as: :rich_text_area %>
+          <%= f.input :text, as: :summernote %>
           <%= f.association :related_category,
                             collection: collection_tree(@website.categories),
                             label_method: ->(p) { sanitize p[:label] },
diff --git a/app/views/admin/communication/website/pages/_treebranch.html.erb b/app/views/admin/communication/website/pages/_treebranch.html.erb
index 96980e5470c33def62a2ab6a658e6e7a16499664..d3e6569796bf413d97bc2f5af813c5837f776fe7 100644
--- a/app/views/admin/communication/website/pages/_treebranch.html.erb
+++ b/app/views/admin/communication/website/pages/_treebranch.html.erb
@@ -16,6 +16,11 @@
                   admin_communication_website_page_path(website_id: page.website.id, id: page.id),
                   class: "#{'opacity-50' unless page.published?}" %>
       <span class="move_btn py-2 ps-2"><i class="fas fa-sort"></i></span>
+      <%= link_to children_admin_communication_website_page_path(website_id: page.website.id, id: page.id),
+                  class: 'js-treeview-openzone small ps-2', remote: true do %>
+        <span class="open_text"><%= t 'folder.open' %></span>
+        <span class="close_text"><%= t 'folder.close' %></span>
+      <% end %>
       <div class="btn-group ms-auto" role="group">
         <%= edit_link page %>
         <%= destroy_link page, confirm_message: page.children.any? ? t('please_confirm_with_children') : t('please_confirm') %>
@@ -24,7 +29,7 @@
     <ul class="list-unstyled treeview__children js-treeview-children <%= 'js-treeview-sortable-container' if can?(:reorder, page) %> ms-4" data-id="<%= page.id %>">
       <li class="treeview__empty">
         <div class="d-flex align-items-center treeview__label border-bottom p-1">
-          <span class="p-2 ps-0"><%= t('empty_folder') %></span>
+          <span class="p-2 ps-0"><%= t('folder.empty') %></span>
         </div>
       </li>
       <li class="treeview__loading border-bottom p-1"><%= t('loading') %></li>
diff --git a/app/views/admin/communication/website/pages/show.html.erb b/app/views/admin/communication/website/pages/show.html.erb
index 898684ec08ae6278bc47ed3ddf9f1286d7f4d665..0300058af7631c41a01df2c8b9ededd734c4e38e 100644
--- a/app/views/admin/communication/website/pages/show.html.erb
+++ b/app/views/admin/communication/website/pages/show.html.erb
@@ -9,13 +9,11 @@
           <h2 class="card-title mb-0 h5"><%= t('content') %></h2>
         </div>
         <div class="card-body">
-          <h3 class="h5"><%= Communication::Website::Page.human_attribute_name('description') %></h3>
-          <%= sanitize @page.description %>
-
-          <h3 class="h5 mt-4"><%= Communication::Website::Page.human_attribute_name('text') %></h3>
-          <%= @page.text %>
+          <%= render 'admin/application/property/text', object: @page, property: :description %>
+          <%= render 'admin/application/property/text', object: @page, property: :text %>
         </div>
       </div>
+      <%= render 'admin/communication/website/blocks/list', about: @page %>
     </div>
     <div class="col-md-4">
       <div class="card flex-fill w-100">
@@ -77,6 +75,11 @@
   </div>
 <% end %>
 
+<% content_for :preview do %>
+  <%= @page.text.to_s %>
+<% end %>
+
 <% content_for :action_bar_right do %>
+  <%= preview_link %>
   <%= edit_link @page %>
 <% end %>
diff --git a/app/views/admin/communication/website/pages/static.html.erb b/app/views/admin/communication/website/pages/static.html.erb
index cc7f289eec0cf977cc1efa86c2ea189e895f4740..27e72b066c8a6992453ae5f5e3166960dc07c4ec 100644
--- a/app/views/admin/communication/website/pages/static.html.erb
+++ b/app/views/admin/communication/website/pages/static.html.erb
@@ -12,5 +12,6 @@ category: "<%= @page.related_category.path %>/"
 <% end %>
 description: >
   <%= prepare_text_for_static @page.description %>
+<%= render 'admin/communication/website/blocks/static', about: @page %>
 ---
 <%= prepare_html_for_static @page.text, @page.university %>
diff --git a/app/views/admin/communication/website/posts/_form.html.erb b/app/views/admin/communication/website/posts/_form.html.erb
index 99427bb40bfaa74d47f3da9e403dd2991452cd5a..c82cdb4b22eecf8375735497c3deb1abaee4c3e8 100644
--- a/app/views/admin/communication/website/posts/_form.html.erb
+++ b/app/views/admin/communication/website/posts/_form.html.erb
@@ -8,7 +8,7 @@
         <div class="card-body">
           <%= f.input :title %>
           <%= f.input :description %>
-          <%= f.input :text, as: :rich_text_area %>
+          <%= f.input :text, as: :summernote %>
         </div>
       </div>
       <div class="card flex-fill w-100">
diff --git a/app/views/admin/communication/website/posts/show.html.erb b/app/views/admin/communication/website/posts/show.html.erb
index 9ffac8da69451a456233aed2efed0c330e84e3d1..cfa349ba6ff4fe7afc01a4ea69f84a9c005b9ddf 100644
--- a/app/views/admin/communication/website/posts/show.html.erb
+++ b/app/views/admin/communication/website/posts/show.html.erb
@@ -8,11 +8,9 @@
           <h2 class="card-title mb-0 h5"><%= t('content') %></h2>
         </div>
         <div class="card-body">
-          <h3 class="h5"><%= Communication::Website::Post.human_attribute_name('description') %></h3>
-          <%= sanitize @post.description %>
-
-          <h3 class="h5 mt-4"><%= Communication::Website::Post.human_attribute_name('text') %></h3>
-          <%= @post.text %>
+          <%= render 'admin/application/property/text', object: @post, property: :description %>
+          <%= render 'admin/application/property/text', object: @post, property: :text %>
+          <%= render 'admin/application/property/summernote_embeds', object: @post, property: :medias %>
         </div>
       </div>
     </div>
@@ -60,6 +58,11 @@
   </div>
 <% end %>
 
+<% content_for :preview do %>
+  <%= @post.text.to_s %>
+<% end %>
+
 <% content_for :action_bar_right do %>
+  <%= preview_link %>
   <%= edit_link @post %>
 <% end %>
diff --git a/app/views/admin/communication/websites/_sidebar.html.erb b/app/views/admin/communication/websites/_sidebar.html.erb
index 07a6d26daaa14437458bf5f6db897473b1fdc318..c8f34789527c8719caac8614678096c25f522211 100644
--- a/app/views/admin/communication/websites/_sidebar.html.erb
+++ b/app/views/admin/communication/websites/_sidebar.html.erb
@@ -9,11 +9,6 @@
             path: admin_communication_website_path(id: @website),
             ability: can?(:read, @website)
           },
-          {
-            title: Communication::Website::Post.model_name.human(count: 2),
-            path: admin_communication_website_posts_path(website_id: @website),
-            ability: can?(:read, Communication::Website::Post)
-          },
           {
             title: Communication::Website::Home.model_name.human,
             path: admin_communication_website_home_path(website_id: @website),
@@ -24,6 +19,11 @@
             path: admin_communication_website_pages_path(website_id: @website),
             ability: can?(:read, Communication::Website::Page)
           },
+          {
+            title: Communication::Website::Post.model_name.human(count: 2),
+            path: admin_communication_website_posts_path(website_id: @website),
+            ability: can?(:read, Communication::Website::Post)
+          },
           {
             title: Communication::Website::Category.model_name.human(count: 2),
             path: admin_communication_website_categories_path(website_id: @website),
diff --git a/app/views/admin/education/program/roles/_form.html.erb b/app/views/admin/education/program/roles/_form.html.erb
index 54d99730bb0f75ceb39daa2b09be65eb3fe51a9c..071666536428eb62160bb0deac3476508931a2b8 100644
--- a/app/views/admin/education/program/roles/_form.html.erb
+++ b/app/views/admin/education/program/roles/_form.html.erb
@@ -8,7 +8,7 @@
           <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
         </div>
         <div class="card-body">
-          <%= f.input :description %>
+          <%= f.input :description, as: :string %>
         </div>
       </div>
     </div>
diff --git a/app/views/admin/education/program/roles/index.html.erb b/app/views/admin/education/program/roles/index.html.erb
index fa4e8a5493acf50486e09e7e5389558adbfad9bf..9efa6d56e14ba8f10e242c7b5c1f5a30f897031b 100644
--- a/app/views/admin/education/program/roles/index.html.erb
+++ b/app/views/admin/education/program/roles/index.html.erb
@@ -2,5 +2,7 @@
 <%= render 'admin/education/program/roles/list', roles: @roles %>
 
 <% content_for :action_bar_right do %>
-  <%= link_to t('add'), new_admin_education_program_role_path(program_id: @program.id), class: button_classes if can? :create, University::Role %>
+  <%= link_to t('create'),
+              new_admin_education_program_role_path(program_id: @program.id),
+              class: button_classes if can? :create, University::Role %>
 <% end %>
diff --git a/app/views/admin/education/program/teachers/_form.html.erb b/app/views/admin/education/program/teachers/_form.html.erb
index b77505dfdb3e19597b8ccde8c8765dfaa5c4278a..08f8fcb78e879a85c064151faad55a602f8e685d 100644
--- a/app/views/admin/education/program/teachers/_form.html.erb
+++ b/app/views/admin/education/program/teachers/_form.html.erb
@@ -11,7 +11,7 @@
           <%= f.association :person, collection: @available_people %>
         </div>
         <div class="col-md-6">
-          <%= f.input :description %>
+          <%= f.input :description, as: :string %>
         </div>
       </div>
     </div>
diff --git a/app/views/admin/education/program/teachers/index.html.erb b/app/views/admin/education/program/teachers/index.html.erb
index f37281009002c9944136ec4e9d76b43ee96b9d5c..2c4ebc71137a21df10684b9591117206134b2da1 100644
--- a/app/views/admin/education/program/teachers/index.html.erb
+++ b/app/views/admin/education/program/teachers/index.html.erb
@@ -2,5 +2,7 @@
 <%= render 'admin/education/program/teachers/list', involvements: @involvements %>
 
 <% content_for :action_bar_right do %>
-  <%= link_to t('add'), new_admin_education_program_teacher_path(program_id: @program.id), class: button_classes %>
+  <%= link_to t('create'),
+              new_admin_education_program_teacher_path(program_id: @program.id),
+              class: button_classes %>
 <% end %>
diff --git a/app/views/admin/education/programs/_form.html.erb b/app/views/admin/education/programs/_form.html.erb
index 461c20397edabcdfe9e4465e00516fa02e001774..efb7293ccc3bd348198e679f6d07fa5b6b15e9ee 100644
--- a/app/views/admin/education/programs/_form.html.erb
+++ b/app/views/admin/education/programs/_form.html.erb
@@ -66,26 +66,40 @@
       <h5 class="card-title mb-0"><%= t('activerecord.attributes.education/program.team') %></h5>
     </div>
     <div class="card-body">
-      <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :contacts %>
+      <div class="row">
+        <div class="col-md-4">
+          <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :contacts %>
+        </div>
+        <div class="col-md-8 clearfix">
+          <div class="row mb-2">
+            <div class="col-md-8">
+              <label class="form-label"><%= Education::Program.human_attribute_name('teachers') %></label>
+            </div>
+            <div class="col-md-4 text-end">
+              <%= link_to_add_association t('add'),
+                                          f,
+                                          :university_person_involvements,
+                                          class: button_classes,
+                                          partial: 'admin/education/programs/involvement_fields',
+                                          data: {
+                                            'association-insertion-method': 'append',
+                                            'association-insertion-node':   '#involvements',
+                                          } %>
+            </div>
+          </div>
 
-      <p><%= Education::Program.human_attribute_name('teachers') %></p>
-      <%= link_to_add_association t('add'), f, :university_person_involvements,
-                                  class: "btn btn-primary mb-3",
-                                  partial: 'admin/education/programs/involvement_fields',
-                                  data: {
-                                    'association-insertion-method': 'append',
-                                    'association-insertion-node':   '#involvements',
-                                  } %>
+          <div id="involvements">
+            <%
+            sorted_involvements = program.university_person_involvements.sort_by { |involvement|
+              [involvement.person&.last_name, involvement.person&.first_name]
+            }
+            %>
+            <%= f.simple_fields_for :university_person_involvements, sorted_involvements, include_id: false do |involvement_f| %>
+              <%= render 'admin/education/programs/involvement_fields', f: involvement_f, include_id: true %>
+            <% end %>
+          </div>
 
-      <div class="row mb-3" id="involvements">
-        <%
-        sorted_involvements = program.university_person_involvements.sort_by { |involvement|
-          [involvement.person&.last_name, involvement.person&.first_name]
-        }
-        %>
-        <%= f.simple_fields_for :university_person_involvements, sorted_involvements, include_id: false do |involvement_f| %>
-          <%= render 'admin/education/programs/involvement_fields', f: involvement_f, include_id: true %>
-        <% end %>
+        </div>
       </div>
     </div>
   </div>
diff --git a/app/views/admin/education/programs/_involvement_fields.html.erb b/app/views/admin/education/programs/_involvement_fields.html.erb
index 08a3e0acc0b5d3db6f4edf28e1e7b9d3c8473036..fe5549b692e79424a714cd38e59e818aac616b85 100644
--- a/app/views/admin/education/programs/_involvement_fields.html.erb
+++ b/app/views/admin/education/programs/_involvement_fields.html.erb
@@ -1,17 +1,25 @@
 <% include_id ||= false %>
-<div class="nested-fields col-md-3">
-  <div class="card mb-2">
-    <div class="card-body">
-      <div class="row align-items-center">
-        <div class="col-10">
-          <%= f.association :person, collection: @teacher_people, label: false, include_blank: :translate, required: true %>
-          <%= f.input :description, label: false, placeholder: University::Person::Involvement.human_attribute_name('description'), wrapper: false %>
-        </div>
-        <div class="col-2">
-          <%= link_to_remove_association '<i class="fas fa-trash"></i>'.html_safe, f, class: 'btn btn-sm btn-danger' %>
-        </div>
-      </div>
+<div class="nested-fields">
+  <div class="row">
+    <div class="col-md-5">
+      <%= f.association :person,
+                        collection: @teacher_people,
+                        label: false,
+                        include_blank: :translate,
+                        required: true %>
+    </div>
+    <div class="col-md-6">
+      <%= f.input :description,
+                  as: :string,
+                  label: false,
+                  placeholder: University::Person::Involvement.human_attribute_name('description'),
+                  wrapper: false %>
+    </div>
+    <div class="col-md-1 text-end">
+      <%= link_to_remove_association  '<i class="fas fa-trash"></i>'.html_safe,
+                                      f,
+                                      class: 'btn btn-sm btn-danger' %>
     </div>
-    <%= f.hidden_field :id if include_id %>
   </div>
+  <%= f.hidden_field :id if include_id %>
 </div>
diff --git a/app/views/admin/education/programs/_treebranch.html.erb b/app/views/admin/education/programs/_treebranch.html.erb
index b70fff45869b86044d84869a447edd122a9cb763..4e34bcf589c0a586d6cc14d488e6dcf18b4690a8 100644
--- a/app/views/admin/education/programs/_treebranch.html.erb
+++ b/app/views/admin/education/programs/_treebranch.html.erb
@@ -15,6 +15,11 @@
       <%= link_to program,
                   admin_education_program_path(id: program.id) %>
       <span class="move_btn py-2 ps-2"><i class="fas fa-sort"></i></span>
+      <%= link_to children_admin_education_program_path(id: program.id),
+                  class: 'js-treeview-openzone small ps-2', remote: true do %>
+        <span class="open_text"><%= t 'folder.open' %></span>
+        <span class="close_text"><%= t 'folder.close' %></span>
+      <% end %>
       <div class="btn-group ms-auto" role="group">
         <%= edit_link program %>
         <%= destroy_link program, confirm_message: program.children.any? ? t('please_confirm_with_children') : t('please_confirm') %>
@@ -23,7 +28,7 @@
     <ul class="list-unstyled treeview__children js-treeview-children <%= 'js-treeview-sortable-container' if can?(:reorder, program) %> ms-4" data-id="<%= program.id %>">
       <li class="treeview__empty">
         <div class="d-flex align-items-center treeview__label border-bottom p-1">
-          <span class="p-2 ps-0"><%= t('empty_folder') %></span>
+          <span class="p-2 ps-0"><%= t('folder.empty') %></span>
         </div>
       </li>
       <li class="treeview__loading border-bottom p-1"><%= t('loading') %></li>
diff --git a/app/views/admin/education/programs/forms/_input_with_inheritance.html.erb b/app/views/admin/education/programs/forms/_input_with_inheritance.html.erb
index 50abd4dd0ce3ec6de5d3cab6ef1e4273e9e7c887..2fd2b5fcd8a60009a89f0356886a602af9b106e5 100644
--- a/app/views/admin/education/programs/forms/_input_with_inheritance.html.erb
+++ b/app/views/admin/education/programs/forms/_input_with_inheritance.html.erb
@@ -17,7 +17,7 @@ id = "#{property}Collapse"
       </a>
     </div>
     <div class="collapse" id="<%= id %>">
-      <%= f.input property, as: :rich_text_area, label: false %>
+      <%= f.input property, as: :summernote, label: false %>
       <div class="bg-light p-2 mt-n2">
         <b><%= t 'admin.inheritance.sentence_html', link: link_to(best_prop_source, [:admin, best_prop_source]) %></b><br>
         <%= best_prop_value %>
@@ -25,5 +25,5 @@ id = "#{property}Collapse"
     </div>
   </div>
 <% else %>
-  <%= f.input property, as: :rich_text_area %>
+  <%= f.input property, as: :summernote %>
 <% end %>
diff --git a/app/views/admin/education/programs/show.html.erb b/app/views/admin/education/programs/show.html.erb
index d6ef2d1ab04c6a560963ca2bb57040cf0e72bb42..c4ce97bdc95a86c8db91399478f41042e3197739 100644
--- a/app/views/admin/education/programs/show.html.erb
+++ b/app/views/admin/education/programs/show.html.erb
@@ -2,7 +2,7 @@
 
 <div class="row">
 
-  <div class="col-md-4">
+  <div class="col-md-3">
     <div class="card flex-fill w-100">
       <div class="card-header">
         <h2 class="card-title mb-0 h5"><%= t('education.program.main_informations') %></h2>
@@ -39,16 +39,13 @@
       </div>
     <% end %>
   </div>
-  <div class="col-md-8">
+  <div class="col-md-4">
     <div class="card flex-fill w-100">
       <div class="card-header">
         <h5 class="card-title mb-0"><%= t('education.program.useful_informations') %></h5>
       </div>
       <div class="card-body">
-        <h3 class="h5 mt-4">
-          <%= Education::Program.human_attribute_name('description') %>
-        </h3>
-        <p><%= @program.description %></p>
+        <%= render 'admin/application/property/text', object: @program, property: :description %>
         <% [
               :registration,
               :pricing,
@@ -56,58 +53,29 @@
               :contacts,
               :accessibility,
               :other
-            ].each_with_index do |prop, index| %>
-          <%
-          best_prop_value = @program.public_send("best_#{prop}")
-          best_prop_source = @program.public_send("best_#{prop}_source")
-          %>
-          <% next if best_prop_value.blank? # No value at all%>
-          <h3 class="h5 mt-4">
-            <%= Education::Program.human_attribute_name(prop) %>
-            <% if best_prop_source %>
-              <span class="small text-muted">
-                <%= t 'admin.inheritance.sentence_html', link: link_to(best_prop_source, [:admin, best_prop_source]) %>
-              </span>
-            <% end %>
-          </h3>
-          <%= best_prop_value %>
+            ].each_with_index do |property, index| %>
+            <%= render 'admin/application/property/text', object: @program, property: property %>
         <% end %>
       </div>
     </div>
   </div>
-</div>
+  <div class="col-md-5">
 
-<div class="card flex-fill w-100">
-  <div class="card-header">
-    <h5 class="card-title mb-0"><%= t('education.program.educational_informations') %></h5>
-  </div>
-  <div class="card-body">
-    <div class="row">
-      <div class="col-md-6">
-        <% i = 0 %>
+    <div class="card flex-fill w-100">
+      <div class="card-header">
+        <h5 class="card-title mb-0"><%= t('education.program.educational_informations') %></h5>
+      </div>
+      <div class="card-body">
         <%  [
               :objectives,
               :content,
-              :prerequisites
-            ].each do |prop| %>
-          <% next if @program.public_send(prop).blank? %>
-          <h3 class="h5 <%= 'mt-4' if i > 0 %>"><%= Education::Program.human_attribute_name(prop) %></h3>
-          <%= @program.public_send prop %>
-          <% i += 1 %>
-        <% end %>
-      </div>
-      <div class="col-md-6">
-        <% i = 0 %>
-        <%  [
+              :prerequisites,
               :pedagogy,
               :evaluation,
               :opportunities,
               :results
-            ].each do |prop| %>
-          <% next if @program.public_send(prop).blank? %>
-          <h3 class="h5 <%= 'mt-4' if i > 0 %>"><%= Education::Program.human_attribute_name(prop) %></h3>
-          <%= @program.public_send prop %>
-          <% i += 1 %>
+            ].each do |property| %>
+          <%= render 'admin/application/property/text', object: @program, property: property %>
         <% end %>
       </div>
     </div>
@@ -141,6 +109,27 @@
   </div>
 <% end %>
 
+<% content_for :preview do %>
+  <%  [
+        :registration,
+        :pricing,
+        :duration,
+        :contacts,
+        :accessibility,
+        :other,
+        :objectives,
+        :content,
+        :prerequisites,
+        :pedagogy,
+        :evaluation,
+        :opportunities,
+        :results
+      ].each do |property| %>
+    <%= @program.send(property).to_s %>
+  <% end %>
+<% end %>
+
 <% content_for :action_bar_right do %>
+  <%= preview_link %>
   <%= edit_link @program %>
 <% end %>
diff --git a/app/views/admin/education/school/roles/_form.html.erb b/app/views/admin/education/school/roles/_form.html.erb
index c5ef4a1c65b23b012228150fb597516195c798c5..effcbf968c7aa761097edfa8ca9dbbba68a6c303 100644
--- a/app/views/admin/education/school/roles/_form.html.erb
+++ b/app/views/admin/education/school/roles/_form.html.erb
@@ -9,7 +9,7 @@
           <h5 class="card-title mb-0"><%= t('admin.infos') %></h5>
         </div>
         <div class="card-body">
-          <%= f.input :description %>
+          <%= f.input :description, as: :string %>
         </div>
       </div>
     </div>
diff --git a/app/views/admin/layouts/application.html.erb b/app/views/admin/layouts/application.html.erb
index adabf291c242ffb062667deaa3a1c155e140ea4c..91f08ea3ac2b3b3fefdab42ab475ce630c29a158 100644
--- a/app/views/admin/layouts/application.html.erb
+++ b/app/views/admin/layouts/application.html.erb
@@ -37,6 +37,7 @@
             </div>
             <%= yield %>
           </div>
+          <%= render 'admin/application/preview' %>
         </main>
       </div>
     </div>
diff --git a/app/views/admin/research/journal/articles/_form.html.erb b/app/views/admin/research/journal/articles/_form.html.erb
index 46bf970021c39cf8cd58f8a335d3ecf844493a28..dfb583c60d1d172b5887ce56b207c98bab37fdd1 100644
--- a/app/views/admin/research/journal/articles/_form.html.erb
+++ b/app/views/admin/research/journal/articles/_form.html.erb
@@ -15,7 +15,7 @@
                       } %>
           <%= f.input :abstract, as: :text, input_html: { rows: 8 } %>
           <%= f.input :pdf %>
-          <%= f.input :text, as: :rich_text_area %>
+          <%= f.input :text, as: :summernote %>
           <%= f.input :references, as: :text, input_html: { rows: 10 } %>
         </div>
       </div>
diff --git a/app/views/admin/research/laboratory/axes/_form.html.erb b/app/views/admin/research/laboratory/axes/_form.html.erb
index 1528df4da672855163b999b25c7910f1df404dc9..f0476a1520b10dfe1c6f4dc62d81abfbced3fdd8 100644
--- a/app/views/admin/research/laboratory/axes/_form.html.erb
+++ b/app/views/admin/research/laboratory/axes/_form.html.erb
@@ -15,7 +15,7 @@
             </div>
           </div>
           <%= f.input :description, as: :text, input_html: { rows: 2 } %>
-          <%= f.input :text, as: :rich_text_area %>
+          <%= f.input :text, as: :summernote %>
         </div>
       </div>
     </div>
diff --git a/app/views/admin/university/people/_form.html.erb b/app/views/admin/university/people/_form.html.erb
index e5781875d4a45d3464ac0ed617a9cde8c15647b2..57edd82edd6633166a7c0773e33699950ef0d237 100644
--- a/app/views/admin/university/people/_form.html.erb
+++ b/app/views/admin/university/people/_form.html.erb
@@ -23,7 +23,7 @@
             </div>
           </div>
           <%= f.input :description %>
-          <%= f.input :biography, as: :rich_text_area %>
+          <%= f.input :biography, as: :summernote %>
         </div>
       </div>
       <div class="card flex-fill w-100">
diff --git a/app/views/server/layouts/application.html.erb b/app/views/server/layouts/application.html.erb
index ec219563bd8e79df2f8e3d07bf075ffc16379503..b3f5fb58c8f5e9ad6bb4448f3dd2b27ac456056d 100644
--- a/app/views/server/layouts/application.html.erb
+++ b/app/views/server/layouts/application.html.erb
@@ -45,6 +45,7 @@
       </div>
     </div>
     <%= javascript_include_tag 'admin' %>
+    <%= render 'gdpr/cookie_consent' %>
     <%= render 'bugsnag' %>
   </body>
 </html>
diff --git a/config/application.rb b/config/application.rb
index 4066c05a38912f51842cc8d19be02f1350dc5aa7..f060b9d569b508db293dd9fbd462e39b42299cdf 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -52,10 +52,10 @@ module Osuny
       "a", "abbr", "acronym", "address", "b", "big", "blockquote", "br",
       "cite", "code", "dd", "del", "dfn", "div", "dl", "dt", "em",
       "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li", "ol",
-      "p", "picture", "pre", "samp", "small", "source", "span", "strong", "sub", "sup", "tt", "u", "ul", "var"
+      "p", "picture", "pre", "samp", "small", "source", "span", "strong", "sub", "sup", "tt", "u", "ul", "var", "video"
     ]
     config.action_view.sanitized_allowed_attributes = [
-      "abbr", "alt", "cite", "class", "datetime", "decoding", "height", "href", "loading",
+      "abbr", "alt", "cite", "class", "controls", "datetime", "decoding", "height", "href", "loading",
       "name", "sizes", "src", "srcset", "style", "target", "title", "type", "width", "xml:lang"
     ]
 
diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml
index afa0575fb77b327c31e45825cf2b67937648015c..f7cc60ce5ecbb1db71d531df167323d194ea92e4 100644
--- a/config/locales/communication/en.yml
+++ b/config/locales/communication/en.yml
@@ -7,6 +7,9 @@ en:
       communication/website:
         one: Website
         other: Websites
+      communication/website/block:
+        one: Content block
+        other: Content blocks
       communication/website/category:
         one: Category
         other: Categories
@@ -43,6 +46,9 @@ en:
         about_type: About
         name: Name
         url: URL
+      communication/website/block:
+        name: Name
+        template: Kind of block
       communication/website/category:
         children: Children categories
         description: Description
@@ -130,6 +136,9 @@ en:
     manage_authors: Manage authors
     number_of_posts: Nunber of posts
     website:
+      block:
+        choose_template: Choose the kind of block to add
+        choose: Choose
       git: Git
       imported:
         from: Imported from
@@ -150,6 +159,10 @@ en:
   enums:
     communication:
       website:
+        block:
+          template:
+            organization_chart: Organization chart
+            partners: Partners
         menu:
           item:
             kind:
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index 9dd4e4d76967206cfc58e4931c64f374085ec63e..c840b2974eaf11163d9d4ce5c9b75aad371fe3fe 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -7,6 +7,9 @@ fr:
       communication/website:
         one: Site Web
         other: Sites Web
+      communication/website/block:
+        one: Bloc de contenu
+        other: Blocs de contenu
       communication/website/category:
         one: Catégorie
         other: Catégories
@@ -46,6 +49,9 @@ fr:
         about_type: Sujet du site
         name: Nom
         url: URL
+      communication/website/block:
+        name: Nom
+        template: Type de bloc
       communication/website/category:
         children: Catégories enfants
         description: Description
@@ -140,6 +146,9 @@ fr:
     manage_authors: Gérer les auteur·rice·s
     number_of_posts: Nombre d'actualités
     website:
+      block:
+        choose_template: Choisir le type de bloc à ajouter
+        choose: Choisir
       git: Git
       imported:
         from: Importé depuis
@@ -202,6 +211,10 @@ fr:
   enums:
     communication:
       website:
+        block:
+          template:
+            organization_chart: Organigramme
+            partners: Partenaires
         menu:
           item:
             kind:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e535a3d133575b6ec0d4b52886dd78a7689a5088..1e7b63f4418bbc67887891c1617458e50b6ac293 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -85,8 +85,8 @@ en:
       send_code_instead: "Send me a code instead"
       send_email_code: 'Send me a code via email'
       success: ""
+  download: Download
   edit: Edit
-  empty_folder: Empty folder
   false: No
   filters:
     attributes:
@@ -95,6 +95,10 @@ en:
     buttons:
       expand: Filter table
       submit: Filter
+  folder:
+    empty: Folder is empty
+    open: Open folder
+    close: Close folder
   gdpr:
     privacy_policy: https://osuny.org/politique-de-confidentialite
   hello: "Hello %{name}!"
@@ -116,6 +120,9 @@ en:
   metadata: Metadata
   please_confirm: Are you sure?
   please_confirm_with_children: "WARNING: deleting this element will also remove every child. Are you sure?"
+  preview:
+    button: Preview
+    title: Mobile preview
   privacy_policy: Privacy policy
   privacy_policy_url: https://osuny.org/politique-de-confidentialite
   quit: Quit
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index f16346f8df5c30959b017b8be3cd7321791864fd..5cedc06f52edc633887e4768bc711b36735e349e 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -85,8 +85,8 @@ fr:
       send_code_instead: "Envoyez-moi plutôt un code"
       send_email_code: 'Envoyer le code par email'
       success: ""
+  download: Télécharger
   edit: Modifier
-  empty_folder: Dossier vide
   false: Non
   filters:
     attributes:
@@ -95,6 +95,10 @@ fr:
     buttons:
       expand: Filtrer le tableau
       submit: Filtrer
+  folder:
+    empty: Le dossier est vide
+    open: Ouvrir le dossier
+    close: Fermer le dossier
   gdpr:
     privacy_policy: https://osuny.org/politique-de-confidentialite
   hello: "Bonjour %{name} !"
@@ -116,6 +120,9 @@ fr:
   metadata: Informations
   please_confirm: Est-ce que vous confirmez ?
   please_confirm_with_children: "ATTENTION : effacer cet élément supprimera aussi tous ses enfants. Est-ce que vous confirmez ?"
+  preview:
+    button: Prévisualiser
+    title: Prévisualisation mobile
   privacy_policy: Politique de confidentialité
   privacy_policy_url: https://osuny.org/politique-de-confidentialite
   quit: Quitter
diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb
index d88c57b0d80446a20036aa071e0553d3a7d2faf7..87ed087750da7d711dcb4daf698c334afe595c21 100644
--- a/config/routes/admin/communication.rb
+++ b/config/routes/admin/communication.rb
@@ -25,6 +25,11 @@ namespace :communication do
     resources :authors, controller: 'website/authors', only: [:index, :show]
     resources :posts, controller: 'website/posts'
     resources :curations, path: 'posts/curations', as: :post_curations, controller: 'website/posts/curations', only: [:new, :create]
+    resources :blocks, controller: 'website/blocks', except: :index do
+      collection do
+        post :reorder
+      end
+    end
     resources :menus, controller: 'website/menus' do
       resources :items, controller: 'website/menu/items', except: :index do
         collection do
diff --git a/db/migrate/20220214125058_add_new_texts.rb b/db/migrate/20220214125058_add_new_texts.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b4ef363ef7039a864583323de47be98aedd97ae0
--- /dev/null
+++ b/db/migrate/20220214125058_add_new_texts.rb
@@ -0,0 +1,24 @@
+class AddNewTexts < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_website_homes, :text_new, :text
+    add_column :communication_website_pages, :text_new, :text
+    add_column :research_journal_articles, :text_new, :text
+    add_column :research_laboratory_axes, :text_new, :text
+    add_column :university_people, :biography_new, :text
+    add_column :education_programs, :accessibility_new, :text
+    add_column :education_programs, :contacts_new, :text
+    add_column :education_programs, :duration_new, :text
+    add_column :education_programs, :evaluation_new, :text
+    add_column :education_programs, :objectives_new, :text
+    add_column :education_programs, :opportunities_new, :text
+    add_column :education_programs, :other_new, :text
+    add_column :education_programs, :pedagogy_new, :text
+    add_column :education_programs, :prerequisites_new, :text
+    add_column :education_programs, :pricing_new, :text
+    add_column :education_programs, :registration_new, :text
+    add_column :education_programs, :content_new, :text
+    add_column :education_programs, :results_new, :text
+    # Clean an old field
+    remove_column :research_journal_articles, :old_text
+  end
+end
diff --git a/db/migrate/20220215094808_create_communication_website_blocks.rb b/db/migrate/20220215094808_create_communication_website_blocks.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dddd548af2c38a68d6d2fb09a4b7fe812442b2ec
--- /dev/null
+++ b/db/migrate/20220215094808_create_communication_website_blocks.rb
@@ -0,0 +1,14 @@
+class CreateCommunicationWebsiteBlocks < ActiveRecord::Migration[6.1]
+  def change
+    create_table :communication_website_blocks, id: :uuid do |t|
+      t.references :university, null: false, foreign_key: true, type: :uuid
+      t.references :communication_website, null: false, foreign_key: true, type: :uuid
+      t.references :about, polymorphic: true, type: :uuid
+      t.integer :template, default: 0, null: false
+      t.jsonb :data
+      t.integer :position, default: 0, null: false
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20220215142845_rename_new_texts.rb b/db/migrate/20220215142845_rename_new_texts.rb
new file mode 100644
index 0000000000000000000000000000000000000000..165437ba0c576a6ab94ecceeb299ff6940d82307
--- /dev/null
+++ b/db/migrate/20220215142845_rename_new_texts.rb
@@ -0,0 +1,23 @@
+class RenameNewTexts < ActiveRecord::Migration[6.1]
+  def change
+    rename_column :communication_website_homes, :text_new, :text
+    rename_column :communication_website_pages, :text_new, :text
+    rename_column :communication_website_posts, :text_new, :text
+    rename_column :research_journal_articles, :text_new, :text
+    rename_column :research_laboratory_axes, :text_new, :text
+    rename_column :university_people, :biography_new, :biography
+    rename_column :education_programs, :accessibility_new, :accessibility
+    rename_column :education_programs, :contacts_new, :contacts
+    rename_column :education_programs, :duration_new, :duration
+    rename_column :education_programs, :evaluation_new, :evaluation
+    rename_column :education_programs, :objectives_new, :objectives
+    rename_column :education_programs, :opportunities_new, :opportunities
+    rename_column :education_programs, :other_new, :other
+    rename_column :education_programs, :pedagogy_new, :pedagogy
+    rename_column :education_programs, :prerequisites_new, :prerequisites
+    rename_column :education_programs, :pricing_new, :pricing
+    rename_column :education_programs, :registration_new, :registration
+    rename_column :education_programs, :content_new, :content
+    rename_column :education_programs, :results_new, :results
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3a9315c5c172064ed2ab8b4a612e6ebcd7a824eb..e310ee7e92b8fcf355f9dac6ac011713e7da3a55 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2022_02_14_144924) do
+ActiveRecord::Schema.define(version: 2022_02_15_142845) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -79,6 +79,21 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.index ["criterion_id"], name: "index_administration_qualiopi_indicators_on_criterion_id"
   end
 
+  create_table "communication_website_blocks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "communication_website_id", null: false
+    t.string "about_type"
+    t.uuid "about_id"
+    t.integer "template", default: 0, null: false
+    t.jsonb "data"
+    t.integer "position", default: 0, null: false
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["about_type", "about_id"], name: "index_communication_website_blocks_on_about"
+    t.index ["communication_website_id"], name: "index_communication_website_blocks_on_communication_website_id"
+    t.index ["university_id"], name: "index_communication_website_blocks_on_university_id"
+  end
+
   create_table "communication_website_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.uuid "communication_website_id", null: false
@@ -126,7 +141,7 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.text "github_path"
     t.string "featured_image_alt"
     t.text "description"
-    t.text "text_new"
+    t.text "text"
     t.index ["communication_website_id"], name: "idx_comm_website_homes_on_communication_website_id"
     t.index ["university_id"], name: "index_communication_website_homes_on_university_id"
   end
@@ -304,7 +319,7 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.text "github_path"
     t.uuid "related_category_id"
     t.string "featured_image_alt"
-    t.text "text_new"
+    t.text "text"
     t.index ["about_type", "about_id"], name: "index_communication_website_pages_on_about"
     t.index ["communication_website_id"], name: "index_communication_website_pages_on_communication_website_id"
     t.index ["parent_id"], name: "index_communication_website_pages_on_parent_id"
@@ -327,7 +342,7 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.uuid "author_id"
     t.boolean "pinned", default: false
     t.string "featured_image_alt"
-    t.text "text_new"
+    t.text "text"
     t.index ["author_id"], name: "index_communication_website_posts_on_author_id"
     t.index ["communication_website_id"], name: "index_communication_website_posts_on_communication_website_id"
     t.index ["university_id"], name: "index_communication_website_posts_on_university_id"
@@ -424,19 +439,19 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.text "description"
     t.boolean "published", default: false
     t.string "featured_image_alt"
-    t.text "accessibility_new"
-    t.text "contacts_new"
-    t.text "duration_new"
-    t.text "evaluation_new"
-    t.text "objectives_new"
-    t.text "opportunities_new"
-    t.text "other_new"
-    t.text "pedagogy_new"
-    t.text "prerequisites_new"
-    t.text "pricing_new"
-    t.text "registration_new"
-    t.text "content_new"
-    t.text "results_new"
+    t.text "accessibility"
+    t.text "contacts"
+    t.text "duration"
+    t.text "evaluation"
+    t.text "objectives"
+    t.text "opportunities"
+    t.text "other"
+    t.text "pedagogy"
+    t.text "prerequisites"
+    t.text "pricing"
+    t.text "registration"
+    t.text "content"
+    t.text "results"
     t.index ["parent_id"], name: "index_education_programs_on_parent_id"
     t.index ["university_id"], name: "index_education_programs_on_university_id"
   end
@@ -491,7 +506,7 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.string "slug"
     t.boolean "published", default: false
     t.integer "position"
-    t.text "text_new"
+    t.text "text"
     t.index ["research_journal_id"], name: "index_research_journal_articles_on_research_journal_id"
     t.index ["research_journal_volume_id"], name: "index_research_journal_articles_on_research_journal_volume_id"
     t.index ["university_id"], name: "index_research_journal_articles_on_university_id"
@@ -555,7 +570,7 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.datetime "created_at", precision: 6, null: false
     t.datetime "updated_at", precision: 6, null: false
     t.string "short_name"
-    t.text "text_new"
+    t.text "text"
     t.index ["research_laboratory_id"], name: "index_research_laboratory_axes_on_research_laboratory_id"
     t.index ["university_id"], name: "index_research_laboratory_axes_on_university_id"
   end
@@ -609,7 +624,7 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
     t.text "description"
     t.boolean "habilitation", default: false
     t.boolean "tenure", default: false
-    t.text "biography_new"
+    t.text "biography"
     t.index ["university_id"], name: "index_university_people_on_university_id"
     t.index ["user_id"], name: "index_university_people_on_user_id"
   end
@@ -687,6 +702,8 @@ ActiveRecord::Schema.define(version: 2022_02_14_144924) do
   add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
   add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
   add_foreign_key "administration_qualiopi_indicators", "administration_qualiopi_criterions", column: "criterion_id"
+  add_foreign_key "communication_website_blocks", "communication_websites"
+  add_foreign_key "communication_website_blocks", "universities"
   add_foreign_key "communication_website_categories", "communication_website_categories", column: "parent_id"
   add_foreign_key "communication_website_categories", "communication_websites"
   add_foreign_key "communication_website_categories", "education_programs", column: "program_id"
diff --git a/docs/communication/websites/prototype.md b/docs/_rd/prototype.md
similarity index 100%
rename from docs/communication/websites/prototype.md
rename to docs/_rd/prototype.md
diff --git a/docs/communication/websites/blocks.md b/docs/communication/websites/blocks.md
new file mode 100644
index 0000000000000000000000000000000000000000..b31e672a8e773953d32be70eb8583969642bc3de
--- /dev/null
+++ b/docs/communication/websites/blocks.md
@@ -0,0 +1,74 @@
+# Blocks
+
+Blocs de contenus ajoutés à un objet (page, post, program...),
+avec des templates (organigramme, partenaires...).
+
+Il faut lister les dépendances des blocs et les ajouter à l'objet about.
+
+## Dev
+
+### Model
+
+```
+communication/website/Block
+- university:references
+- website:references
+- about:references (polymorphic)
+- template:integer (enum)
+- position:integer
+- data:jsonb
+```
+
+Pour commencer, les valeurs de l'enum seront :
+- 100, organization_chart
+- 200, partners
+
+### Partial about
+Un partial que l'on peut ajouter à un show d'objet, avec :
+- la liste des blocs utilisés (avec boutons show et edit)
+- la possibilité de les ordonner (position)
+- un bouton pour ajouter un bloc
+
+```
+views/admin/communication/website/blocks/_list.html.erb
+```
+
+### Show
+Le show du bloc utilise le partial de son template
+```
+views/admin/communication/website/blocks/templates/partners/_show.html.erb
+```
+
+### Edit
+L'edit du bloc utilise le partial de son template
+```
+views/admin/communication/website/blocks/templates/partners/_edit.html.erb
+```
+
+### Concern
+Tous les objets ayant des blocs utilisent le concern `WithBlocks`, qui ajoute la méthode `blocks` (la liste des blocs, dans l'ordre).
+
+### Export statique
+Les blocs sont exportés dans le frontmatter grâce au partial
+```
+views/admin/communication/website/blocks/_static.html.erb
+```
+qui donne ce type de résultat
+```
+blocks:
+  - template: partners
+    data:
+      - name: Partner 1
+        url: https://partner1.com
+        logo: "e09f3794-44e5-4b51-be02-0e384616e791"
+```
+Les générateurs de chaque type suivent l'organisation :
+```
+views/admin/communication/website/blocks/templates/partners/_static.html.erb
+```
+Attention, il faut 6 espaces pour respecter l'indentation du front-matter :
+```
+      - name: Partner 1
+        url: https://partner1.com
+        logo: "e09f3794-44e5-4b51-be02-0e384616e791"
+```
diff --git a/docs/communication/websites/customs.md b/docs/communication/websites/customs.md
new file mode 100644
index 0000000000000000000000000000000000000000..6dad14a7c768d87fbc433d1ebe871fd088aec5da
--- /dev/null
+++ b/docs/communication/websites/customs.md
@@ -0,0 +1,52 @@
+# Customs
+
+Au-delà des pages et des actualités, les sites ont souvent besoin d'objets spécifiques, au cas par cas.
+Le site https://www.osuny.org/ présente des fonctionnalités, avec un statut.
+Le site https://cyberneticproject.eu/ présente des fiches techniques, avec des synonymes, des téléchargements, un récapitulatif, des références bibliographiques...
+
+
+Afin de permettre cette souplesse, nous utilisons des types personnalisés (custom types).
+Le type définit une nouvelle sorte d'objets (ex: feature, technical_sheet...).
+Chaque type a des propriétés (title, description, summary, status, references...), qui génèrent un formulaire à la volée.
+Le type s'ajoute au menu du site, et permet de créer des éléments.
+Les éléments s'exportent en statique en utilisant la structure définie par les propriétés.
+
+## Modèles
+
+communication/website/custom/Type
+- university:references
+- website:references
+- name:string
+- identifier:string
+- position:integer
+- order:boolean
+- tree:boolean
+- date:boolean
+
+
+Si order est true, les éléments de ce type peuvent être classés par position (js sortable).
+Si tree est true, les éléments peuvent être organisés en arbre, avec des parents et des enfants.
+Si date est true, les élément peuvent être publiés à une date donnée.
+
+
+communication/website/custom/type/Property
+- university:references
+- website:references
+- type:references
+- name:string
+- identifier:string
+- kind:integer (enum)
+- position
+
+
+communication/website/custom/Element
+- university:references
+- website:references
+- type:references
+- name:string
+- slug:string
+- published:boolean
+- published_at:datetime
+- parent:references
+- position:integer
+- data:jsonb
diff --git a/docs/communication/websites/export.md b/docs/communication/websites/export.md
index 2af108bcda4077c57f81959666bb5e74ba41c0b7..efc0e03e90c7229394896b52ee73b0b87cbf1d6f 100644
--- a/docs/communication/websites/export.md
+++ b/docs/communication/websites/export.md
@@ -1,4 +1,4 @@
-# Export
+# Export Hugo
 
 ## Contexte
 
diff --git a/docs/communication/websites/import.md b/docs/communication/websites/import.md
index 2e2127707493b46bcc38a1cfc14ce2dd66c741cd..50f270657cb2098bc2908245fac3e6b1c67a11f2 100644
--- a/docs/communication/websites/import.md
+++ b/docs/communication/websites/import.md
@@ -1,4 +1,4 @@
-# Import
+# Import WordPress
 
 ## Contexte
 
diff --git a/docs/communication/websites/templates.md b/docs/communication/websites/templates.md
index 2e5c84061f92980756349504f7b63d92df038ba3..1d03ffb132ec9ce1ee7c0fc6805275f85fdbf162 100644
--- a/docs/communication/websites/templates.md
+++ b/docs/communication/websites/templates.md
@@ -1,17 +1,17 @@
 # Templates
 
-## Template de tous les sites
+## Thème
 
-https://github.com/osuny-org/template
+https://github.com/noesya/osuny-hugo-theme
 
-## Templates de tous les journaux
+## Template
 
-https://github.com/osuny-org/template-journal
+https://github.com/noesya/osuny-hugo-template
 
 Pour faire la mise à jour :
 
 ```
-git remote add template git@github.com:osuny-org/template.git
+git remote add template git@github.com:noesya/osuny-hugo-template.git
 git fetch --all
 git merge template/master --allow-unrelated-histories
 ```
@@ -23,7 +23,7 @@ https://github.com/osuny-org/clermontauvergne-journal-degrowth
 Pour faire la mise à jour :
 
 ```
-git remote add template git@github.com:osuny-org/template-journal.git
+git remote add template git@github.com:noesya/osuny-hugo-template.git
 git fetch --all
 git merge template/master --allow-unrelated-histories
 ```
diff --git a/docs/communication/websites/wysiwyg.md b/docs/communication/websites/wysiwyg.md
new file mode 100644
index 0000000000000000000000000000000000000000..43a4073f8ce6b5f9dba18a129d93a3c481119621
--- /dev/null
+++ b/docs/communication/websites/wysiwyg.md
@@ -0,0 +1,135 @@
+# WYSIWYG
+
+## Quels enjeux ?
+
+Permettre l'édition, mais limiter les options graphiques (ni couleurs, ni tailles, ni typos).
+
+Fonctionnalités :
+- intégration d'images dans le corps du texte, en gardant la trace du blob active storage, et en les intégrant dans la liste des dépendances.
+- intégration de vidéos.
+- intégration d'autres formats (Tweets...).
+
+## Solutions techniques
+
+### ActionText
+
+Avantages :
+- active storage intégré
+- Trix intégré
+
+Inconvénients :
+- Pas de modèle (polymorphic)
+
+### Trix
+
+Avantages :
+- intégré à ActionText
+- très limité
+
+Inconvénients :
+- très limité (target blank, 1 seul niveau de titre, pas d'embed, pas de code source)
+- pas extensible
+
+### Summernote
+
+Avantages :
+- vaste
+- extensible
+
+Inconvénients :
+- dépendance jQuery
+- pas intégré à ActionText
+- moyennement robuste quand on le torture
+
+### Page builder custom
+
+Avantages :
+- puissant
+- souple
+
+Inconvénients :
+- compliqué à construire et maintenir
+- compliqué à utiliser
+
+
+## Benchmark
+
+[Refinery](https://www.refinerycms.com/)
+
+
+[Spina](https://spinacms.com/)
+
+
+[Alchemy CMS](https://alchemy-cms.com/)
+
+
+[Locomotive CMS](https://www.locomotivecms.com/)
+
+
+## Méthode
+
+### action-text-attachment
+
+Dans la BDD, on stocke cette balise :
+```
+<action-text-attachment sgid="BAh[...]1df3"
+                        content-type="image/jpeg"
+                        url="http://demo.osuny:3000/rails/active_storage/blobs/redirect/eyJf[...]0f4a1/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg" filename="domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg"
+                        filesize="352931"
+                        width="588"
+                        height="746"
+                        previewable="true"
+                        presentation="gallery">
+</action-text-attachment>
+```
+
+A l'édition, la balise est "remplie" avant affichage, pour avoir une preview.
+A l'enregistrement, la balise est vidée.
+
+Etapes normales
+-[x] A l'import d'une image, ajouter l'action-text-attachement autour de l'img
+-[ ] A la suppression d'une image dans l'éditeur, supprimer l'action-text-attachement autour de l'img
+-[x] A l'enregistrement, déshydrater les action-text-attachements
+-[x] A l'édition, réhydrater les action-text-attachements
+-[ ] Après l'enregistrement mettre à jour les blobs attachés à l'objet parent (le post, par exemple)
+
+Si un programme a 5 champs Summernote avec 3 images dans chaque champ, cela fait 15 attachments à lier au programme.
+Si on enlève une image d'un champ, il faut mettre à jour la liste pour avoir les 14 bons attachments.
+
+Actions de dev
+-[ ] Coder les ajouts aux modèles dans Osuny
+-[ ] Coder le JS dans Osuny
+-[ ] Une fois que c'est fait, déplacer le Ruby et le JS dans summernote-rails
+
+Migration phase 1
+-[x] Ajouter des champs _new
+-[x] Au rails app:fix, transformer le markup Trix en markup Summernote (application_record) dans les propriétés _new
+Migration phase 2
+-[ ] Supprimer les champs ActionText dans les modèles
+-[ ] Supprimer la table d'ActionText
+-[ ] Renommer les champs en enlevant _new
+
+### Le pdf
+
+Autoriser dans summernote
+
+### Code HTML cible
+
+```
+<h2>Titre</h2>
+<p>
+  Texte normal<br>
+  <b>Texte en gras</b><br>
+  <i>Texte en italique</i>
+  <action-text-attachment sgid="BAh7CEkiCGdpZAY6BkVUSSJUZ2lkOi8vb3N1bnkvQWN0aXZlU3RvcmFnZTo6QmxvYi9hYWUyNDI5OC1kNDE2LTQ2YWMtYTRlNS02ZjY4ZGU2MjFiZDE_ZXhwaXJlc19pbgY7AFRJIgxwdXJwb3NlBjsAVEkiD2F0dGFjaGFibGUGOwBUSSIPZXhwaXJlc19hdAY7AFQw--7e8ead4d79f455499f1d73e8d53a4b8e81a21df3" content-type="image/jpeg" url="http://demo.osuny:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibW...df8140070f4a1/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58" filename="domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg" filesize="352931" width="588" height="746" previewable="true" presentation="gallery">
+    <figure class="attachment attachment--preview attachment--jpg">
+      <picture>
+        <source srcset="/rails/active_storage/representations/redirect/eyJfcmFpbHMiOns...XJpYXRpb24ifX0=--7d11fdd26322fef8959415f46d5e2c6d6763b4c0/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg 100w, /rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaE...527eb11f95949a389acb1c/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg 200w" type="image/webp">
+        <source srcset="/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibW...9fd77765da7c4f647d453b2/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58 100w, /rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibW...bb3bc14127bc06ce0d1e32/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58 200w" type="image/jpeg">
+        <img src="/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsi...190ffccd8/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58" loading="lazy" decoding="async" width="800">
+      </picture>
+    </figure>
+  </action-text-attachment>
+  <a href="https://www.u-bordeaux-montaigne.fr/fr/actualites/vie-etudiante/soutenir-les-etudiant-e-s-les-aides-de-l-universite.html">Lien</a>
+</p>
+```
diff --git a/docs/communication/wysiwyg.md b/docs/communication/wysiwyg.md
index 53a331177783595c4a7c48deb9d656e13f0a21be..96b007c386e8eb5aba0cccb86e7a987b35ed5850 100644
--- a/docs/communication/wysiwyg.md
+++ b/docs/communication/wysiwyg.md
@@ -64,3 +64,73 @@ Inconvénients :
 
 
 [Locomotive CMS](https://www.locomotivecms.com/)
+
+
+## Méthode
+
+### action-text-attachment
+
+Dans la BDD, on stocke cette balise :
+```
+<action-text-attachment sgid="BAh[...]1df3"
+                        content-type="image/jpeg"
+                        url="http://demo.osuny:3000/rails/active_storage/blobs/redirect/eyJf[...]0f4a1/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg" filename="domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg"
+                        filesize="352931"
+                        width="588"
+                        height="746"
+                        previewable="true"
+                        presentation="gallery">
+</action-text-attachment>
+```
+
+A l'édition, la balise est "remplie" avant affichage, pour avoir une preview.
+A l'enregistrement, la balise est vidée.
+
+Etapes normales
+-[x] A l'import d'une image, ajouter l'action-text-attachement autour de l'img
+-[x] A la suppression d'une image dans l'éditeur, supprimer l'action-text-attachement autour de l'img
+-[x] A l'enregistrement, déshydrater les action-text-attachements
+-[x] A l'édition, réhydrater les action-text-attachements
+-[x] Après l'enregistrement mettre à jour les blobs attachés à l'objet parent (le post, par exemple)
+
+Si un programme a 5 champs Summernote avec 3 images dans chaque champ, cela fait 15 attachments à lier au programme.
+Si on enlève une image d'un champ, il faut mettre à jour la liste pour avoir les 14 bons attachments.
+
+Actions de dev
+-[x] Coder les ajouts aux modèles dans Osuny
+-[x] Coder le JS dans Osuny
+-[x] Une fois que c'est fait, déplacer le Ruby et le JS dans summernote-rails
+
+Migration phase 1
+-[x] Ajouter des champs _new
+-[x] Au rails app:fix, transformer le markup Trix en markup Summernote (application_record) dans les propriétés _new
+-[x] Vérifier les paramètres du sanitizer d'Action Text (ActionText::ContentHelper : allowed_tags & allowed_attributes)
+Migration phase 2
+-[x] Supprimer les associations ActionText dans les modèles
+-[x] Renommer les champs en enlevant _new
+-[ ] Supprimer la table d'ActionText
+
+### Le pdf
+
+Autoriser dans summernote
+
+### Code HTML cible
+
+```
+<h2>Titre</h2>
+<p>
+  Texte normal<br>
+  <b>Texte en gras</b><br>
+  <i>Texte en italique</i>
+  <action-text-attachment sgid="BAh7CEkiCGdpZAY6BkVUSSJUZ2lkOi8vb3N1bnkvQWN0aXZlU3RvcmFnZTo6QmxvYi9hYWUyNDI5OC1kNDE2LTQ2YWMtYTRlNS02ZjY4ZGU2MjFiZDE_ZXhwaXJlc19pbgY7AFRJIgxwdXJwb3NlBjsAVEkiD2F0dGFjaGFibGUGOwBUSSIPZXhwaXJlc19hdAY7AFQw--7e8ead4d79f455499f1d73e8d53a4b8e81a21df3" content-type="image/jpeg" url="http://demo.osuny:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibW...df8140070f4a1/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58" filename="domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg" filesize="352931" width="588" height="746" previewable="true" presentation="gallery">
+    <figure class="attachment attachment--preview attachment--jpg">
+      <picture>
+        <source srcset="/rails/active_storage/representations/redirect/eyJfcmFpbHMiOns...XJpYXRpb24ifX0=--7d11fdd26322fef8959415f46d5e2c6d6763b4c0/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg 100w, /rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaE...527eb11f95949a389acb1c/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg 200w" type="image/webp">
+        <source srcset="/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibW...9fd77765da7c4f647d453b2/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58 100w, /rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibW...bb3bc14127bc06ce0d1e32/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58 200w" type="image/jpeg">
+        <img src="/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsi...190ffccd8/domenico_bruno_de_lobkowitz_watchingwindows_com_08.jpg?website_id=6d8fb0bb-0445-46f0-8954-0e25143e7a58" loading="lazy" decoding="async" width="800">
+      </picture>
+    </figure>
+  </action-text-attachment>
+  <a href="https://www.u-bordeaux-montaigne.fr/fr/actualites/vie-etudiante/soutenir-les-etudiant-e-s-les-aides-de-l-universite.html">Lien</a>
+</p>
+```
diff --git a/docs/readme.md b/docs/readme.md
index 0fc5a29944658b21481a471a3e4d7af097a9680b..0ec72b5dcd4f19bafc0eddb586608f9fd7222818 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -2,10 +2,10 @@
 
 ## Domaines
 
-https://bordeauxmontaigne.osuny.org/admin -> admin
-https://bordeauxmontaigne.osuny.org/alumni -> webservice des alumni, accessible en iframe
-https://bordeauxmontaigne.osuny.org/journal -> workflow publication et review revue scientifique
-https://bordeauxmontaigne.osuny.org/profile -> gestion de son propre profil
+- https://bordeauxmontaigne.osuny.org/admin -> admin
+- https://bordeauxmontaigne.osuny.org/alumni -> webservice des alumni, accessible en iframe
+- https://bordeauxmontaigne.osuny.org/journal -> workflow publication et review revue scientifique
+- https://bordeauxmontaigne.osuny.org/profile -> gestion de son propre profil
 
 
 Attention, il ne faut pas coder de couplage fort avec osuny.org (utiliser des variables d'env dans models/university/with_idenfier.rb).
diff --git a/lib/active_storage/service/scaleway_service.rb b/lib/active_storage/service/scaleway_service.rb
index 917bfd032d09389a0fabc2ffbb27d5c58c76e64c..28b7569b96cf8bf5149497c361c1ae19f7a2c17b 100644
--- a/lib/active_storage/service/scaleway_service.rb
+++ b/lib/active_storage/service/scaleway_service.rb
@@ -14,5 +14,17 @@ module ActiveStorage
 
       headers.merge({ "Content-Type" => content_type, "Content-MD5" => checksum, "Content-Disposition" => content_disposition })
     end
+
+    private
+
+    def public_url(key, **options)
+      disposition, filename, content_type = options.values_at(:disposition, :filename, :content_type)
+      uri = URI.parse(object_for(key).public_url)
+      uri.query = URI.encode_www_form({
+        "response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
+        "response-content-type" => content_type
+      })
+      uri.to_s
+    end
   end
 end
diff --git a/lib/tasks/app.rake b/lib/tasks/app.rake
index baf1c9b674bc4e613c414b1034b988fb92c7843a..3ab19673c2947b3dc11b5756ea120f985d34a15a 100644
--- a/lib/tasks/app.rake
+++ b/lib/tasks/app.rake
@@ -8,41 +8,26 @@ namespace :app do
 
   desc 'Fix things'
   task fix: :environment do
-    Communication::Website.find_each { |website|
-      website.build_home(university_id: website.university_id).save if website.home.nil?
-      website.update_column(:url, "https://#{website.url}") unless website.url.blank? || website.url.starts_with?('https://')
-    }
-
-    Education::Program.where(slug: [nil, '']).find_each { |program| program.update_column(:slug, program.name.parameterize) }
-    Research::Journal::Article.where(slug: [nil, '']).find_each { |article| article.update_column(:slug, article.title.parameterize) }
-    Research::Journal::Volume.where(slug: [nil, '']).find_each { |volume| volume.update_column(:slug, volume.title.parameterize) }
-
-    10.times do
-      Education::Program.find_each { |p| p.update_column :path, "#{p.parent&.path}/#{p.slug}".gsub(/\/+/, '/') }
-    end
-
-    Communication::Website::Post.find_each do |post|
-      post.categories = post.categories.select { |category| category.children.none? { |child| post.categories.include?(child) } }
-    end
-
-    Research::Journal::Article.where(position: nil).order(:published_at, :created_at).group_by(&:research_journal_volume_id).each do |_, articles|
-      articles.each_with_index do |article, index|
-        article.update_columns({
-          published: article.published_at.present?,
-          position: index + 1
-        })
-      end
-    end
-
-    # MICA & Class'Code
-    Communication::Website.where(id: ["6dfb358c-21bc-440f-9156-e09b72671c32", "1bb0f013-4d3d-49be-84bc-087c8cff3c77"]).each do |website|
-      website.imported_website.posts.find_each do |imported_post|
-        imported_post.post&.update_column :published_at, imported_post.published_at
-      end
+    [
+      "text", "biography", "accessibility", "contacts", "duration",
+      "evaluation", "objectives", "opportunities", "other", "pedagogy",
+      "prerequisites", "pricing", "registration", "content", "results"
+    ].each do |attribute|
+      ActiveStorage::Attachment.where(name: "#{attribute}_new_summernote_embeds").find_each { _1.update_column :name, "#{attribute}_summernote_embeds" }
     end
+  end
 
-    # Website structures
-    Communication::Website.all.each { |w| w.build_structure(university_id: w.university_id).save }
+  def clean_for_summernote(actiontext)
+    return '' if actiontext.nil?
+    actiontext.body
+              .to_html
+              .gsub('<div>', '<p>')
+              .gsub('</div>', '</p>')
+              .gsub('<strong>', '<b>')
+              .gsub('</strong>', '</b>')
+              .gsub('<em>', '<i>')
+              .gsub('</em>', '</i>')
+              .gsub('<p><br></p>', '')
   end
 
   namespace :db do
diff --git a/test/fixtures/communication/website.yml b/test/fixtures/communication/website.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5e9fc04572143c27e0ac3edf2cca2755f6bfe8f1
--- /dev/null
+++ b/test/fixtures/communication/website.yml
@@ -0,0 +1,3 @@
+test:
+  university: test
+  name: Site de test
diff --git a/test/fixtures/communication/website/github_files.yml b/test/fixtures/communication/website/github_files.yml
deleted file mode 100644
index f62b00bd44515d0bd25111210b6ec85cdedca846..0000000000000000000000000000000000000000
--- a/test/fixtures/communication/website/github_files.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-# == Schema Information
-#
-# Table name: communication_website_github_files
-#
-#  id                  :uuid             not null, primary key
-#  about_type          :string           not null
-#  github_path         :string
-#  manifest_identifier :string
-#  created_at          :datetime         not null
-#  updated_at          :datetime         not null
-#  about_id            :uuid             not null
-#  website_id          :uuid             not null
-#
-# Indexes
-#
-#  index_communication_website_github_files_on_about       (about_type,about_id)
-#  index_communication_website_github_files_on_website_id  (website_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (website_id => communication_websites.id)
-#
-
-one:
-  github_path: MyString
-  about: one
-
-two:
-  github_path: MyString
-  about: two
diff --git a/test/fixtures/communication/website/post.yml b/test/fixtures/communication/website/post.yml
new file mode 100644
index 0000000000000000000000000000000000000000..acb62a96a95f0fcedbffa49bef57dd388b1d0e8e
--- /dev/null
+++ b/test/fixtures/communication/website/post.yml
@@ -0,0 +1,5 @@
+test:
+  university: test
+  website: test
+  title: Test
+  slug: test
diff --git a/test/fixtures/education/program/members.yml b/test/fixtures/education/program/members.yml
deleted file mode 100644
index ddb1da3fb54bb6a9f75f56328c46965f9b3fc4de..0000000000000000000000000000000000000000
--- a/test/fixtures/education/program/members.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_members
-#
-#  id         :uuid             not null, primary key
-#  role       :string
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
-#  member_id  :uuid             not null
-#  program_id :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_members_on_member_id   (member_id)
-#  index_education_program_members_on_program_id  (program_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (member_id => university_people.id)
-#  fk_rails_...  (program_id => education_programs.id)
-#
-
-one:
-  role: MyString
-  member: one
-  program: one
-
-two:
-  role: MyString
-  member: two
-  program: two
diff --git a/test/fixtures/education/program/role/people.yml b/test/fixtures/education/program/role/people.yml
deleted file mode 100644
index 50a25e47a89ea4b3a4cda4a15f37db6331820438..0000000000000000000000000000000000000000
--- a/test/fixtures/education/program/role/people.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_role_people
-#
-#  id         :uuid             not null, primary key
-#  position   :integer
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
-#  person_id  :uuid             not null
-#  role_id    :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_role_people_on_person_id  (person_id)
-#  index_education_program_role_people_on_role_id    (role_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (person_id => university_people.id)
-#  fk_rails_...  (role_id => education_program_roles.id)
-#
-
-one:
-  position: 1
-  person: one
-  role: one
-
-two:
-  position: 1
-  person: two
-  role: two
diff --git a/test/fixtures/education/program/roles.yml b/test/fixtures/education/program/roles.yml
deleted file mode 100644
index cce31b11fc8609374f9656de9c9803efd0d48ec9..0000000000000000000000000000000000000000
--- a/test/fixtures/education/program/roles.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_roles
-#
-#  id            :uuid             not null, primary key
-#  position      :integer
-#  title         :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  program_id    :uuid             not null
-#  university_id :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_roles_on_program_id     (program_id)
-#  index_education_program_roles_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (program_id => education_programs.id)
-#  fk_rails_...  (university_id => universities.id)
-#
-
-one:
-  title: MyString
-  position: 1
-  program: one
-  university: one
-
-two:
-  title: MyString
-  position: 1
-  program: two
-  university: two
diff --git a/test/fixtures/education/program/teachers.yml b/test/fixtures/education/program/teachers.yml
deleted file mode 100644
index 1029c55daa2461be96d5eea5193efb06bea66597..0000000000000000000000000000000000000000
--- a/test/fixtures/education/program/teachers.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_teachers
-#
-#  id          :uuid             not null, primary key
-#  description :text
-#  created_at  :datetime         not null
-#  updated_at  :datetime         not null
-#  person_id   :uuid             not null
-#  program_id  :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_teachers_on_person_id   (person_id)
-#  index_education_program_teachers_on_program_id  (program_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (person_id => university_people.id)
-#  fk_rails_...  (program_id => education_programs.id)
-#
-
-one:
-  description: MyText
-  program: one
-  person: one
-
-two:
-  description: MyText
-  program: two
-  person: two
diff --git a/test/fixtures/education/school/administrators.yml b/test/fixtures/education/school/administrators.yml
deleted file mode 100644
index 2e5542621d8a3cb262c0eb722b87255fc495dc53..0000000000000000000000000000000000000000
--- a/test/fixtures/education/school/administrators.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-# == Schema Information
-#
-# Table name: education_school_administrators
-#
-#  id          :uuid             not null, primary key
-#  description :text
-#  created_at  :datetime         not null
-#  updated_at  :datetime         not null
-#  person_id   :uuid             not null
-#  school_id   :uuid             not null
-#
-# Indexes
-#
-#  index_education_school_administrators_on_person_id  (person_id)
-#  index_education_school_administrators_on_school_id  (school_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (person_id => university_people.id)
-#  fk_rails_...  (school_id => education_schools.id)
-#
-
-one:
-  description: MyText
-  school: one
-  person: one
-
-two:
-  description: MyText
-  school: two
-  person: two
diff --git a/test/fixtures/research/laboratories.yml b/test/fixtures/research/laboratories.yml
deleted file mode 100644
index 39a78ada0a853b429337db92bbbbdfb694263b61..0000000000000000000000000000000000000000
--- a/test/fixtures/research/laboratories.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-# == Schema Information
-#
-# Table name: research_laboratories
-#
-#  id            :uuid             not null, primary key
-#  address       :string
-#  city          :string
-#  country       :string
-#  name          :string
-#  zipcode       :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  university_id :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_research_laboratories_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_f61d27545f  (university_id => universities.id)
-#
-
-one:
-  university: one
-  name: MyString
-  address: MyString
-  zipcode: MyString
-  city: MyString
-  country: MyString
-
-two:
-  university: two
-  name: MyString
-  address: MyString
-  zipcode: MyString
-  city: MyString
-  country: MyString
diff --git a/test/fixtures/research/laboratory/axes.yml b/test/fixtures/research/laboratory/axes.yml
deleted file mode 100644
index 1ff6715cc3683b92cfac45e891a5d28d35047dec..0000000000000000000000000000000000000000
--- a/test/fixtures/research/laboratory/axes.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-# == Schema Information
-#
-# Table name: research_laboratory_axes
-#
-#  id                     :uuid             not null, primary key
-#  description            :text
-#  name                   :string
-#  position               :integer
-#  short_name             :string
-#  text_new               :text
-#  created_at             :datetime         not null
-#  updated_at             :datetime         not null
-#  research_laboratory_id :uuid             not null, indexed
-#  university_id          :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_research_laboratory_axes_on_research_laboratory_id  (research_laboratory_id)
-#  index_research_laboratory_axes_on_university_id           (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_ad2cb9a562  (research_laboratory_id => research_laboratories.id)
-#  fk_rails_d334f832b4  (university_id => universities.id)
-#
-
-one:
-  university: one
-  research_laboratory: one
-  name: MyString
-  description: MyText
-  position: 1
-
-two:
-  university: two
-  research_laboratory: two
-  name: MyString
-  description: MyText
-  position: 1
diff --git a/test/fixtures/research/theses.yml b/test/fixtures/research/theses.yml
deleted file mode 100644
index c7cd5783ba0e9d8cbe0ae07ef980725ad038a5d9..0000000000000000000000000000000000000000
--- a/test/fixtures/research/theses.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-# == Schema Information
-#
-# Table name: research_theses
-#
-#  id                     :uuid             not null, primary key
-#  abstract               :text
-#  completed              :boolean          default(FALSE)
-#  completed_at           :date
-#  started_at             :date
-#  title                  :string
-#  created_at             :datetime         not null
-#  updated_at             :datetime         not null
-#  author_id              :uuid             not null, indexed
-#  director_id            :uuid             not null, indexed
-#  research_laboratory_id :uuid             not null, indexed
-#  university_id          :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_research_theses_on_author_id               (author_id)
-#  index_research_theses_on_director_id             (director_id)
-#  index_research_theses_on_research_laboratory_id  (research_laboratory_id)
-#  index_research_theses_on_university_id           (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_1e42972d90  (author_id => university_people.id)
-#  fk_rails_44b431f9e5  (university_id => universities.id)
-#  fk_rails_8d223fdbaf  (director_id => university_people.id)
-#  fk_rails_b3380066dc  (research_laboratory_id => research_laboratories.id)
-#
-
-one:
-  university: one
-  research_laboratory: one
-  author: one
-  director: one
-  title: MyString
-  abstract: MyText
-  started_at: 2022-01-20
-  completed: false
-  completed_at: 2022-01-20
-
-two:
-  university: two
-  research_laboratory: two
-  author: two
-  director: two
-  title: MyString
-  abstract: MyText
-  started_at: 2022-01-20
-  completed: false
-  completed_at: 2022-01-20
diff --git a/test/fixtures/university.yml b/test/fixtures/university.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0ef3e762f353b857b6a82e0e390b29bbf8ad422a
--- /dev/null
+++ b/test/fixtures/university.yml
@@ -0,0 +1,2 @@
+test:
+  name: Université de test
diff --git a/test/fixtures/university/person/involvements.yml b/test/fixtures/university/person/involvements.yml
deleted file mode 100644
index 3673a2c923f39dd6b3ed8db53e4d4ef0cf68fe28..0000000000000000000000000000000000000000
--- a/test/fixtures/university/person/involvements.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-# == Schema Information
-#
-# Table name: university_person_involvements
-#
-#  id            :uuid             not null, primary key
-#  description   :text
-#  kind          :integer
-#  position      :integer
-#  target_type   :string           not null, indexed => [target_id]
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  person_id     :uuid             not null, indexed
-#  target_id     :uuid             not null, indexed => [target_type]
-#  university_id :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_university_person_involvements_on_person_id      (person_id)
-#  index_university_person_involvements_on_target         (target_type,target_id)
-#  index_university_person_involvements_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_407e2a671c  (person_id => university_people.id)
-#  fk_rails_5c704f6338  (university_id => universities.id)
-#
-
-one:
-  university: one
-  person: one
-  kind: 1
-  target: one
-  description: MyText
-  position: 1
-
-two:
-  university: two
-  person: two
-  kind: 1
-  target: two
-  description: MyText
-  position: 1
diff --git a/test/fixtures/university/roles.yml b/test/fixtures/university/roles.yml
deleted file mode 100644
index d3001160f12234a6ee6620ee1a383824724d2dcf..0000000000000000000000000000000000000000
--- a/test/fixtures/university/roles.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-# == Schema Information
-#
-# Table name: university_roles
-#
-#  id            :uuid             not null, primary key
-#  description   :text
-#  position      :integer
-#  target_type   :string           indexed => [target_id]
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  target_id     :uuid             indexed => [target_type]
-#  university_id :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_university_roles_on_target         (target_type,target_id)
-#  index_university_roles_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_8e52293a38  (university_id => universities.id)
-#
-
-one:
-  university: one
-  target: one
-  description: MyText
-  position: 1
-
-two:
-  university: two
-  target: two
-  description: MyText
-  position: 1
diff --git a/test/integration/summernote_test.rb b/test/integration/summernote_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..43cef8518107b3fda71fbb281c2114fd5cbc0122
--- /dev/null
+++ b/test/integration/summernote_test.rb
@@ -0,0 +1,22 @@
+require "test_helper"
+
+class SummernoteTest < ActiveSupport::TestCase
+  HTML_HYDRATED = "<action-text-attachment sgid=\"sgid\" content-type=\"image/jpeg\" url=\"http://localhost:3000/dan-gold.jpeg\" filename=\"test.jpg\" filesize=\"352931\" width=\"588\" height=\"746\" previewable=\"true\" presentation=\"gallery\"><figure class=\"attachment attachment--preview\">\n  <img width=\"588\" height=\"746\" src=\"http://localhost:3000/dan-gold.jpeg\">\n</figure></action-text-attachment>\n"
+  HTML_DEHYDRATED = "<action-text-attachment sgid=\"sgid\" content-type=\"image/jpeg\" url=\"http://localhost:3000/dan-gold.jpeg\" filename=\"test.jpg\" filesize=\"352931\" width=\"588\" height=\"746\" previewable=\"true\" presentation=\"gallery\"></action-text-attachment>"
+
+  test "dehydrate actiontext" do
+    post = communication_website_post(:test)
+    post.text_new = HTML_HYDRATED
+    post.save
+    post.reload
+    assert_equal HTML_DEHYDRATED, post.text_new_before_type_cast
+  end
+
+  test "rehydrate actiontext" do
+    post = communication_website_post(:test)
+    post.text_new = HTML_DEHYDRATED
+    post.save
+    post.reload
+    assert_equal HTML_HYDRATED, communication_website_post(:test).text_new.to_s
+  end
+ end
diff --git a/test/models/variant_service_test.rb b/test/integration/variant_service_test.rb
similarity index 100%
rename from test/models/variant_service_test.rb
rename to test/integration/variant_service_test.rb
diff --git a/test/models/wordpress_test.rb b/test/integration/wordpress_test.rb
similarity index 100%
rename from test/models/wordpress_test.rb
rename to test/integration/wordpress_test.rb
diff --git a/test/models/.keep b/test/models/.keep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/test/models/communication/website/github_file_test.rb b/test/models/communication/website/github_file_test.rb
deleted file mode 100644
index 72374f59d14999ee55f3516ed13be3eefa558f26..0000000000000000000000000000000000000000
--- a/test/models/communication/website/github_file_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# == Schema Information
-#
-# Table name: communication_website_github_files
-#
-#  id                  :uuid             not null, primary key
-#  about_type          :string           not null
-#  github_path         :string
-#  manifest_identifier :string
-#  created_at          :datetime         not null
-#  updated_at          :datetime         not null
-#  about_id            :uuid             not null
-#  website_id          :uuid             not null
-#
-# Indexes
-#
-#  index_communication_website_github_files_on_about       (about_type,about_id)
-#  index_communication_website_github_files_on_website_id  (website_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (website_id => communication_websites.id)
-#
-require "test_helper"
-
-class Communication::Website::GithubFileTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/education/program/member_test.rb b/test/models/education/program/member_test.rb
deleted file mode 100644
index 824cc97edbb20e766f3a0e310082b2d315322535..0000000000000000000000000000000000000000
--- a/test/models/education/program/member_test.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_members
-#
-#  id         :uuid             not null, primary key
-#  role       :string
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
-#  member_id  :uuid             not null
-#  program_id :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_members_on_member_id   (member_id)
-#  index_education_program_members_on_program_id  (program_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (member_id => university_people.id)
-#  fk_rails_...  (program_id => education_programs.id)
-#
-require "test_helper"
-
-class Education::Program::MemberTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/education/program/role/person_test.rb b/test/models/education/program/role/person_test.rb
deleted file mode 100644
index a257dd899084f03b9b60d8a932b174c47621aed8..0000000000000000000000000000000000000000
--- a/test/models/education/program/role/person_test.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_role_people
-#
-#  id         :uuid             not null, primary key
-#  position   :integer
-#  created_at :datetime         not null
-#  updated_at :datetime         not null
-#  person_id  :uuid             not null
-#  role_id    :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_role_people_on_person_id  (person_id)
-#  index_education_program_role_people_on_role_id    (role_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (person_id => university_people.id)
-#  fk_rails_...  (role_id => education_program_roles.id)
-#
-require "test_helper"
-
-class Education::Program::Role::PersonTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/education/program/role_test.rb b/test/models/education/program/role_test.rb
deleted file mode 100644
index 2b9d81195b5c96bec871bf57ea9e4b6caab9b05a..0000000000000000000000000000000000000000
--- a/test/models/education/program/role_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_roles
-#
-#  id            :uuid             not null, primary key
-#  position      :integer
-#  title         :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  program_id    :uuid             not null
-#  university_id :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_roles_on_program_id     (program_id)
-#  index_education_program_roles_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (program_id => education_programs.id)
-#  fk_rails_...  (university_id => universities.id)
-#
-require "test_helper"
-
-class Education::Program::RoleTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/education/program/teacher_test.rb b/test/models/education/program/teacher_test.rb
deleted file mode 100644
index 7806b4fcbda0ece1feda5af3d5b0edbfd585e95d..0000000000000000000000000000000000000000
--- a/test/models/education/program/teacher_test.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# == Schema Information
-#
-# Table name: education_program_teachers
-#
-#  id          :uuid             not null, primary key
-#  description :text
-#  created_at  :datetime         not null
-#  updated_at  :datetime         not null
-#  person_id   :uuid             not null
-#  program_id  :uuid             not null
-#
-# Indexes
-#
-#  index_education_program_teachers_on_person_id   (person_id)
-#  index_education_program_teachers_on_program_id  (program_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (person_id => university_people.id)
-#  fk_rails_...  (program_id => education_programs.id)
-#
-require "test_helper"
-
-class Education::Program::TeacherTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/education/school/administrator_test.rb b/test/models/education/school/administrator_test.rb
deleted file mode 100644
index bdf223d6db7b2ae4bf2e3898d934c14310cc7024..0000000000000000000000000000000000000000
--- a/test/models/education/school/administrator_test.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# == Schema Information
-#
-# Table name: education_school_administrators
-#
-#  id          :uuid             not null, primary key
-#  description :text
-#  created_at  :datetime         not null
-#  updated_at  :datetime         not null
-#  person_id   :uuid             not null
-#  school_id   :uuid             not null
-#
-# Indexes
-#
-#  index_education_school_administrators_on_person_id  (person_id)
-#  index_education_school_administrators_on_school_id  (school_id)
-#
-# Foreign Keys
-#
-#  fk_rails_...  (person_id => university_people.id)
-#  fk_rails_...  (school_id => education_schools.id)
-#
-require "test_helper"
-
-class Education::School::AdministratorTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/research/laboratory/axis_test.rb b/test/models/research/laboratory/axis_test.rb
deleted file mode 100644
index 0ed57cec560d0ee30ea592ce89f14472526cc58b..0000000000000000000000000000000000000000
--- a/test/models/research/laboratory/axis_test.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# == Schema Information
-#
-# Table name: research_laboratory_axes
-#
-#  id                     :uuid             not null, primary key
-#  description            :text
-#  name                   :string
-#  position               :integer
-#  short_name             :string
-#  text_new               :text
-#  created_at             :datetime         not null
-#  updated_at             :datetime         not null
-#  research_laboratory_id :uuid             not null, indexed
-#  university_id          :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_research_laboratory_axes_on_research_laboratory_id  (research_laboratory_id)
-#  index_research_laboratory_axes_on_university_id           (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_ad2cb9a562  (research_laboratory_id => research_laboratories.id)
-#  fk_rails_d334f832b4  (university_id => universities.id)
-#
-require "test_helper"
-
-class Research::Laboratory::AxisTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/research/laboratory_test.rb b/test/models/research/laboratory_test.rb
deleted file mode 100644
index 54066f43146b3719162356c70762fcc8097ba425..0000000000000000000000000000000000000000
--- a/test/models/research/laboratory_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# == Schema Information
-#
-# Table name: research_laboratories
-#
-#  id            :uuid             not null, primary key
-#  address       :string
-#  city          :string
-#  country       :string
-#  name          :string
-#  zipcode       :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  university_id :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_research_laboratories_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_f61d27545f  (university_id => universities.id)
-#
-require "test_helper"
-
-class Research::LaboratoryTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/research/thesis_test.rb b/test/models/research/thesis_test.rb
deleted file mode 100644
index 436839fedd2f1528ba703a6eb56d29623fc40199..0000000000000000000000000000000000000000
--- a/test/models/research/thesis_test.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# == Schema Information
-#
-# Table name: research_theses
-#
-#  id                     :uuid             not null, primary key
-#  abstract               :text
-#  completed              :boolean          default(FALSE)
-#  completed_at           :date
-#  started_at             :date
-#  title                  :string
-#  created_at             :datetime         not null
-#  updated_at             :datetime         not null
-#  author_id              :uuid             not null, indexed
-#  director_id            :uuid             not null, indexed
-#  research_laboratory_id :uuid             not null, indexed
-#  university_id          :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_research_theses_on_author_id               (author_id)
-#  index_research_theses_on_director_id             (director_id)
-#  index_research_theses_on_research_laboratory_id  (research_laboratory_id)
-#  index_research_theses_on_university_id           (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_1e42972d90  (author_id => university_people.id)
-#  fk_rails_44b431f9e5  (university_id => universities.id)
-#  fk_rails_8d223fdbaf  (director_id => university_people.id)
-#  fk_rails_b3380066dc  (research_laboratory_id => research_laboratories.id)
-#
-require "test_helper"
-
-class Research::ThesisTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/university/person/involvement_test.rb b/test/models/university/person/involvement_test.rb
deleted file mode 100644
index 90ea6f5dac2f126bdf3dd2a8b51c3d1637ae0f82..0000000000000000000000000000000000000000
--- a/test/models/university/person/involvement_test.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# == Schema Information
-#
-# Table name: university_person_involvements
-#
-#  id            :uuid             not null, primary key
-#  description   :text
-#  kind          :integer
-#  position      :integer
-#  target_type   :string           not null, indexed => [target_id]
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  person_id     :uuid             not null, indexed
-#  target_id     :uuid             not null, indexed => [target_type]
-#  university_id :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_university_person_involvements_on_person_id      (person_id)
-#  index_university_person_involvements_on_target         (target_type,target_id)
-#  index_university_person_involvements_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_407e2a671c  (person_id => university_people.id)
-#  fk_rails_5c704f6338  (university_id => universities.id)
-#
-require "test_helper"
-
-class University::Person::InvolvementTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/models/university/role_test.rb b/test/models/university/role_test.rb
deleted file mode 100644
index a0c47a9a421e1b609cf3d72ec012a3b18dc51ea5..0000000000000000000000000000000000000000
--- a/test/models/university/role_test.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# == Schema Information
-#
-# Table name: university_roles
-#
-#  id            :uuid             not null, primary key
-#  description   :text
-#  position      :integer
-#  target_type   :string           indexed => [target_id]
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  target_id     :uuid             indexed => [target_type]
-#  university_id :uuid             not null, indexed
-#
-# Indexes
-#
-#  index_university_roles_on_target         (target_type,target_id)
-#  index_university_roles_on_university_id  (university_id)
-#
-# Foreign Keys
-#
-#  fk_rails_8e52293a38  (university_id => universities.id)
-#
-require "test_helper"
-
-class University::RoleTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
-end
diff --git a/test/system/communication/website/pages_test.rb b/test/system/communication/website/pages_test.rb
deleted file mode 100644
index 8d302d5a5e0a47023c138301bef9dab9afd70173..0000000000000000000000000000000000000000
--- a/test/system/communication/website/pages_test.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require "application_system_test_case"
-
-class Communication::Website::PagesTest < ApplicationSystemTestCase
-  setup do
-    @communication_website_page = communication_website_pages(:one)
-  end
-
-  test "visiting the index" do
-    visit communication_website_pages_url
-    assert_selector "h1", text: "Communication/Website/Pages"
-  end
-
-  test "creating a Page" do
-    visit communication_website_pages_url
-    click_on "New Communication/Website/Page"
-
-    fill_in "About", with: @communication_website_page.about_id
-    fill_in "Communication website", with: @communication_website_page.communication_website_id
-    fill_in "Description", with: @communication_website_page.description
-    fill_in "Kind", with: @communication_website_page.kind
-    fill_in "Title", with: @communication_website_page.title
-    fill_in "University", with: @communication_website_page.university_id
-    click_on "Create Page"
-
-    assert_text "Page was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Page" do
-    visit communication_website_pages_url
-    click_on "Edit", match: :first
-
-    fill_in "About", with: @communication_website_page.about_id
-    fill_in "Communication website", with: @communication_website_page.communication_website_id
-    fill_in "Description", with: @communication_website_page.description
-    fill_in "Kind", with: @communication_website_page.kind
-    fill_in "Title", with: @communication_website_page.title
-    fill_in "University", with: @communication_website_page.university_id
-    click_on "Update Page"
-
-    assert_text "Page was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Page" do
-    visit communication_website_pages_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Page was successfully destroyed"
-  end
-end
diff --git a/test/system/communication/website/posts_test.rb b/test/system/communication/website/posts_test.rb
deleted file mode 100644
index cbd0d35c7b3491e166337ec2e0e6e0a7dabfbebf..0000000000000000000000000000000000000000
--- a/test/system/communication/website/posts_test.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-require "application_system_test_case"
-
-class Communication::Website::PostsTest < ApplicationSystemTestCase
-  setup do
-    @communication_website_post = communication_website_posts(:one)
-  end
-
-  test "visiting the index" do
-    visit communication_website_posts_url
-    assert_selector "h1", text: "Communication/Website/Posts"
-  end
-
-  test "creating a Post" do
-    visit communication_website_posts_url
-    click_on "New Communication/Website/Post"
-
-    fill_in "Description", with: @communication_website_post.description
-    fill_in "Published", with: @communication_website_post.published
-    fill_in "Published at", with: @communication_website_post.published_at
-    fill_in "Text", with: @communication_website_post.text
-    fill_in "Title", with: @communication_website_post.title
-    fill_in "University", with: @communication_website_post.university_id
-    fill_in "Website", with: @communication_website_post.website_id
-    click_on "Create Post"
-
-    assert_text "Post was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Post" do
-    visit communication_website_posts_url
-    click_on "Edit", match: :first
-
-    fill_in "Description", with: @communication_website_post.description
-    fill_in "Published", with: @communication_website_post.published
-    fill_in "Published at", with: @communication_website_post.published_at
-    fill_in "Text", with: @communication_website_post.text
-    fill_in "Title", with: @communication_website_post.title
-    fill_in "University", with: @communication_website_post.university_id
-    fill_in "Website", with: @communication_website_post.website_id
-    click_on "Update Post"
-
-    assert_text "Post was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Post" do
-    visit communication_website_posts_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Post was successfully destroyed"
-  end
-end
diff --git a/test/system/features/websites/sites_test.rb b/test/system/features/websites/sites_test.rb
deleted file mode 100644
index b6e665bad81430226382a7aec8ff8324beb25f1a..0000000000000000000000000000000000000000
--- a/test/system/features/websites/sites_test.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require "application_system_test_case"
-
-class Features::Websites::SitesTest < ApplicationSystemTestCase
-  setup do
-    @features_websites_site = features_websites_sites(:one)
-  end
-
-  test "visiting the index" do
-    visit features_websites_sites_url
-    assert_selector "h1", text: "Features/Websites/Sites"
-  end
-
-  test "creating a Site" do
-    visit features_websites_sites_url
-    click_on "New Features/Websites/Site"
-
-    fill_in "Domain", with: @features_websites_site.domain
-    fill_in "Name", with: @features_websites_site.name
-    click_on "Create Site"
-
-    assert_text "Site was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Site" do
-    visit features_websites_sites_url
-    click_on "Edit", match: :first
-
-    fill_in "Domain", with: @features_websites_site.domain
-    fill_in "Name", with: @features_websites_site.name
-    click_on "Update Site"
-
-    assert_text "Site was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Site" do
-    visit features_websites_sites_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Site was successfully destroyed"
-  end
-end
diff --git a/test/system/languages_test.rb b/test/system/languages_test.rb
deleted file mode 100644
index b5d0360f238a800d57fc746952a7fb03f40e7918..0000000000000000000000000000000000000000
--- a/test/system/languages_test.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require "application_system_test_case"
-
-class LanguagesTest < ApplicationSystemTestCase
-  setup do
-    @language = languages(:one)
-  end
-
-  test "visiting the index" do
-    visit languages_url
-    assert_selector "h1", text: "Languages"
-  end
-
-  test "creating a Language" do
-    visit languages_url
-    click_on "New Language"
-
-    fill_in "Iso code", with: @language.iso_code
-    fill_in "Name", with: @language.name
-    click_on "Create Language"
-
-    assert_text "Language was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Language" do
-    visit languages_url
-    click_on "Edit", match: :first
-
-    fill_in "Iso code", with: @language.iso_code
-    fill_in "Name", with: @language.name
-    click_on "Update Language"
-
-    assert_text "Language was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Language" do
-    visit languages_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Language was successfully destroyed"
-  end
-end
diff --git a/test/system/programs_test.rb b/test/system/programs_test.rb
deleted file mode 100644
index 13b7a3193690992ab098b2696b4ac16715cafb08..0000000000000000000000000000000000000000
--- a/test/system/programs_test.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require "application_system_test_case"
-
-class ProgramsTest < ApplicationSystemTestCase
-  setup do
-    @program = programs(:one)
-  end
-
-  test "visiting the index" do
-    visit programs_url
-    assert_selector "h1", text: "Programs"
-  end
-
-  test "creating a Program" do
-    visit programs_url
-    click_on "New Program"
-
-    fill_in "Accessibility", with: @program.accessibility
-    fill_in "Capacity", with: @program.capacity
-    check "Continuing" if @program.continuing
-    fill_in "Duration", with: @program.duration
-    fill_in "Ects", with: @program.ects
-    fill_in "Evaluation", with: @program.evaluation
-    fill_in "Level", with: @program.level
-    fill_in "Name", with: @program.name
-    fill_in "Objectives", with: @program.objectives
-    fill_in "Pedagogy", with: @program.pedagogy
-    fill_in "Prerequisites", with: @program.prerequisites
-    fill_in "Registration", with: @program.registration
-    fill_in "University", with: @program.university_id
-    click_on "Create Program"
-
-    assert_text "Program was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Program" do
-    visit programs_url
-    click_on "Edit", match: :first
-
-    fill_in "Accessibility", with: @program.accessibility
-    fill_in "Capacity", with: @program.capacity
-    check "Continuing" if @program.continuing
-    fill_in "Duration", with: @program.duration
-    fill_in "Ects", with: @program.ects
-    fill_in "Evaluation", with: @program.evaluation
-    fill_in "Level", with: @program.level
-    fill_in "Name", with: @program.name
-    fill_in "Objectives", with: @program.objectives
-    fill_in "Pedagogy", with: @program.pedagogy
-    fill_in "Prerequisites", with: @program.prerequisites
-    fill_in "Registration", with: @program.registration
-    fill_in "University", with: @program.university_id
-    click_on "Update Program"
-
-    assert_text "Program was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Program" do
-    visit programs_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Program was successfully destroyed"
-  end
-end
diff --git a/test/system/qualiopi/criterions_test.rb b/test/system/qualiopi/criterions_test.rb
deleted file mode 100644
index 9185df996ca9ceba2957833f3d96549b77d323b9..0000000000000000000000000000000000000000
--- a/test/system/qualiopi/criterions_test.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require "application_system_test_case"
-
-class Qualiopi::CriterionsTest < ApplicationSystemTestCase
-  setup do
-    @qualiopi_criterion = qualiopi_criterions(:one)
-  end
-
-  test "visiting the index" do
-    visit qualiopi_criterions_url
-    assert_selector "h1", text: "Qualiopi/Criterions"
-  end
-
-  test "creating a Criterion" do
-    visit qualiopi_criterions_url
-    click_on "New Qualiopi/Criterion"
-
-    fill_in "Description", with: @qualiopi_criterion.description
-    fill_in "Name", with: @qualiopi_criterion.name
-    fill_in "Number", with: @qualiopi_criterion.number
-    click_on "Create Criterion"
-
-    assert_text "Criterion was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Criterion" do
-    visit qualiopi_criterions_url
-    click_on "Edit", match: :first
-
-    fill_in "Description", with: @qualiopi_criterion.description
-    fill_in "Name", with: @qualiopi_criterion.name
-    fill_in "Number", with: @qualiopi_criterion.number
-    click_on "Update Criterion"
-
-    assert_text "Criterion was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Criterion" do
-    visit qualiopi_criterions_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Criterion was successfully destroyed"
-  end
-end
diff --git a/test/system/qualiopi/indicators_test.rb b/test/system/qualiopi/indicators_test.rb
deleted file mode 100644
index 08133e726a769cc8dfd8c2bc24c7978fc40d4ee2..0000000000000000000000000000000000000000
--- a/test/system/qualiopi/indicators_test.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-require "application_system_test_case"
-
-class Qualiopi::IndicatorsTest < ApplicationSystemTestCase
-  setup do
-    @qualiopi_indicator = qualiopi_indicators(:one)
-  end
-
-  test "visiting the index" do
-    visit qualiopi_indicators_url
-    assert_selector "h1", text: "Qualiopi/Indicators"
-  end
-
-  test "creating a Indicator" do
-    visit qualiopi_indicators_url
-    click_on "New Qualiopi/Indicator"
-
-    fill_in "Criterion", with: @qualiopi_indicator.criterion_id
-    fill_in "Level expected", with: @qualiopi_indicator.level_expected
-    fill_in "Name", with: @qualiopi_indicator.name
-    fill_in "Non conformity", with: @qualiopi_indicator.non_conformity
-    fill_in "Number", with: @qualiopi_indicator.number
-    fill_in "Proof", with: @qualiopi_indicator.proof
-    fill_in "Requirement", with: @qualiopi_indicator.requirement
-    click_on "Create Indicator"
-
-    assert_text "Indicator was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Indicator" do
-    visit qualiopi_indicators_url
-    click_on "Edit", match: :first
-
-    fill_in "Criterion", with: @qualiopi_indicator.criterion_id
-    fill_in "Level expected", with: @qualiopi_indicator.level_expected
-    fill_in "Name", with: @qualiopi_indicator.name
-    fill_in "Non conformity", with: @qualiopi_indicator.non_conformity
-    fill_in "Number", with: @qualiopi_indicator.number
-    fill_in "Proof", with: @qualiopi_indicator.proof
-    fill_in "Requirement", with: @qualiopi_indicator.requirement
-    click_on "Update Indicator"
-
-    assert_text "Indicator was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Indicator" do
-    visit qualiopi_indicators_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Indicator was successfully destroyed"
-  end
-end
diff --git a/test/system/research/journal/articles_test.rb b/test/system/research/journal/articles_test.rb
deleted file mode 100644
index f3ec7b46e2abced666eae18e482b09225f85dece..0000000000000000000000000000000000000000
--- a/test/system/research/journal/articles_test.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require "application_system_test_case"
-
-class Research::Journal::ArticlesTest < ApplicationSystemTestCase
-  setup do
-    @research_journal_article = research_journal_articles(:one)
-  end
-
-  test "visiting the index" do
-    visit research_journal_articles_url
-    assert_selector "h1", text: "Research/Journal/Articles"
-  end
-
-  test "creating a Article" do
-    visit research_journal_articles_url
-    click_on "New Research/Journal/Article"
-
-    fill_in "Published at", with: @research_journal_article.published_at
-    fill_in "Research journal", with: @research_journal_article.research_journal_id
-    fill_in "Research journal volume", with: @research_journal_article.research_journal_volume_id
-    fill_in "Text", with: @research_journal_article.text
-    fill_in "Title", with: @research_journal_article.title
-    fill_in "University", with: @research_journal_article.university_id
-    click_on "Create Article"
-
-    assert_text "Article was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Article" do
-    visit research_journal_articles_url
-    click_on "Edit", match: :first
-
-    fill_in "Published at", with: @research_journal_article.published_at
-    fill_in "Research journal", with: @research_journal_article.research_journal_id
-    fill_in "Research journal volume", with: @research_journal_article.research_journal_volume_id
-    fill_in "Text", with: @research_journal_article.text
-    fill_in "Title", with: @research_journal_article.title
-    fill_in "University", with: @research_journal_article.university_id
-    click_on "Update Article"
-
-    assert_text "Article was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Article" do
-    visit research_journal_articles_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Article was successfully destroyed"
-  end
-end
diff --git a/test/system/research/journal/volumes_test.rb b/test/system/research/journal/volumes_test.rb
deleted file mode 100644
index 85d50549bc7d167f5808982131598f255d31608b..0000000000000000000000000000000000000000
--- a/test/system/research/journal/volumes_test.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require "application_system_test_case"
-
-class Research::Journal::VolumesTest < ApplicationSystemTestCase
-  setup do
-    @research_journal_volume = research_journal_volumes(:one)
-  end
-
-  test "visiting the index" do
-    visit research_journal_volumes_url
-    assert_selector "h1", text: "Research/Journal/Volumes"
-  end
-
-  test "creating a Volume" do
-    visit research_journal_volumes_url
-    click_on "New Research/Journal/Volume"
-
-    fill_in "Number", with: @research_journal_volume.number
-    fill_in "Published at", with: @research_journal_volume.published_at
-    fill_in "Title", with: @research_journal_volume.title
-    click_on "Create Volume"
-
-    assert_text "Volume was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Volume" do
-    visit research_journal_volumes_url
-    click_on "Edit", match: :first
-
-    fill_in "Number", with: @research_journal_volume.number
-    fill_in "Published at", with: @research_journal_volume.published_at
-    fill_in "Title", with: @research_journal_volume.title
-    click_on "Update Volume"
-
-    assert_text "Volume was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Volume" do
-    visit research_journal_volumes_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Volume was successfully destroyed"
-  end
-end
diff --git a/test/system/research/journals_test.rb b/test/system/research/journals_test.rb
deleted file mode 100644
index 3c83334e62fc4c8dd7216d7c634a5b1e8a584457..0000000000000000000000000000000000000000
--- a/test/system/research/journals_test.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require "application_system_test_case"
-
-class Research::JournalsTest < ApplicationSystemTestCase
-  setup do
-    @research_journal = research_journals(:one)
-  end
-
-  test "visiting the index" do
-    visit research_journals_url
-    assert_selector "h1", text: "Research/Journals"
-  end
-
-  test "creating a Journal" do
-    visit research_journals_url
-    click_on "New Research/Journal"
-
-    fill_in "Description", with: @research_journal.description
-    fill_in "Title", with: @research_journal.title
-    click_on "Create Journal"
-
-    assert_text "Journal was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Journal" do
-    visit research_journals_url
-    click_on "Edit", match: :first
-
-    fill_in "Description", with: @research_journal.description
-    fill_in "Title", with: @research_journal.title
-    click_on "Update Journal"
-
-    assert_text "Journal was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Journal" do
-    visit research_journals_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Journal was successfully destroyed"
-  end
-end
diff --git a/test/system/research/researchers_test.rb b/test/system/research/researchers_test.rb
deleted file mode 100644
index f31cb48aa1271486b207056e872e28628e5be66f..0000000000000000000000000000000000000000
--- a/test/system/research/researchers_test.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require "application_system_test_case"
-
-class Research::ResearchersTest < ApplicationSystemTestCase
-  setup do
-    @research_researcher = research_researchers(:one)
-  end
-
-  test "visiting the index" do
-    visit research_researchers_url
-    assert_selector "h1", text: "Research/Researchers"
-  end
-
-  test "creating a Researcher" do
-    visit research_researchers_url
-    click_on "New Research/Researcher"
-
-    fill_in "Biography", with: @research_researcher.biography
-    fill_in "First name", with: @research_researcher.first_name
-    fill_in "Last name", with: @research_researcher.last_name
-    fill_in "User", with: @research_researcher.user_id
-    click_on "Create Researcher"
-
-    assert_text "Researcher was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a Researcher" do
-    visit research_researchers_url
-    click_on "Edit", match: :first
-
-    fill_in "Biography", with: @research_researcher.biography
-    fill_in "First name", with: @research_researcher.first_name
-    fill_in "Last name", with: @research_researcher.last_name
-    fill_in "User", with: @research_researcher.user_id
-    click_on "Update Researcher"
-
-    assert_text "Researcher was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a Researcher" do
-    visit research_researchers_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "Researcher was successfully destroyed"
-  end
-end
diff --git a/test/system/universities_test.rb b/test/system/universities_test.rb
deleted file mode 100644
index bc8e1af7929d70b46bdc6b07734dbbb2d964c0c4..0000000000000000000000000000000000000000
--- a/test/system/universities_test.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require "application_system_test_case"
-
-class UniversitiesTest < ApplicationSystemTestCase
-  setup do
-    @university = universities(:one)
-  end
-
-  test "visiting the index" do
-    visit universities_url
-    assert_selector "h1", text: "Universities"
-  end
-
-  test "creating a University" do
-    visit universities_url
-    click_on "New University"
-
-    fill_in "Address", with: @university.address
-    fill_in "City", with: @university.city
-    fill_in "Country", with: @university.country
-    fill_in "Name", with: @university.name
-    check "Private" if @university.private
-    fill_in "Zipcode", with: @university.zipcode
-    click_on "Create University"
-
-    assert_text "University was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a University" do
-    visit universities_url
-    click_on "Edit", match: :first
-
-    fill_in "Address", with: @university.address
-    fill_in "City", with: @university.city
-    fill_in "Country", with: @university.country
-    fill_in "Name", with: @university.name
-    check "Private" if @university.private
-    fill_in "Zipcode", with: @university.zipcode
-    click_on "Update University"
-
-    assert_text "University was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a University" do
-    visit universities_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "University was successfully destroyed"
-  end
-end
diff --git a/test/system/university/schools_test.rb b/test/system/university/schools_test.rb
deleted file mode 100644
index 3055e119d1ed67d5ef2008ac5d96f69da11d84a9..0000000000000000000000000000000000000000
--- a/test/system/university/schools_test.rb
+++ /dev/null
@@ -1,57 +0,0 @@
-require "application_system_test_case"
-
-class University::SchoolsTest < ApplicationSystemTestCase
-  setup do
-    @university_school = university_schools(:one)
-  end
-
-  test "visiting the index" do
-    visit university_schools_url
-    assert_selector "h1", text: "University/Schools"
-  end
-
-  test "creating a School" do
-    visit university_schools_url
-    click_on "New University/School"
-
-    fill_in "Address", with: @university_school.address
-    fill_in "City", with: @university_school.city
-    fill_in "Country", with: @university_school.country
-    fill_in "Latitude", with: @university_school.latitude
-    fill_in "Longitude", with: @university_school.longitude
-    fill_in "Name", with: @university_school.name
-    fill_in "University", with: @university_school.university_id
-    fill_in "Zipcode", with: @university_school.zipcode
-    click_on "Create School"
-
-    assert_text "School was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a School" do
-    visit university_schools_url
-    click_on "Edit", match: :first
-
-    fill_in "Address", with: @university_school.address
-    fill_in "City", with: @university_school.city
-    fill_in "Country", with: @university_school.country
-    fill_in "Latitude", with: @university_school.latitude
-    fill_in "Longitude", with: @university_school.longitude
-    fill_in "Name", with: @university_school.name
-    fill_in "University", with: @university_school.university_id
-    fill_in "Zipcode", with: @university_school.zipcode
-    click_on "Update School"
-
-    assert_text "School was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a School" do
-    visit university_schools_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "School was successfully destroyed"
-  end
-end
diff --git a/test/system/users_test.rb b/test/system/users_test.rb
deleted file mode 100644
index 06f7377f621b4477ad231a08d7ee271bfb55e520..0000000000000000000000000000000000000000
--- a/test/system/users_test.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require "application_system_test_case"
-
-class UsersTest < ApplicationSystemTestCase
-  setup do
-    @user = users(:one)
-  end
-
-  test "visiting the index" do
-    visit users_url
-    assert_selector "h1", text: "Users"
-  end
-
-  test "creating a User" do
-    visit users_url
-    click_on "New User"
-
-    fill_in "First name", with: @user.first_name
-    fill_in "Last name", with: @user.last_name
-    fill_in "Role", with: @user.role
-    click_on "Create User"
-
-    assert_text "User was successfully created"
-    click_on "Back"
-  end
-
-  test "updating a User" do
-    visit users_url
-    click_on "Edit", match: :first
-
-    fill_in "First name", with: @user.first_name
-    fill_in "Last name", with: @user.last_name
-    fill_in "Role", with: @user.role
-    click_on "Update User"
-
-    assert_text "User was successfully updated"
-    click_on "Back"
-  end
-
-  test "destroying a User" do
-    visit users_url
-    page.accept_confirm do
-      click_on "Destroy", match: :first
-    end
-
-    assert_text "User was successfully destroyed"
-  end
-end