diff --git a/app/assets/javascripts/admin/appstack.js b/app/assets/javascripts/admin/appstack.js
index aa96e4785e2122a1d5a8f8f4f5c96192ec2041f6..288469caaf16052c44adc410d92efad1a25c718e 100644
--- a/app/assets/javascripts/admin/appstack.js
+++ b/app/assets/javascripts/admin/appstack.js
@@ -12,6 +12,7 @@
 //= require summernote/summernote-bs5
 //= require slug/slug
 //= require cocoon
+//= require codemirror/lib/codemirror
 //= require_self
 //= require_tree ./commons
 //= require_tree ../application/plugins
diff --git a/app/assets/javascripts/admin/plugins/codemirror.js b/app/assets/javascripts/admin/plugins/codemirror.js
new file mode 100644
index 0000000000000000000000000000000000000000..553e9afd748b24c9bf3dee73f9bd49c39d0b5d11
--- /dev/null
+++ b/app/assets/javascripts/admin/plugins/codemirror.js
@@ -0,0 +1,53 @@
+//= require codemirror/mode/xml/xml
+//= require codemirror/mode/javascript/javascript
+//= require codemirror/mode/css/css
+//= require codemirror/mode/htmlmixed/htmlmixed
+//= require codemirror/mode/sass/sass
+
+/*global CodeMirror */
+
+// Add [data-provider="codemirror"] to textarea.
+// You need to set [data-codemirror-mode="<language>"] to set the language.
+// You can use set [data-codemirror-indentation="n"] to set the indentation level (2 by default).
+window.codemirrorManager = {
+    init: function () {
+        'use strict';
+        var i;
+        this.textareas = document.querySelectorAll('textarea[data-provider="codemirror"]');
+        this.instances = [];
+        for (i = 0; i < this.textareas.length; i += 1) {
+            this.instances.push(this.createInstance(this.textareas[i]));
+        }
+    },
+
+    createInstance: function (textarea) {
+        'use strict';
+        var mode = textarea.getAttribute('data-codemirror-mode'),
+            indentationLevel = window.parseInt(textarea.getAttribute('data-codemirror-indentation'));
+
+        if (isNaN(indentationLevel)) {
+            indentationLevel = 2;
+        }
+
+        return CodeMirror.fromTextArea(textarea, {
+            lineNumbers: true,
+            matchBrackets: true,
+            styleActiveLine: true,
+            indentUnit: indentationLevel,
+            viewportMargin: Infinity,
+            mode: mode
+        });
+    },
+
+    invoke: function () {
+        'use strict';
+        return {
+            init: this.init.bind(this)
+        };
+    }
+}.invoke();
+
+window.addEventListener('DOMContentLoaded', function () {
+    'use strict';
+    window.codemirrorManager.init();
+});
diff --git a/app/assets/javascripts/admin/pure.js b/app/assets/javascripts/admin/pure.js
index ce84c279a86652825ff124a99876d8cf2f5339c1..94017fb5f5845850521b0e158949325b6794e6f7 100644
--- a/app/assets/javascripts/admin/pure.js
+++ b/app/assets/javascripts/admin/pure.js
@@ -13,6 +13,7 @@
 //= require summernote/summernote-bs5
 //= require slug/slug
 //= require cocoon
+//= require codemirror/lib/codemirror
 //= require_self
 //= require_tree ./commons
 //= require_tree ../application/plugins
diff --git a/app/assets/javascripts/extranet/experiences.js b/app/assets/javascripts/extranet/experiences.js
index f00ced3d8d9560c7d5f1953a057c253fd798be18..4246230c05e4b2d28eb7f648021262a9c52dba65 100644
--- a/app/assets/javascripts/extranet/experiences.js
+++ b/app/assets/javascripts/extranet/experiences.js
@@ -1,18 +1,42 @@
 /*global $ */
 $(function () {
     'use strict';
-    var setAutocompleteTargetValue = function (targetId, value) {
+    var setAutocompleteTargetValue,
+        setAutocompleteNothingFound;
+
+    setAutocompleteTargetValue = function (targetId, value) {
         var targetInput = document.querySelector(targetId);
         if (targetInput) {
             targetInput.value = value;
         }
     };
 
+    setAutocompleteNothingFound = function (target, search) {
+        var defaultText,
+            text;
+        if (target) {
+            defaultText = target.dataset.defaultText;
+            text = defaultText.replaceAll('CHANGEME', search);
+            target.innerHTML = text;
+            target.classList.remove('d-none');
+        }
+    };
+
     $('input.autocomplete')
         .on('input', function ($event) {
             setAutocompleteTargetValue($event.target.dataset.autocompleteTarget, '');
         })
         .on('railsAutocomplete.select', function ($event, data) {
+            var noResultTarget = document.querySelector($event.target.dataset.autocompleteNoResultTarget);
             setAutocompleteTargetValue($event.target.dataset.autocompleteTarget, data.item.id);
+            noResultTarget.classList.add('d-none');
+        })
+        .on('railsAutocomplete.source', function ($event, data) {
+            var noResultTarget = document.querySelector($event.target.dataset.autocompleteNoResultTarget);
+            if (data.length === 0) {
+                setAutocompleteNothingFound(noResultTarget, $event.target.value);
+            } else {
+                noResultTarget.classList.add('d-none');
+            }
         });
 });
diff --git a/app/assets/stylesheets/admin/appstack.sass b/app/assets/stylesheets/admin/appstack.sass
index 06e674993f421ad82117422b524ea86c91d90846..3413526ba440914d25ccfa8aea3f2e44d45ddf3e 100644
--- a/app/assets/stylesheets/admin/appstack.sass
+++ b/app/assets/stylesheets/admin/appstack.sass
@@ -7,6 +7,7 @@
 @import 'summernote-bs5'
 @import 'cropperjs/dist/cropper'
 @import 'gdpr/cookie_consent'
+@import 'codemirror/lib/codemirror'
 @import '../commons/*'
 @import 'commons/*'
 @import 'appstack/*'
diff --git a/app/assets/stylesheets/admin/commons/codemirror.sass b/app/assets/stylesheets/admin/commons/codemirror.sass
new file mode 100644
index 0000000000000000000000000000000000000000..f7c3a66762077a977db4ae333af3814473903be8
--- /dev/null
+++ b/app/assets/stylesheets/admin/commons/codemirror.sass
@@ -0,0 +1,2 @@
+.CodeMirror
+    border: 1px solid #CED4DA
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/pure.sass b/app/assets/stylesheets/admin/pure.sass
index a769401d2472d51dab00ff4d314da975acb0c262..3a2248c6d08bd76b573ece1fce347666a5d0c63a 100644
--- a/app/assets/stylesheets/admin/pure.sass
+++ b/app/assets/stylesheets/admin/pure.sass
@@ -10,6 +10,7 @@
 @import 'summernote-bs5'
 @import 'cropperjs/dist/cropper'
 @import 'gdpr/cookie_consent'
+@import 'codemirror/lib/codemirror'
 @import '../commons/*'
 @import 'commons/*'
 @import 'pure/buttons'
diff --git a/app/assets/stylesheets/extranet/layout/_header.sass b/app/assets/stylesheets/extranet/layout/_header.sass
index 444cef53578dbad447ee1a70efb6a7dea04b00d2..0056fb05b3145cd6710ecc859bcbffd47197bd64 100644
--- a/app/assets/stylesheets/extranet/layout/_header.sass
+++ b/app/assets/stylesheets/extranet/layout/_header.sass
@@ -9,3 +9,7 @@ header,
             text-align: right
             margin-top: -60px
             margin-bottom: 0
+    &__title
+        @extend h1
+        p
+            margin-bottom: 0
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/pages/_experiences.sass b/app/assets/stylesheets/extranet/pages/_experiences.sass
index 39dbc8668dedc2b9523a4529269fb524698266e4..efbd0e9f1e2ac2d8e276af2778eeab2d0b9b8366 100644
--- a/app/assets/stylesheets/extranet/pages/_experiences.sass
+++ b/app/assets/stylesheets/extranet/pages/_experiences.sass
@@ -1,2 +1,5 @@
-.experience__organization__logo
-    height: 100%
\ No newline at end of file
+.experience
+    line-height: px2rem(24)
+    position: relative
+    &__organization__logo
+        height: 100%
\ No newline at end of file
diff --git a/app/controllers/extranet/alumni/organizations_controller.rb b/app/controllers/extranet/alumni/organizations_controller.rb
index 2d75beb4ba2fc320e5012540cdada5a70a43d1d0..69c516df49146c5fd211f6b4aee349aaa51eccad 100644
--- a/app/controllers/extranet/alumni/organizations_controller.rb
+++ b/app/controllers/extranet/alumni/organizations_controller.rb
@@ -12,13 +12,6 @@ class Extranet::Alumni::OrganizationsController < Extranet::Alumni::ApplicationC
     breadcrumb
   end
 
-  def search
-    @term = params[:term].to_s
-    @organizations = current_university.organizations
-                                      .search_by_siren_or_name(@term)
-                                      .ordered
-  end
-
   def show
     @organization = about.university_person_alumni_organizations.find(params[:id])
     breadcrumb
diff --git a/app/controllers/extranet/application_controller.rb b/app/controllers/extranet/application_controller.rb
index a4a6731228372351ae07c62c8be95ce2d4a0ef9e..e0b98e084b3920e685900ad3c1860dfe81515f22 100644
--- a/app/controllers/extranet/application_controller.rb
+++ b/app/controllers/extranet/application_controller.rb
@@ -19,6 +19,23 @@ class Extranet::ApplicationController < ApplicationController
   end
 
   def authorize_extranet_access!
-    raise CanCan::AccessDenied if current_user.visitor? && about.alumni.find_by(id: current_user.person&.id).nil?
+    raise CanCan::AccessDenied unless user_is_authorized?
   end
+
+  def user_is_authorized?
+    user_is_more_than_visitor || user_is_alumnus || user_is_contact
+  end
+
+  def user_is_more_than_visitor
+    !current_user.visitor?
+  end
+
+  def user_is_alumnus
+    about.alumni.find_by(id: current_user.person&.id).present?
+  end
+
+  def user_is_contact
+    current_extranet.connected_persons.find_by(id: current_user.person&.id).present?
+  end
+
 end
diff --git a/app/controllers/extranet/contacts/organizations_controller.rb b/app/controllers/extranet/contacts/organizations_controller.rb
index f2cbefc1a568633f17e571d9a225690f1f348857..b58426e960e1abb83684c8e795897fa8a2a75f63 100644
--- a/app/controllers/extranet/contacts/organizations_controller.rb
+++ b/app/controllers/extranet/contacts/organizations_controller.rb
@@ -10,6 +10,7 @@ class Extranet::Contacts::OrganizationsController < Extranet::Contacts::Applicat
 
   def show
     @organization = current_extranet.connected_organizations.find(params[:id])
+    @current_experiences = @organization.experiences.includes(:person).current.ordered
     breadcrumb
   end
 
diff --git a/app/controllers/extranet/contacts/persons_controller.rb b/app/controllers/extranet/contacts/persons_controller.rb
index 6ef8e86c3ade4f8339fc7b488138b6bad8e64d74..5d6b40885d51e771d254fc9445e123e1287b38a0 100644
--- a/app/controllers/extranet/contacts/persons_controller.rb
+++ b/app/controllers/extranet/contacts/persons_controller.rb
@@ -10,6 +10,7 @@ class Extranet::Contacts::PersonsController < Extranet::Contacts::ApplicationCon
 
   def show
     @person = current_extranet.connected_persons.find(params[:id])
+    @current_experiences = @person.experiences.includes(:organization).current.ordered
     breadcrumb
   end
 
diff --git a/app/controllers/extranet/experiences_controller.rb b/app/controllers/extranet/experiences_controller.rb
index 2697cc7f87a314a9158035bb8121ac72d5d29b5c..9a297799d554f70d46251856421fd427ed409294 100644
--- a/app/controllers/extranet/experiences_controller.rb
+++ b/app/controllers/extranet/experiences_controller.rb
@@ -1,11 +1,11 @@
 class Extranet::ExperiencesController < Extranet::ApplicationController
+  before_action :load_experience, only: [:edit, :update, :destroy]
   def new
     @experience = current_user.experiences.new
     breadcrumb
   end
 
   def edit
-    @experience = current_user.experiences.find(params[:id])
     breadcrumb
   end
 
@@ -13,7 +13,8 @@ class Extranet::ExperiencesController < Extranet::ApplicationController
     @experience = current_user.experiences.new(experience_params)
     @experience.university = current_university
     if @experience.save
-      redirect_to account_path, notice: 'Ok'
+      redirect_to account_path,
+                  notice: t('admin.successfully_created_html', model: @experience.organization.to_s)
     else
       breadcrumb
       render :new
@@ -21,17 +22,27 @@ class Extranet::ExperiencesController < Extranet::ApplicationController
   end
 
   def update
-    @experience = current_user.experiences.find(params[:id])
     if @experience.update experience_params
-      redirect_to account_path, notice: 'Ok'
+      redirect_to account_path,
+                  notice: t('admin.successfully_updated_html', model: @experience.organization.to_s)
     else
       breadcrumb
       render :edit
     end
   end
 
+  def destroy
+    @experience.destroy
+    redirect_to account_path,
+                notice: t('admin.successfully_destroyed_html', model: @experience.organization.to_s)
+  end
+
   protected
 
+  def load_experience
+    @experience = current_user.experiences.find_by!(id: params[:id])
+  end
+
   def experience_params
     params.require(:university_person_experience)
           .permit(:description, :from_year, :to_year, :organization_id, :organization_name)
@@ -42,4 +53,4 @@ class Extranet::ExperiencesController < Extranet::ApplicationController
     add_breadcrumb t('extranet.account.my'), account_path
     add_breadcrumb @experience
   end
-end
\ No newline at end of file
+end
diff --git a/app/controllers/extranet/organizations_controller.rb b/app/controllers/extranet/organizations_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..af318f25a12e5deabde835ae1e8818b5be56f243
--- /dev/null
+++ b/app/controllers/extranet/organizations_controller.rb
@@ -0,0 +1,74 @@
+class Extranet::OrganizationsController < Extranet::ApplicationController
+  before_action :load_organization, only: [:show, :edit, :update]
+
+  def search
+    @term = params[:term].to_s
+    @organizations = current_university.organizations
+                                      .search_by_siren_or_name(@term)
+                                      .ordered
+  end
+
+  def show
+    breadcrumb
+  end
+
+  def new
+    @organization = current_university.organizations.new
+    @organization.name = params[:name] if params.has_key?(:name)
+    breadcrumb
+    add_breadcrumb t('create')
+  end
+
+  def create
+    @organization = current_university.organizations.new(organization_params)
+    if @organization.save
+      redirect_to organization_path(@organization),
+                  notice: t('admin.successfully_created_html', model: @organization.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('create')
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('edit')
+  end
+
+  def update
+    if @organization.update(organization_params)
+      redirect_to organization_path(@organization),
+                  notice: t('admin.successfully_updated_html', model: @organization.to_s)
+    else
+      breadcrumb
+      add_breadcrumb t('edit')
+      render :new, status: :unprocessable_entity
+    end
+  end
+
+  private
+
+  def breadcrumb
+    super
+    add_breadcrumb  University::Organization.model_name.human(count: 2)
+    add_breadcrumb @organization, organization_path(@organization) if @organization.persisted?
+  end
+
+  def load_organization
+    # this is an "experience" organization so it can be not connected to the extranet
+    @organization = current_university.organizations.find_by!(id: params[:id])
+  end
+
+  def organization_params
+    params.require(:university_organization)
+          .permit(
+            :name, :long_name, :summary, :siren, :kind,
+            :address, :address_name, :address_additional, :zipcode, :city, :country, :text,
+            :url, :phone, :email, :linkedin, :twitter, :mastodon,
+            :logo, :logo_delete, :logo_infos,
+            :logo_on_dark_background, :logo_on_dark_background_delete, :logo_on_dark_background_infos,
+          )
+  end
+
+end
diff --git a/app/controllers/extranet/pages_controller.rb b/app/controllers/extranet/pages_controller.rb
index 1cb2242cc14d3f32c33f1aeac241531f59861786..a3bc8035e5d7d9c40a26063051c6c4832affdcb5 100644
--- a/app/controllers/extranet/pages_controller.rb
+++ b/app/controllers/extranet/pages_controller.rb
@@ -17,14 +17,21 @@ class Extranet::PagesController < Extranet::ApplicationController
   end
 
   def data
-    @metrics = [
-      { value: current_extranet.alumni.count, name: University::Person::Alumnus.model_name.human(count: 2) },
-      { value: current_extranet.users.count, name: User.model_name.human(count: 2) },
-      { value: current_extranet.experiences.count, name: University::Person::Experience.model_name.human(count: 2) },
-      { value: current_extranet.academic_years.count, name: Education::AcademicYear.model_name.human(count: 2) },
-      { value: current_extranet.cohorts.count, name: Education::Cohort.model_name.human(count: 2) },
-      { value: current_extranet.organizations.count, name: University::Organization.model_name.human(count: 2) },
-    ]
+    @metrics = []
+    if current_extranet.has_feature?(:alumni)
+      @metrics.concat [
+        { value: current_extranet.alumni.count, name: University::Person::Alumnus.model_name.human(count: 2) },
+        { value: current_extranet.academic_years.count, name: Education::AcademicYear.model_name.human(count: 2) },
+        { value: current_extranet.cohorts.count, name: Education::Cohort.model_name.human(count: 2) }
+      ]
+    end
+    if current_extranet.has_feature?(:alumni) || current_extranet.has_feature?(:contacts)
+      @metrics.concat [
+        { value: current_extranet.users.count, name: User.model_name.human(count: 2) },
+        { value: current_extranet.experiences.count, name: University::Person::Experience.model_name.human(count: 2) },
+        { value: current_extranet.organizations.count, name: University::Organization.model_name.human(count: 2) }
+      ]
+    end
     breadcrumb
     add_breadcrumb t('extranet.data')
   end
diff --git a/app/controllers/extranet/style_controller.rb b/app/controllers/extranet/style_controller.rb
index dea8f4d4b07d08303b30e5c00abfabf28fc330eb..3eb7c8587a2876c04a9be5b355261ab86f509bf7 100644
--- a/app/controllers/extranet/style_controller.rb
+++ b/app/controllers/extranet/style_controller.rb
@@ -1,5 +1,7 @@
 class Extranet::StyleController < Extranet::ApplicationController
+  skip_before_action :authenticate_user!, :authorize_extranet_access!
+  
   def index
     render body: current_extranet.css, content_type: 'text/css'
   end
-end
\ No newline at end of file
+end
diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb
index c8ab92c466d3180edc318ed5d12aec0055b7ab65..c99daf122abc88d0f162d495cacdae7a82b36e3b 100644
--- a/app/models/communication/extranet.rb
+++ b/app/models/communication/extranet.rb
@@ -66,6 +66,7 @@ class Communication::Extranet < ApplicationRecord
   validates_presence_of :name, :host
   validates :logo, size: { less_than: 1.megabytes }
   validates :favicon, size: { less_than: 1.megabytes }
+  validates_presence_of :about_type, :about_id, if: :feature_alumni
 
   before_validation :sanitize_fields
 
@@ -106,11 +107,19 @@ class Communication::Extranet < ApplicationRecord
   alias academic_years years
 
   def organizations
-    about&.alumni_organizations
+    if about.present? && about.respond_to?(:alumni_organizations)
+      about.alumni_organizations
+    else
+      connected_organizations
+    end
   end
 
   def experiences
-    about&.alumni_experiences
+    if about.present? && about.respond_to?(:alumni_experiences)
+      about.alumni_experiences
+    else
+      experiences_through_connections
+    end
   end
 
   def url
diff --git a/app/models/communication/extranet/document.rb b/app/models/communication/extranet/document.rb
index 9b332be81ebbaf763b0c4202fc428b07a1b3a046..09e6d96b62b4aae947b7cfb1f82b6adf6c4303a4 100644
--- a/app/models/communication/extranet/document.rb
+++ b/app/models/communication/extranet/document.rb
@@ -8,24 +8,18 @@
 #  published_at  :datetime
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
-#  category_id   :uuid             indexed
 #  extranet_id   :uuid             not null, indexed
-#  kind_id       :uuid             indexed
 #  university_id :uuid             not null, indexed
 #
 # Indexes
 #
-#  extranet_document_categories                             (category_id)
 #  index_communication_extranet_documents_on_extranet_id    (extranet_id)
 #  index_communication_extranet_documents_on_university_id  (university_id)
-#  index_extranet_document_kinds                            (kind_id)
 #
 # Foreign Keys
 #
 #  fk_rails_1272fd263c  (extranet_id => communication_extranets.id)
-#  fk_rails_51f7db2f66  (kind_id => communication_extranet_document_kinds.id)
 #  fk_rails_af877a8c0c  (university_id => universities.id)
-#  fk_rails_eb351dc444  (category_id => communication_extranet_document_categories.id)
 #
 class Communication::Extranet::Document < ApplicationRecord
   include Sanitizable
diff --git a/app/models/communication/extranet/with_connections.rb b/app/models/communication/extranet/with_connections.rb
index 67841e9235ab6d571a83acd50aa0c5dbb50ac225..1325bfcec6c8751760fa94ad125c951a992930e5 100644
--- a/app/models/communication/extranet/with_connections.rb
+++ b/app/models/communication/extranet/with_connections.rb
@@ -27,4 +27,8 @@ module Communication::Extranet::WithConnections
     University::Person.where(id: ids)
   end
 
+  def experiences_through_connections
+    University::Person::Experience.where(person_id: connected_persons, organization_id: connected_organizations)
+  end
+
 end
\ No newline at end of file
diff --git a/app/models/university/person/experience.rb b/app/models/university/person/experience.rb
index 60c2a43632ea9fdd7e62cadab1a7e9af2c5f6b8e..2bd6df5582ef29bf0a12db955a01907c06dce9de 100644
--- a/app/models/university/person/experience.rb
+++ b/app/models/university/person/experience.rb
@@ -33,14 +33,12 @@ class University::Person::Experience < ApplicationRecord
   belongs_to :person
   belongs_to :organization, class_name: "University::Organization"
 
-  validates_presence_of :organization
   validates_presence_of :from_year
-  # TODO validateur de comparaison
-  # validates_numericality_of :to_year, { greater_than_or_equal_to: :from_year }, allow_nil: true
   validate :to_year, :not_before_from_year
 
-  before_validation :create_organization_if_needed
+  after_validation :deport_error_on_organization
 
+  scope :current, -> { where('from_year <= :current_year AND (to_year IS NULL OR to_year >= :current_year)', current_year: Date.today.year) }
   scope :ordered, -> { order('university_person_experiences.to_year DESC NULLS FIRST, university_person_experiences.from_year') }
   scope :recent, -> {
     where.not(from_year: nil)
@@ -65,13 +63,10 @@ class University::Person::Experience < ApplicationRecord
     end
   end
 
-  def create_organization_if_needed
-    if organization.nil? && organization_name.present?
-      self.organization_name = self.organization_name.strip
-      orga = university.organizations.find_by("name ILIKE ?", organization_name)
-      orga ||= university.organizations.find_by(siren: organization_name)
-      orga ||= university.organizations.create(name: organization_name, created_from_extranet: true)
-      self.organization = orga if orga.persisted?
+  def deport_error_on_organization
+    if errors[:organization].present? && organization_name
+      errors.add :organization_name, :required
     end
   end
+
 end
diff --git a/app/views/admin/communication/blocks/components/_edit.html.erb b/app/views/admin/communication/blocks/components/_edit.html.erb
index b2bc336a1db1ad86780cdde67f3b6f1f2e460177..f3c6a8352944be21b27cfb764eca6860d68614e1 100644
--- a/app/views/admin/communication/blocks/components/_edit.html.erb
+++ b/app/views/admin/communication/blocks/components/_edit.html.erb
@@ -19,6 +19,7 @@ placeholder ||= t "#{i18n_component}.placeholder", default: ''
 hint ||= t "#{i18n_component}.hint", default: ''
 none ||= t "#{i18n_component}.none", default: ''
 summernote_config ||= "mini-list"
+codemirror_mode ||= "htmlmixed"
 partial = "admin/communication/blocks/components/#{component.kind}/edit"
 
 local_assigns[:template] = template
@@ -31,5 +32,6 @@ local_assigns[:placeholder] = placeholder
 local_assigns[:hint] = hint
 local_assigns[:none] ||= t "#{i18n_component}.none", default: ''
 local_assigns[:summernote_config] ||= summernote_config
+local_assigns[:codemirror_mode] ||= codemirror_mode
 %>
 <%= render partial, **local_assigns %>
diff --git a/app/views/admin/communication/blocks/components/code/_edit.html.erb b/app/views/admin/communication/blocks/components/code/_edit.html.erb
index 378a26d41bc751c05ee349f1ddeca7895b1df33d..c21538631ba9c501802a04f93d723a9f2a6c109b 100644
--- a/app/views/admin/communication/blocks/components/code/_edit.html.erb
+++ b/app/views/admin/communication/blocks/components/code/_edit.html.erb
@@ -4,7 +4,8 @@
   <%= label %>
 </label>
 <textarea :id="<%= dom_id.html_safe %>"
-          class="form-control mb-3"
+          class="form-control mb-3 codemirror-vue"
+          data-codemirror-mode="<%= codemirror_mode %>"
           rows="<%= rows %>"
           v-model="<%= model %>.<%= property %>"
           placeholder="<%= placeholder %>"></textarea>
diff --git a/app/views/admin/communication/blocks/edit.html.erb b/app/views/admin/communication/blocks/edit.html.erb
index d57c344baacdba41e8e45f2cabe0122919169d07..e4813e15a33e370cab21e7dfe3c010a6b4dec19a 100644
--- a/app/views/admin/communication/blocks/edit.html.erb
+++ b/app/views/admin/communication/blocks/edit.html.erb
@@ -71,9 +71,9 @@
         this.uploadFile(event.target, files[0], object, key);
       },
       uploadFile(input, file, object, key) {
-        var size = Math.round(file.size / 1024 / 1024), 
+        var size = Math.round(file.size / 1024 / 1024),
             sizeLimit = <%= Communication::Block::IMAGE_MAX_SIZE %>,
-            sizeLimitMo = 0, 
+            sizeLimitMo = 0,
             controller;
         if (input.hasAttribute('data-size-limit')) {
           sizeLimit = input.getAttribute('data-size-limit');
@@ -107,6 +107,13 @@
           this.initSummernote($summernoteElements.get(index));
         }.bind(this));
       },
+      handleCodemirrors() {
+        var $codemirrorElements = $('.codemirror-vue');
+
+        $codemirrorElements.each(function(index){
+          this.initCodemirror($codemirrorElements.get(index));
+        }.bind(this));
+      },
       initSummernote(element) {
         var config = element.getAttribute('data-summernote-config') || 'default';
         $(element).summernote({
@@ -121,10 +128,21 @@
             }.bind(this)
           }
         });
+      },
+      initCodemirror(element) {
+        CodeMirror.fromTextArea(element, {
+            lineNumbers: true,
+            styleActiveLine: true,
+            indentUnit: 2,
+            viewportMargin: Infinity,
+            mode: element.getAttribute('data-codemirror-mode')
+        });
       }
     },
     mounted: function() {
       this.handleSummernotes();
+      // Use Timeout to prevent display issues
+      setTimeout(this.handleCodemirrors.bind(this), 0);
     }
   });
 
diff --git a/app/views/admin/communication/extranets/_form.html.erb b/app/views/admin/communication/extranets/_form.html.erb
index eef002e8e81176d5512e22bc0b363c067fc711ec..bcd8c3d72b1a3ef086441a29c6caa0d9082d59a3 100644
--- a/app/views/admin/communication/extranets/_form.html.erb
+++ b/app/views/admin/communication/extranets/_form.html.erb
@@ -22,8 +22,15 @@
                     preview: 100,
                     direct_upload: true %>
         <%= f.input :color, as: :color %>
-        <%= f.input :home_sentence %>
-        <%= f.input :sass %>
+        <%= f.input :home_sentence, as: :summernote, input_html: { data: { 'summernote-config': 'link' } } %>
+        <%= f.input :sass,
+                    input_html: {
+                      data: {
+                        provider: 'codemirror',
+                        "codemirror-mode": "sass",
+                        "codemirror-indentation": 4
+                      }
+                    } %>
       <% end %>
     </div>
     <div class="col-xl-6">
diff --git a/app/views/admin/communication/extranets/posts/show.html.erb b/app/views/admin/communication/extranets/posts/show.html.erb
index a4aa85eec80ed99554224e3cdb473d32c1e71440..4895b36dcec1e322112143a3c39a91e9819b04dc 100644
--- a/app/views/admin/communication/extranets/posts/show.html.erb
+++ b/app/views/admin/communication/extranets/posts/show.html.erb
@@ -10,7 +10,7 @@
       <%
       action = ''
       action += link_to t('open'),
-                        posts_communication_extranet_post_url(@post.slug, host: @post.extranet.url, extranet_id: nil),
+                        posts_post_url(@post.slug, host: @post.extranet.url, extranet_id: nil),
                         target: :_blank,
                         class: 'btn btn-light btn-xs' if @post.published
       %>
diff --git a/app/views/admin/university/organizations/show.html.erb b/app/views/admin/university/organizations/show.html.erb
index d45b20164b2363af7bfc5702a857e13f855662c6..46dd34a5f1e7a11749586f6d6b25a1faf1b83bab 100644
--- a/app/views/admin/university/organizations/show.html.erb
+++ b/app/views/admin/university/organizations/show.html.erb
@@ -123,12 +123,12 @@
       <tbody>
         <% @organization.experiences.ordered.each do |experience| %>
           <%
-            alumnus = experience.person
-            path = admin_university_alumnus_path(alumnus)
+            person = experience.person
+            path = admin_university_person_path(person)
           %>
           <tr>
-            <td><%= link_to_if can?(:read, alumnus), alumnus.last_name, path %></td>
-            <td><%= link_to_if can?(:read, alumnus), alumnus.first_name, path %></td>
+            <td><%= link_to_if can?(:read, person), person.last_name, path %></td>
+            <td><%= link_to_if can?(:read, person), person.first_name, path %></td>
             <td>
               <%= "#{experience.from_year} - #{experience.to_year.present? ? experience.to_year : t('today')}" %>
             </td>
diff --git a/app/views/admin/university/organizations/static.html.erb b/app/views/admin/university/organizations/static.html.erb
index 60054f0d4fbeacd0eb5c737974fdfedd7db117d9..ac035815dde3defe990bba3c4ff006073013dd31 100644
--- a/app/views/admin/university/organizations/static.html.erb
+++ b/app/views/admin/university/organizations/static.html.erb
@@ -16,8 +16,6 @@ kind:
   :zipcode,
   :city,
   :country,
-  :latitude,
-  :longitude,
   :phone,
   :email,
   :twitter,
@@ -43,6 +41,9 @@ contact_details:
 <%= render 'admin/application/static/contact_detail', variable: :mastodon, data: @about.mastodon, kind: ContactDetails::Mastodon %>
 <%= render 'admin/application/static/contact_detail', variable: :phone, data: @about.phone, kind: ContactDetails::Phone %>
 <%= render 'admin/application/static/contact_detail', variable: :email, data: @about.email, kind: ContactDetails::Email %>
+  geolocation:
+    latitude: <%= @about.latitude %>
+    longitude: <%= @about.longitude %>
 <% if @about.logo.attached? %>
 logo: "<%= @about.logo.blob.id %>"
 <% end %>
diff --git a/app/views/extranet/account/show.html.erb b/app/views/extranet/account/show.html.erb
index cb79fe1a16b9feb55f4dd90dce2838bcd618d681..d36d78bad6c0351babe368cb53646604b38261a1 100644
--- a/app/views/extranet/account/show.html.erb
+++ b/app/views/extranet/account/show.html.erb
@@ -11,7 +11,7 @@
     <%= link_to University::Person::Experience.human_attribute_name('new'),
                 new_experience_path,
                 class: 'btn btn-sm btn-primary mt-md-n5 float-md-end' %>
-    <%= render 'extranet/alumni/persons/path', person: @person, edit: true %>
+    <%= render 'extranet/experiences/list', person: @person, edit: true %>
   </div>
   <div class="col-md-3">
     <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person&.best_picture&.attached? %>
@@ -19,6 +19,6 @@
       <%= link_to t('extranet.account.edit'), edit_account_path, class: 'btn btn-primary mb-2' %>
       <%= link_to t('extranet.account.edit_personal_data'), edit_personal_data_path, class: 'btn btn-primary mb-2' %>
     </div>
-    <%= render 'extranet/alumni/persons/details', person: @person unless @person.nil? %>
+    <%= render 'extranet/personal_data/details', person: @person unless @person.nil? %>
   </div>
 </div>
diff --git a/app/views/extranet/alumni/persons/_path.html.erb b/app/views/extranet/alumni/persons/_path.html.erb
deleted file mode 100644
index 4572ea2b20a4cbf92e2ea566c4204e678c18d22a..0000000000000000000000000000000000000000
--- a/app/views/extranet/alumni/persons/_path.html.erb
+++ /dev/null
@@ -1,34 +0,0 @@
-<%
-edit ||= false
-%>
-<div class="experiences mt-4">
-  <ul class="list-unstyled">
-    <% if person&.experiences&.any? %>
-      <% @person.experiences.ordered.each do |experience| %>
-        <%= render 'extranet/experiences/experience', experience: experience, edit: edit %>
-      <% end %>
-    <% end %>
-    <% person&.cohorts&.each do |cohort| %>
-      <li class="experiences__experience py-4 border-top">
-        <div class="row">
-          <div class="col-md-6">
-            <p class="mb-0">
-              <%= link_to [:alumni, cohort] do %>
-                <b><%= cohort.program %></b><br>
-                <%= cohort.program.diploma %><br>
-                <%= cohort.year %>
-              <% end %>
-            </p>
-          </div>
-          <div class="col-md-6 text-end">
-            <% if cohort.school.logo.attached? %>
-              <%= kamifusen_tag cohort.school.logo, width: 100, class: 'img-fluid experience__organization__logo' %>
-            <% else %>
-              <p class="text-end"><%= cohort.school %></p>
-            <% end %>
-          </div>
-        </div>
-      </li>
-    <% end %>
-  </ul>
-</div>
diff --git a/app/views/extranet/alumni/persons/show.html.erb b/app/views/extranet/alumni/persons/show.html.erb
index 6079d71e13004f41c86705e6603db3862af383d2..33896432b2c293381a5a587c0daaf7e90ab9a7ea 100644
--- a/app/views/extranet/alumni/persons/show.html.erb
+++ b/app/views/extranet/alumni/persons/show.html.erb
@@ -12,10 +12,38 @@
       </div>
     </div>
     <p class="mb-4"><%= t('extranet.experiences.title') %></p>
-    <%= render 'extranet/alumni/persons/path', person: @person %>
+    <%= render 'extranet/experiences/list', person: @person %>
+
+    <div class="experiences mt-4">
+      <ul class="list-unstyled">
+        <% @person&.cohorts&.each do |cohort| %>
+          <li class="experiences__experience py-4 border-top">
+            <div class="row">
+              <div class="col-md-6">
+                <p class="mb-0">
+                  <%= link_to [:alumni, cohort] do %>
+                    <b><%= cohort.program %></b><br>
+                    <%= cohort.program.diploma %><br>
+                    <%= cohort.year %>
+                  <% end %>
+                </p>
+              </div>
+              <div class="col-md-6 text-end">
+                <% if cohort.school.logo.attached? %>
+                  <%= kamifusen_tag cohort.school.logo, width: 100, class: 'img-fluid experience__organization__logo' %>
+                <% else %>
+                  <p class="text-end"><%= cohort.school %></p>
+                <% end %>
+              </div>
+            </div>
+          </li>
+        <% end %>
+      </ul>
+    </div>
+
   </div>
   <div class="offset-md-1 col-md-3 order-1 order-md-2">
     <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person.best_picture.attached? %>
-    <%= render 'extranet/alumni/persons/details', person: @person %>
+    <%= render 'extranet/personal_data/details', person: @person %>
   </div>
 </div>
diff --git a/app/views/extranet/contacts/organizations/show.html.erb b/app/views/extranet/contacts/organizations/show.html.erb
index 7e294913f1fba849ab800f8e7e133a04d0cd0924..855d43325861c3883b55c05266735e3a50acad1e 100644
--- a/app/views/extranet/contacts/organizations/show.html.erb
+++ b/app/views/extranet/contacts/organizations/show.html.erb
@@ -7,6 +7,36 @@
         <div class="biography mb-5">
           <%= sanitize @organization.text %>
         </div>
+        <% if @current_experiences.any? %>
+          <div class="experiences mb-5">
+            <h3><%= t('extranet.contacts.organizations.experiences', count: @current_experiences.pluck(:person_id).uniq.size) %></h3>
+
+            <% @current_experiences.each do |experience| %>
+              <article class="experience mb-4">
+                <div class="row gx-3">
+                  <div class="col-md-3">
+                    <% if experience.person.best_picture.attached? %>
+                      <%= kamifusen_tag experience.person.best_picture, width: 400, class: 'img-fluid',
+                        sizes: {
+                            '(max-width: 576px)': '400px',
+                            '(max-width: 991px)': '200px'
+                        } %>
+                    <% else %>
+                      <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %>
+                    <% end %>
+                  </div>
+                  <div class="col-md-9">
+                    <%= link_to [:contacts, experience.person], class: 'stretched-link' do %>
+                      <p>
+                        <b><%= experience.person.first_name %> <%= experience.person.last_name %></b><br>
+                        <span class="text-muted"><%= experience.description %></span>
+                      </p>
+                    <% end %>
+                  </div>
+              </article>
+            <% end %>
+          </div>
+        <% end %>
       </div>
     </div>
   </div>
diff --git a/app/views/extranet/contacts/persons/show.html.erb b/app/views/extranet/contacts/persons/show.html.erb
index 36302396a7f90bee2cc44955907a1f096817c230..69c480d48020311a0e36f6559cdbb65c94a7e26f 100644
--- a/app/views/extranet/contacts/persons/show.html.erb
+++ b/app/views/extranet/contacts/persons/show.html.erb
@@ -10,15 +10,43 @@
           </p>
         <% end %>
         <% unless @person.biography.blank? %>
-          <div class="biography mt-5">
+          <div class="biography my-5">
             <%= sanitize @person&.biography %>
           </div>
         <% end %>
+        <% if @current_experiences.any? %>
+          <div class="experiences mb-5">
+            <h3><%= t('extranet.contacts.persons.experiences', count: @current_experiences.pluck(:organization_id).uniq.size) %></h3>
+
+            <% @current_experiences.each do |experience| %>
+              <article class="experience mb-4">
+                <div class="row gx-3">
+                  <div class="col-md-3">
+                    <% if experience.organization.logo.attached? %>
+                      <%= kamifusen_tag experience.organization.logo, width: 400, class: 'img-fluid',
+                        sizes: {
+                            '(max-width: 576px)': '400px',
+                            '(max-width: 991px)': '200px'
+                        } %>
+                    <% end %>
+                  </div>
+                  <div class="col-md-9">
+                    <%= link_to [:contacts, experience.organization], class: 'stretched-link' do %>
+                      <p>
+                        <b><%= experience.organization %></b><br>
+                        <span class="text-muted"><%= experience.description %></span>
+                      </p>
+                    <% end %>
+                  </div>
+              </article>
+            <% end %>
+          </div>
+        <% end %>
       </div>
     </div>
   </div>
   <div class="offset-md-1 col-md-3 order-1 order-md-2">
     <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person.best_picture.attached? %>
-    <%= render 'extranet/alumni/persons/details', person: @person %>
+    <%= render 'extranet/personal_data/details', person: @person %>
   </div>
 </div>
diff --git a/app/views/extranet/experiences/_experience.html.erb b/app/views/extranet/experiences/_experience.html.erb
index e5f211fc62bc64248d3ebdb99f8faf04068b3f5c..4db5233f761ba5c886c29c841f66da37dc86c745 100644
--- a/app/views/extranet/experiences/_experience.html.erb
+++ b/app/views/extranet/experiences/_experience.html.erb
@@ -15,12 +15,12 @@ edit ||= false
     </div>
     <div class="col-md-6 text-end">
       <% if experience.organization.present? %>
-        <%= link_to [:alumni, experience.organization] do %>
-          <% if experience.organization.logo.attached? %>
+        <% if experience.organization.logo.attached? %>
+          <%= link_to organization_path(experience.organization) do %>
             <%= kamifusen_tag experience.organization.logo, width: 100, class: 'img-fluid experience__organization__logo' %>
-          <% else %>
-            <p class="text-end><%= link_to experience.organization, [:alumni, experience.organization] %></p>
           <% end %>
+        <% else %>
+          <p class="text-end><%= link_to experience.organization, organization_path(experience.organization) %></p>
         <% end %>
       <div>
     <% end %>
diff --git a/app/views/extranet/experiences/_form.html.erb b/app/views/extranet/experiences/_form.html.erb
index 5ff1f5470817ac3386fa70c3f46a06fa23f9ce9e..1773637dbbc7521096017c0352f99831fbe65ffc 100644
--- a/app/views/extranet/experiences/_form.html.erb
+++ b/app/views/extranet/experiences/_form.html.erb
@@ -1,18 +1,30 @@
 <%= simple_form_for experience, url: experience.persisted? ? experience_path(experience) : experiences_path do |f| %>
 
-  <% if experience.errors.any? %>
-    <div id="error_explanation" class="text-danger">
-      <ul class="list-unstyled">
-        <% experience.errors.each do |error| %>
-          <li><%= error.full_message %></li>
+  <div class="row">
+    <div class="col-lg-6">
+      <%= f.input :organization_name,
+      label: University::Organization.model_name.human,
+      as: :autocomplete,
+      required: true,
+      url: search_organizations_path,
+      placeholder: t("extranet.experiences.search_organization"),
+      input_html: {
+        data: {
+          "showNoMatches": "false",
+          "autocomplete-target": "#university_person_experience_organization_id",
+          "autocomplete-no-result-target": "#university_person_experience_organization_not_found"
+        },
+        autocomplete: 'off',
+        role: 'presentation'
+      } %>
+      <%= f.hidden_field :organization_id %>
+      <div class="<%= 'd-none' unless experience.organization_id.nil? && experience.organization_name.present? %>" id="university_person_experience_organization_not_found" data-default-text="<%= t('extranet.account.experiences.create_new_html', name: 'CHANGEME', url: new_organization_path(name: 'CHANGEME')) %>">
+        <% if experience.organization_id.nil? && experience.organization_name.present? %>
+        <%= t('extranet.account.experiences.create_new_html', name: experience.organization_name, url: new_organization_path(name: experience.organization_name)) %>
         <% end %>
-      </ul>
+      </div>
     </div>
-  <% end %>
-
-  <div class="row">
     <div class="col-lg-6">
-      <%= f.input :description, as: :string %>
       <div class="row">
         <div class="col-6">
           <%= f.input :from_year %>
@@ -21,23 +33,8 @@
           <%= f.input :to_year %>
         </div>
       </div>
-    </div>
-    <div class="col-lg-6">
-      <%= f.input :organization_name,
-                  label: University::Organization.model_name.human,
-                  as: :autocomplete,
-                  url: alumni_search_university_organizations_path,
-                  placeholder: t("extranet.experiences.search_organization"),
-                  input_html: {
-                    data: {
-                      "showNoMatches": "false",
-                      "autocomplete-target": "#university_person_experience_organization_id"
-                    },
-                    autocomplete: 'off',
-                    role: 'presentation'
-                  } %>
-      <%= f.hidden_field :organization_id %>
+      <%= f.input :description, as: :string %>
     </div>
   </div>
   <%= submit f %>
-<% end %>
\ No newline at end of file
+<% end %>
diff --git a/app/views/extranet/experiences/_list.html.erb b/app/views/extranet/experiences/_list.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..8873d0a515295669d128e561397da4501fd286c1
--- /dev/null
+++ b/app/views/extranet/experiences/_list.html.erb
@@ -0,0 +1,12 @@
+<%
+edit ||= false
+%>
+<div class="experiences mt-4">
+  <ul class="list-unstyled">
+    <% if person&.experiences&.any? %>
+      <% @person.experiences.ordered.each do |experience| %>
+        <%= render 'extranet/experiences/experience', experience: experience, edit: edit %>
+      <% end %>
+    <% end %>
+  </ul>
+</div>
diff --git a/app/views/extranet/experiences/edit.html.erb b/app/views/extranet/experiences/edit.html.erb
index acfba4993cd514add045f930bcb215301e21d5d6..0a0c8aa0b70e1e3613ac1c7dfcee924e4b40bd37 100644
--- a/app/views/extranet/experiences/edit.html.erb
+++ b/app/views/extranet/experiences/edit.html.erb
@@ -1,3 +1,5 @@
 <% content_for :title, @experience %>
 
-<%= render 'form', experience: @experience %>
\ No newline at end of file
+<%= render 'form', experience: @experience %>
+
+<%= link_to t('delete'), experience_path(@experience), method: :delete, data: { confirm: t('please_confirm') }, class: 'btn btn-danger mt-3' %>
diff --git a/app/views/extranet/home/index.html.erb b/app/views/extranet/home/index.html.erb
index 6cd5f804587ddcd34b4c52ad301c15842ca52472..dcfaf67ad3356a166c43626f0fa8ce1d732f9060 100644
--- a/app/views/extranet/home/index.html.erb
+++ b/app/views/extranet/home/index.html.erb
@@ -1,15 +1,14 @@
 <% content_for :title, current_context %>
 <% content_for :header do %>
-  <h1>
+  <div class="header__title">
     <% if current_extranet.home_sentence.present? %>
-      <%= current_extranet.home_sentence.html_safe %>
+      <%= sanitize current_extranet.home_sentence %>
     <% else %>
-      <%= t 'extranet.home.welcome' %>
+      <p><%= t 'extranet.home.welcome' %></p>
     <% end %>
-  </h1>
+  </div>
 <% end %>
 
 <%= render 'extranet/home/features/posts' if current_extranet.feature_posts %>
 <%= render 'extranet/home/features/alumni' if current_extranet.feature_alumni %>
 <%= render 'extranet/home/features/contacts' if current_extranet.feature_contacts %>
-
diff --git a/app/views/extranet/layouts/devise.html.erb b/app/views/extranet/layouts/devise.html.erb
index b8ebe5083ad89910bc9b58d2daccbed966e33421..f94aae6fee43e9285b0b021aa7c4ae9b779a4464 100644
--- a/app/views/extranet/layouts/devise.html.erb
+++ b/app/views/extranet/layouts/devise.html.erb
@@ -6,7 +6,7 @@
   <body class="<%= body_classes %> layout-devise">
     <main class="container">
       <div class="row">
-        <div class="offset-md-2 col-md-8">
+        <div class="offset-xl-1 col-xl-10">
           <h1 class="text-center">
             <%= link_to root_path do %>
               <%= render 'logo' %>
@@ -31,5 +31,6 @@
     </main>
     <%= render 'extranet/gdpr/cookie_consent' %>
     <%= render 'bugsnag' %>
+    <%= javascript_include_tag 'extranet' %>
   </body>
 </html>
diff --git a/app/views/extranet/organizations/_form.html.erb b/app/views/extranet/organizations/_form.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..21d1904fcb3aae321d04ec8d44ba9635165837bf
--- /dev/null
+++ b/app/views/extranet/organizations/_form.html.erb
@@ -0,0 +1,92 @@
+<% url = organization.persisted? ? organization_path(organization) : organizations_path %>
+<%= simple_form_for organization, url: url do |f| %>
+  <%= f.error_notification %>
+  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+  <div class="row">
+    <div class="col-xl-6">
+      <%= f.input :name %>
+      <%= render 'admin/application/summary/form', f: f, about: organization %>
+      <%= f.input :text,
+                  as: :summernote,
+                  input_html: {
+                    data: { 'summernote-config' => 'mini-list' }
+                  } %>
+
+      <h2><%= University::Organization.human_attribute_name('legal') %></h2>
+      <div class="row">
+        <div class="col-xl-6">
+          <%= f.input :long_name %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :kind, include_blank: false %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :siren %>
+        </div>
+      </div>
+    </div>
+
+    <div class="col-xl-6">
+      <h2><%= University::Organization.human_attribute_name('physical') %></h2>
+      <div class="row">
+        <div class="col-xl-6">
+          <%= f.input :address_name %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :address %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :address_additional %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :zipcode %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :city %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :country, input_html: { class: 'form-select' } %>
+        </div>
+      </div>
+
+      <h2><%= University::Organization.human_attribute_name('digital') %></h2>
+      <div class="row">
+        <div class="col-xl-6">
+          <%= f.input :url %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :phone %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :email %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :linkedin %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :twitter %>
+        </div>
+        <div class="col-xl-6">
+          <%= f.input :mastodon %>
+        </div>
+      </div>
+
+      <h2><%= University::Organization.human_attribute_name('logos') %></h2>
+      <%= f.input :logo,
+                  as: :single_deletable_file,
+                  input_html: { accept: '.jpg,.jpeg,.png,.svg' },
+                  preview: 200,
+                  resize: false,
+                  direct_upload: true %>
+      <%= f.input :logo_on_dark_background,
+                  as: :single_deletable_file,
+                  input_html: { accept: '.jpg,.jpeg,.png,.svg' },
+                  preview: 200,
+                  resize: false,
+                  direct_upload: true %>
+    </div>
+
+  </div>
+  <%= submit f %>
+<% end %>
diff --git a/app/views/extranet/organizations/edit.html.erb b/app/views/extranet/organizations/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..8e990f07344d2b5384fcbe9aaa67cbce7e2000ce
--- /dev/null
+++ b/app/views/extranet/organizations/edit.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, @organization %>
+
+<%= render 'form', organization: @organization %>
diff --git a/app/views/extranet/organizations/new.html.erb b/app/views/extranet/organizations/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..96d61c5358d2c3ff3efb5df4fb854c9cbe98b367
--- /dev/null
+++ b/app/views/extranet/organizations/new.html.erb
@@ -0,0 +1,3 @@
+<% content_for :title, University::Organization.model_name.human %>
+
+<%= render 'form', organization: @organization %>
diff --git a/app/views/extranet/alumni/organizations/search.json.jbuilder b/app/views/extranet/organizations/search.json.jbuilder
similarity index 100%
rename from app/views/extranet/alumni/organizations/search.json.jbuilder
rename to app/views/extranet/organizations/search.json.jbuilder
diff --git a/app/views/extranet/organizations/show.html.erb b/app/views/extranet/organizations/show.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..0c6394a26b6b4c23d11efb0fd894d7e380ec959b
--- /dev/null
+++ b/app/views/extranet/organizations/show.html.erb
@@ -0,0 +1,117 @@
+<% content_for :title, @organization %>
+<div class="row">
+  <div class="col-md-6">
+    <%= render 'admin/application/summary/show', about: @organization %>
+
+    <% if strip_tags(@organization.text.to_s).present? %>
+    <h2><%= University::Organization.human_attribute_name('text') %></h2>
+    <%= @organization.text.to_s.html_safe %>
+    <% end %>
+
+    <h2><%= University::Organization.human_attribute_name('legal') %></h2>
+    <div class="row">
+      <% if @organization.long_name.present? %>
+        <div class="col-xxl-6">
+          <%= osuny_label University::Organization.human_attribute_name('long_name') %>
+          <p><%= @organization.long_name %></p>
+        </div>
+      <% end %>
+      <div class="col-xxl-6">
+        <%= osuny_label University::Organization.human_attribute_name('kind') %>
+        <p><%= @organization.kind_i18n %></p>
+      </div>
+      <% if @organization.siren.present? %>
+        <div class="col-xxl-6">
+          <%= osuny_label University::Organization.human_attribute_name('siren') %>
+          <p><%= @organization.siren %></p>
+        </div>
+      <% end %>
+    </div>
+  </div>
+
+  <div class="col-md-6">
+    <% if @organization.address_name.present? ||
+          @organization.address.present? ||
+          @organization.address_additional.present? ||
+          @organization.zipcode.present? ||
+          @organization.city.present? ||
+          @organization.country.present? ||
+          @organization.geolocated? %>
+      <h2><%= University::Organization.human_attribute_name('physical') %>
+      <div class="row">
+        <% [
+            :address_name,
+            :address,
+            :address_additional,
+            :zipcode,
+            :city,
+          ].each do |property| %>
+          <% value = @organization.send property %>
+          <% next if value.blank? %>
+          <div class="col-xxl-6">
+            <%= osuny_label University::Organization.human_attribute_name(property) %>
+            <p><%= value %></p>
+          </div>
+        <% end %>
+        <% if @organization.country.present? %>
+          <div class="col-xxl-6">
+            <%= osuny_label University::Organization.human_attribute_name('country') %>
+            <p><%= ISO3166::Country[@organization.country].common_name %></p>
+          </div>
+        <% end %>
+        <% if @organization.geolocated? %>
+          <div class="col-xxl-6">
+            <%= osuny_label University::Organization.human_attribute_name('geolocation') %>
+            <p><%= @organization.geo_point.to_s %></p>
+          </div>
+        <% end %>
+      </div>
+    <% end %>
+
+    <% if @organization.phone.present? ||
+          @organization.email.present? ||
+          @organization.linkedin.present? ||
+          @organization.twitter.present? ||
+          @organization.mastodon.present? %>
+      <h2><%= University::Organization.human_attribute_name('digital') %></h2>
+      <div class="row">
+        <% unless @organization.url.blank? %>
+          <div class="col-xxl-6">
+            <%= osuny_label University::Organization.human_attribute_name('url') %>
+            <p><%= link_to  @organization.url,
+                            @organization.url,
+                            target: :_blank %></p>
+          </div>
+        <% end %>
+        <% [
+            :phone,
+            :email,
+            :linkedin,
+            :twitter,
+            :mastodon
+            ].each do |property| %>
+          <% value = @organization.send property %>
+          <% next if value.blank? %>
+          <div class="col-xxl-6">
+            <%= osuny_label University::Organization.human_attribute_name(property) %>
+            <p><%= value %></p>
+          </div>
+        <% end %>
+      </div>
+    <% end %>
+
+    <% if @organization.logo.attached? || @organization.logo_on_dark_background.attached? %>
+      <h2><%= t('university.organization.logos') %></h2>
+      <% if @organization.logo.attached? %>
+        <%= osuny_label University::Organization.human_attribute_name('logo') %><br>
+        <%= kamifusen_tag @organization.logo, class: 'img-fluid img-fill bg-light img-thumbnail mb-3' %>
+      <% end %>
+      <% if @organization.logo_on_dark_background.attached? %>
+        <%= osuny_label University::Organization.human_attribute_name('logo_on_dark_background') %><br>
+        <%= kamifusen_tag @organization.logo_on_dark_background, class: 'img-fluid img-fill bg-dark img-thumbnail' %>
+      <% end %>
+    <% end %>
+  </div>
+
+</div>
+<%= link_to t('edit'), edit_organization_path(@organization), class: 'btn btn-primary' %>
diff --git a/app/views/extranet/alumni/persons/_details.html.erb b/app/views/extranet/personal_data/_details.html.erb
similarity index 100%
rename from app/views/extranet/alumni/persons/_details.html.erb
rename to app/views/extranet/personal_data/_details.html.erb
diff --git a/config/application.sample.yml b/config/application.sample.yml
index f273685fe74d4c19abeb00985b75ea07beeebbff..105eafe9569a653dec5c252a097c1b38266b1254 100644
--- a/config/application.sample.yml
+++ b/config/application.sample.yml
@@ -1,6 +1,4 @@
 APPLICATION_ENV: development
-# Can be used when working on two incompatible branches (e.g. main & i18n)
-OSUNY_DEVELOPMENT_DBNAME:
 
 BUGSNAG_JAVASCRIPT_KEY:
 BUGSNAG_RUBY_KEY:
@@ -8,6 +6,9 @@ BUGSNAG_RUBY_KEY:
 MAIL_FROM_DEFAULT_ADDRESS:
 MAIL_FROM_DEFAULT_NAME:
 
+  # Can be used when working on two incompatible branches (e.g. main & i18n)
+OSUNY_DEVELOPMENT_DBNAME:
+
 OSUNY_STAGING_APP_NAME:
 OSUNY_STAGING_PG_ADDON_ID:
 
diff --git a/config/locales/extranet/en.yml b/config/locales/extranet/en.yml
index fb877a0b81a1a8e13a913c766b1ee9b417e7e671..8e470e5b45f7803d2055e53a1b3df5825cea472a 100644
--- a/config/locales/extranet/en.yml
+++ b/config/locales/extranet/en.yml
@@ -2,12 +2,18 @@ en:
   extranet:
     features: Features
     account:
-      my: My account
       edit: Edit account
       edit_personal_data: Edit profile
+      experiences:
+        create_new_html: The organization *** doesn't exist, do you want to <a class='btn btn-primary' href='%{url}'>create it</a>?
+      my: My account
       updated: Updated
       logout: Log out
     contacts:
+      organizations:
+        experiences: Members of this organization (%{count})
+      persons:
+        experiences: Organizations where they belong (%{count})
       search:
         home: Search in directory
         title: Search
@@ -38,4 +44,4 @@ en:
       updated: Your personal data has been updated!
     posts:
       home: Recent posts
-      read_post: Read post
\ No newline at end of file
+      read_post: Read post
diff --git a/config/locales/extranet/fr.yml b/config/locales/extranet/fr.yml
index 87fcc92b5e502247244bb5761ce3c12ede289ffd..1c80d42bc669ca36ad67f6cf15572ea5842efe8e 100644
--- a/config/locales/extranet/fr.yml
+++ b/config/locales/extranet/fr.yml
@@ -2,12 +2,18 @@ fr:
   extranet:
     features: Fonctionnalités
     account:
-      my: Mon compte
       edit: Modifier mon compte
       edit_personal_data: Modifier mon profil
+      experiences:
+        create_new_html: L'organisation <b>%{name}</b> n'existe pas, souhaitez-vous <a class='btn btn-primary' href='%{url}'>la créer</a> ?
+      my: Mon compte
       updated: Mise à jour effectuée
       logout: Déconnexion
     contacts:
+      organizations:
+        experiences: Membres de cette organisation (%{count})
+      persons:
+        experiences: Organisations dont iel fait partie (%{count})
       search:
         home: Chercher dans l'annuaire
         title: Recherche
@@ -38,4 +44,4 @@ fr:
       updated: Mise à jour des donnes personnelles effectuée !
     posts:
       home: Actualités récentes
-      read_post: Lire l'article
\ No newline at end of file
+      read_post: Lire l'article
diff --git a/config/locales/university/en.yml b/config/locales/university/en.yml
index 1958db7928d4368fc45c70cc5542c3b85ceb0ee4..b681492b3a478c70796c3d221a13bda8e9935c7d 100644
--- a/config/locales/university/en.yml
+++ b/config/locales/university/en.yml
@@ -76,6 +76,7 @@ en:
         description: Description
         edit: Edit experience
         organization: Organization
+        organization_name: Organisation
         from_year: Start year
         to_year: End year
         new: Add experience
diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml
index bec6dcddafad2f5715b4fcb1e02d19bce32c0f9d..2adbfaf37179e61069498280868d3204bf736a14 100644
--- a/config/locales/university/fr.yml
+++ b/config/locales/university/fr.yml
@@ -78,6 +78,7 @@ fr:
         from_year: Année de début
         new: Ajouter une expérience
         organization: Organisation
+        organization_name: Organisation
         to_year: Année de fin
       university/person/involvement:
         description: Mission (dans ce contexte)
diff --git a/config/routes/extranet.rb b/config/routes/extranet.rb
index 8ea81aaa667989b9db0cf730edf47d903a4a1fc7..f62c4b0e96b0d094f1efd00c227b73f203a6d586 100644
--- a/config/routes/extranet.rb
+++ b/config/routes/extranet.rb
@@ -7,18 +7,22 @@ namespace :contacts do
   get 'search' => 'search#index', as: :search
   root to: 'persons#index'
 end
-namespace :alumni do 
+namespace :alumni do
   get 'cohorts' => 'cohorts#index', as: :education_cohorts
   get 'cohorts/:id' => 'cohorts#show', as: :education_cohort
   get 'organizations' => 'organizations#index', as: :university_organizations
-  get 'organizations/search' => 'organizations#search', as: :search_university_organizations, defaults: { format: 'json' }
-  get 'organizations/:id' => 'organizations#show', as: :university_organization
+  get 'organization/:id' => 'organizations#show', as: :university_organization
   get 'persons' => 'persons#index', as: :university_persons
   get 'persons/:id' => 'persons#show', as: :university_person
   get 'years' => 'academic_years#index', as: :education_academic_years
   get 'years/:id' => 'academic_years#show', as: :education_academic_year
   root to: 'persons#index'
 end
+resources :organizations, except: [:index, :destroy] do
+  collection do
+    get 'search' => 'organizations#search', as: :search, defaults: { format: 'json' }
+  end
+end
 namespace :posts do
   get 'categories' => 'categories#index', as: :categories
   get 'categories/:slug' => 'categories#show', as: :category
diff --git a/package.json b/package.json
index bea2adeadb53d5f70e63ae09c35ceb6b12cb0879..11690b06ba4a455b22621bafeea7231ffad8c7e0 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,7 @@
   "dependencies": {
     "bootstrap-icons": "^1.9.1",
     "bootstrap-print-css": "^1.0.1",
+    "codemirror": "5",
     "cropperjs": "^1.5.12",
     "jquery-cropper": "^1.0.1",
     "notyf": "^3.10.0",
diff --git a/test/controllers/extranet/alumni/organizations_controller_test.rb b/test/controllers/extranet/alumni/organizations_controller_test.rb
index 4ae389477eb5ff650133f317dd1ecdf7f4be5030..fa9557a8bdda0f8277b6d929fc7a9d1d8357f843 100644
--- a/test/controllers/extranet/alumni/organizations_controller_test.rb
+++ b/test/controllers/extranet/alumni/organizations_controller_test.rb
@@ -8,14 +8,6 @@ class Extranet::Alumni::OrganizationsControllerTest < ActionDispatch::Integratio
     assert_response(:success)
   end
 
-  def test_search
-    get alumni_search_university_organizations_path(term: "Organisation de test")
-    assert_response(:success)
-    results = JSON.parse(response.body)
-    assert_equal(1, results.size)
-    assert_equal("Organisation de test", results.first["label"])
-  end
-
   def test_show
     get alumni_university_organization_path(university_organizations(:default_organization))
     assert_response(:success)
diff --git a/test/controllers/extranet/organizations_controller_test.rb b/test/controllers/extranet/organizations_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..112be04e1bef97dbcd572c87cdfbf20c4e8d3a7b
--- /dev/null
+++ b/test/controllers/extranet/organizations_controller_test.rb
@@ -0,0 +1,14 @@
+require "test_helper"
+
+class Extranet::OrganizationsControllerTest < ActionDispatch::IntegrationTest
+  include ExtranetSetup
+
+  def test_search
+    get search_organizations_path(term: "Organisation de test")
+    assert_response(:success)
+    results = JSON.parse(response.body)
+    assert_equal(1, results.size)
+    assert_equal("Organisation de test", results.first["label"])
+  end
+
+end
diff --git a/test/fixtures/communication/extranet/documents.yml b/test/fixtures/communication/extranet/documents.yml
index fb4fa23733ee89bef580ed42a2418d63d9d1b4cd..be1d0d6ab57326b590356596a4609a335ddd6e69 100644
--- a/test/fixtures/communication/extranet/documents.yml
+++ b/test/fixtures/communication/extranet/documents.yml
@@ -8,24 +8,18 @@
 #  published_at  :datetime
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
-#  category_id   :uuid             indexed
 #  extranet_id   :uuid             not null, indexed
-#  kind_id       :uuid             indexed
 #  university_id :uuid             not null, indexed
 #
 # Indexes
 #
-#  extranet_document_categories                             (category_id)
 #  index_communication_extranet_documents_on_extranet_id    (extranet_id)
 #  index_communication_extranet_documents_on_university_id  (university_id)
-#  index_extranet_document_kinds                            (kind_id)
 #
 # Foreign Keys
 #
 #  fk_rails_1272fd263c  (extranet_id => communication_extranets.id)
-#  fk_rails_51f7db2f66  (kind_id => communication_extranet_document_kinds.id)
 #  fk_rails_af877a8c0c  (university_id => universities.id)
-#  fk_rails_eb351dc444  (category_id => communication_extranet_document_categories.id)
 #
 
 one:
diff --git a/yarn.lock b/yarn.lock
index a8431a395052b1f0405556a0c582ccce88c64c1d..c7d515077ce9a861f931e17189c3cecd9862a22a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -107,6 +107,11 @@ bootstrap-print-css@^1.0.1:
   resolved "https://registry.yarnpkg.com/bootstrap-print-css/-/bootstrap-print-css-1.0.1.tgz#acc0264388caebbad0805e60c869d42cd6fe55bf"
   integrity sha512-I73Cw87BaxCccTjo3qEbvn7KRb55msMxTuT7mpkAAY4Obq8iG9xCybdxnJqq+RrykLD79O3092AiJwaKiEex7w==
 
+codemirror@5:
+  version "5.65.12"
+  resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.12.tgz#294fdf097d10ac5b56a9e011a91eff252afc73ae"
+  integrity sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw==
+
 cropperjs@^1.5.12:
   version "1.5.12"
   resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50"